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::Auto => unreachable!("Auto resolved above"),
 1707                Formatter::Prettier => {
 1708                    let logger = zlog::scoped!(logger => "prettier");
 1709                    zlog::trace!(logger => "formatting");
 1710                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1711
 1712                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1713                        lsp_store.prettier_store().unwrap().downgrade()
 1714                    })?;
 1715                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1716                        .await
 1717                        .transpose()?;
 1718                    let Some(diff) = diff else {
 1719                        zlog::trace!(logger => "No changes");
 1720                        continue;
 1721                    };
 1722
 1723                    extend_formatting_transaction(
 1724                        buffer,
 1725                        formatting_transaction_id,
 1726                        cx,
 1727                        |buffer, cx| {
 1728                            buffer.apply_diff(diff, cx);
 1729                        },
 1730                    )?;
 1731                }
 1732                Formatter::External { command, arguments } => {
 1733                    let logger = zlog::scoped!(logger => "command");
 1734                    zlog::trace!(logger => "formatting");
 1735                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1736
 1737                    let diff = Self::format_via_external_command(
 1738                        buffer,
 1739                        &command,
 1740                        arguments.as_deref(),
 1741                        cx,
 1742                    )
 1743                    .await
 1744                    .with_context(|| {
 1745                        format!("Failed to format buffer via external command: {}", command)
 1746                    })?;
 1747                    let Some(diff) = diff else {
 1748                        zlog::trace!(logger => "No changes");
 1749                        continue;
 1750                    };
 1751
 1752                    extend_formatting_transaction(
 1753                        buffer,
 1754                        formatting_transaction_id,
 1755                        cx,
 1756                        |buffer, cx| {
 1757                            buffer.apply_diff(diff, cx);
 1758                        },
 1759                    )?;
 1760                }
 1761                Formatter::LanguageServer(specifier) => {
 1762                    let logger = zlog::scoped!(logger => "language-server");
 1763                    zlog::trace!(logger => "formatting");
 1764                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1765
 1766                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1767                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1768                        continue;
 1769                    };
 1770
 1771                    let language_server = match specifier {
 1772                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1773                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1774                                if adapter.name.0.as_ref() == name {
 1775                                    Some(server.clone())
 1776                                } else {
 1777                                    None
 1778                                }
 1779                            })
 1780                        }
 1781                        settings::LanguageServerFormatterSpecifier::Current => adapters_and_servers
 1782                            .iter()
 1783                            .find(|(_, server)| Self::server_supports_formatting(server))
 1784                            .map(|(_, server)| server.clone()),
 1785                    };
 1786
 1787                    let Some(language_server) = language_server else {
 1788                        log::debug!(
 1789                            "No language server found to format buffer '{:?}'. Skipping",
 1790                            buffer_path_abs.as_path().to_string_lossy()
 1791                        );
 1792                        continue;
 1793                    };
 1794
 1795                    zlog::trace!(
 1796                        logger =>
 1797                        "Formatting buffer '{:?}' using language server '{:?}'",
 1798                        buffer_path_abs.as_path().to_string_lossy(),
 1799                        language_server.name()
 1800                    );
 1801
 1802                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1803                        zlog::trace!(logger => "formatting ranges");
 1804                        Self::format_ranges_via_lsp(
 1805                            &lsp_store,
 1806                            &buffer.handle,
 1807                            ranges,
 1808                            buffer_path_abs,
 1809                            &language_server,
 1810                            &settings,
 1811                            cx,
 1812                        )
 1813                        .await
 1814                        .context("Failed to format ranges via language server")?
 1815                    } else {
 1816                        zlog::trace!(logger => "formatting full");
 1817                        Self::format_via_lsp(
 1818                            &lsp_store,
 1819                            &buffer.handle,
 1820                            buffer_path_abs,
 1821                            &language_server,
 1822                            &settings,
 1823                            cx,
 1824                        )
 1825                        .await
 1826                        .context("failed to format via language server")?
 1827                    };
 1828
 1829                    if edits.is_empty() {
 1830                        zlog::trace!(logger => "No changes");
 1831                        continue;
 1832                    }
 1833                    extend_formatting_transaction(
 1834                        buffer,
 1835                        formatting_transaction_id,
 1836                        cx,
 1837                        |buffer, cx| {
 1838                            buffer.edit(edits, None, cx);
 1839                        },
 1840                    )?;
 1841                }
 1842                Formatter::CodeAction(code_action_name) => {
 1843                    let logger = zlog::scoped!(logger => "code-actions");
 1844                    zlog::trace!(logger => "formatting");
 1845                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1846
 1847                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1848                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1849                        continue;
 1850                    };
 1851
 1852                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1853                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1854
 1855                    let mut actions_and_servers = Vec::new();
 1856
 1857                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1858                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1859                            &lsp_store,
 1860                            language_server.server_id(),
 1861                            vec![code_action_kind.clone()],
 1862                            &buffer.handle,
 1863                            cx,
 1864                        )
 1865                        .await
 1866                        .with_context(|| {
 1867                            format!(
 1868                                "Failed to resolve code action {:?} with language server {}",
 1869                                code_action_kind,
 1870                                language_server.name()
 1871                            )
 1872                        });
 1873                        let Ok(actions) = actions_result else {
 1874                            // note: it may be better to set result to the error and break formatters here
 1875                            // but for now we try to execute the actions that we can resolve and skip the rest
 1876                            zlog::error!(
 1877                                logger =>
 1878                                "Failed to resolve code action {:?} with language server {}",
 1879                                code_action_kind,
 1880                                language_server.name()
 1881                            );
 1882                            continue;
 1883                        };
 1884                        for action in actions {
 1885                            actions_and_servers.push((action, index));
 1886                        }
 1887                    }
 1888
 1889                    if actions_and_servers.is_empty() {
 1890                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1891                        continue;
 1892                    }
 1893
 1894                    'actions: for (mut action, server_index) in actions_and_servers {
 1895                        let server = &adapters_and_servers[server_index].1;
 1896
 1897                        let describe_code_action = |action: &CodeAction| {
 1898                            format!(
 1899                                "code action '{}' with title \"{}\" on server {}",
 1900                                action
 1901                                    .lsp_action
 1902                                    .action_kind()
 1903                                    .unwrap_or("unknown".into())
 1904                                    .as_str(),
 1905                                action.lsp_action.title(),
 1906                                server.name(),
 1907                            )
 1908                        };
 1909
 1910                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1911
 1912                        if let Err(err) =
 1913                            Self::try_resolve_code_action(server, &mut action, request_timeout)
 1914                                .await
 1915                        {
 1916                            zlog::error!(
 1917                                logger =>
 1918                                "Failed to resolve {}. Error: {}",
 1919                                describe_code_action(&action),
 1920                                err
 1921                            );
 1922                            continue;
 1923                        }
 1924
 1925                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1926                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1927                            // but filters out and logs warnings for code actions that require unreasonably
 1928                            // difficult handling on our part, such as:
 1929                            // - applying edits that call commands
 1930                            //   which can result in arbitrary workspace edits being sent from the server that
 1931                            //   have no way of being tied back to the command that initiated them (i.e. we
 1932                            //   can't know which edits are part of the format request, or if the server is done sending
 1933                            //   actions in response to the command)
 1934                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1935                            //   as we then would need to handle such changes correctly in the local history as well
 1936                            //   as the remote history through the ProjectTransaction
 1937                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1938                            // Supporting these actions is not impossible, but not supported as of yet.
 1939                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1940                                zlog::trace!(
 1941                                    logger =>
 1942                                    "No changes for code action. Skipping {}",
 1943                                    describe_code_action(&action),
 1944                                );
 1945                                continue;
 1946                            }
 1947
 1948                            let mut operations = Vec::new();
 1949                            if let Some(document_changes) = edit.document_changes {
 1950                                match document_changes {
 1951                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1952                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1953                                    ),
 1954                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1955                                }
 1956                            } else if let Some(changes) = edit.changes {
 1957                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1958                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1959                                        text_document:
 1960                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1961                                                uri,
 1962                                                version: None,
 1963                                            },
 1964                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1965                                    })
 1966                                }));
 1967                            }
 1968
 1969                            let mut edits = Vec::with_capacity(operations.len());
 1970
 1971                            if operations.is_empty() {
 1972                                zlog::trace!(
 1973                                    logger =>
 1974                                    "No changes for code action. Skipping {}",
 1975                                    describe_code_action(&action),
 1976                                );
 1977                                continue;
 1978                            }
 1979                            for operation in operations {
 1980                                let op = match operation {
 1981                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1982                                    lsp::DocumentChangeOperation::Op(_) => {
 1983                                        zlog::warn!(
 1984                                            logger =>
 1985                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1986                                            describe_code_action(&action),
 1987                                        );
 1988                                        continue 'actions;
 1989                                    }
 1990                                };
 1991                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1992                                    zlog::warn!(
 1993                                        logger =>
 1994                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1995                                        &op.text_document.uri,
 1996                                        describe_code_action(&action),
 1997                                    );
 1998                                    continue 'actions;
 1999                                };
 2000                                if &file_path != buffer_path_abs {
 2001                                    zlog::warn!(
 2002                                        logger =>
 2003                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 2004                                        file_path,
 2005                                        buffer_path_abs,
 2006                                        describe_code_action(&action),
 2007                                    );
 2008                                    continue 'actions;
 2009                                }
 2010
 2011                                let mut lsp_edits = Vec::new();
 2012                                for edit in op.edits {
 2013                                    match edit {
 2014                                        Edit::Plain(edit) => {
 2015                                            if !lsp_edits.contains(&edit) {
 2016                                                lsp_edits.push(edit);
 2017                                            }
 2018                                        }
 2019                                        Edit::Annotated(edit) => {
 2020                                            if !lsp_edits.contains(&edit.text_edit) {
 2021                                                lsp_edits.push(edit.text_edit);
 2022                                            }
 2023                                        }
 2024                                        Edit::Snippet(_) => {
 2025                                            zlog::warn!(
 2026                                                logger =>
 2027                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 2028                                                describe_code_action(&action),
 2029                                            );
 2030                                            continue 'actions;
 2031                                        }
 2032                                    }
 2033                                }
 2034                                let edits_result = lsp_store
 2035                                    .update(cx, |lsp_store, cx| {
 2036                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 2037                                            &buffer.handle,
 2038                                            lsp_edits,
 2039                                            server.server_id(),
 2040                                            op.text_document.version,
 2041                                            cx,
 2042                                        )
 2043                                    })?
 2044                                    .await;
 2045                                let Ok(resolved_edits) = edits_result else {
 2046                                    zlog::warn!(
 2047                                        logger =>
 2048                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 2049                                        buffer_path_abs.as_path(),
 2050                                        describe_code_action(&action),
 2051                                    );
 2052                                    continue 'actions;
 2053                                };
 2054                                edits.extend(resolved_edits);
 2055                            }
 2056
 2057                            if edits.is_empty() {
 2058                                zlog::warn!(logger => "No edits resolved from LSP");
 2059                                continue;
 2060                            }
 2061
 2062                            extend_formatting_transaction(
 2063                                buffer,
 2064                                formatting_transaction_id,
 2065                                cx,
 2066                                |buffer, cx| {
 2067                                    zlog::info!(
 2068                                        "Applying edits {edits:?}. Content: {:?}",
 2069                                        buffer.text()
 2070                                    );
 2071                                    buffer.edit(edits, None, cx);
 2072                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 2073                                },
 2074                            )?;
 2075                        }
 2076
 2077                        // bail early if command is invalid
 2078                        let Some(command) = action.lsp_action.command() else {
 2079                            continue;
 2080                        };
 2081
 2082                        zlog::warn!(
 2083                            logger =>
 2084                            "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 2085                            &command.command,
 2086                        );
 2087
 2088                        let server_capabilities = server.capabilities();
 2089                        let available_commands = server_capabilities
 2090                            .execute_command_provider
 2091                            .as_ref()
 2092                            .map(|options| options.commands.as_slice())
 2093                            .unwrap_or_default();
 2094                        if !available_commands.contains(&command.command) {
 2095                            zlog::warn!(
 2096                                logger =>
 2097                                "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2098                                command.command,
 2099                                server.name(),
 2100                            );
 2101                            continue;
 2102                        }
 2103
 2104                        // noop so we just ensure buffer hasn't been edited since resolving code actions
 2105                        extend_formatting_transaction(
 2106                            buffer,
 2107                            formatting_transaction_id,
 2108                            cx,
 2109                            |_, _| {},
 2110                        )?;
 2111                        zlog::info!(logger => "Executing command {}", &command.command);
 2112
 2113                        lsp_store.update(cx, |this, _| {
 2114                            this.as_local_mut()
 2115                                .unwrap()
 2116                                .last_workspace_edits_by_language_server
 2117                                .remove(&server.server_id());
 2118                        })?;
 2119
 2120                        let execute_command_result = server
 2121                            .request::<lsp::request::ExecuteCommand>(
 2122                                lsp::ExecuteCommandParams {
 2123                                    command: command.command.clone(),
 2124                                    arguments: command.arguments.clone().unwrap_or_default(),
 2125                                    ..Default::default()
 2126                                },
 2127                                request_timeout,
 2128                            )
 2129                            .await
 2130                            .into_response();
 2131
 2132                        if execute_command_result.is_err() {
 2133                            zlog::error!(
 2134                                logger =>
 2135                                "Failed to execute command '{}' as part of {}",
 2136                                &command.command,
 2137                                describe_code_action(&action),
 2138                            );
 2139                            continue 'actions;
 2140                        }
 2141
 2142                        let mut project_transaction_command = lsp_store.update(cx, |this, _| {
 2143                            this.as_local_mut()
 2144                                .unwrap()
 2145                                .last_workspace_edits_by_language_server
 2146                                .remove(&server.server_id())
 2147                                .unwrap_or_default()
 2148                        })?;
 2149
 2150                        if let Some(transaction) =
 2151                            project_transaction_command.0.remove(&buffer.handle)
 2152                        {
 2153                            zlog::trace!(
 2154                                logger =>
 2155                                "Successfully captured {} edits that resulted from command {}",
 2156                                transaction.edit_ids.len(),
 2157                                &command.command,
 2158                            );
 2159                            let transaction_id_project_transaction = transaction.id;
 2160                            buffer.handle.update(cx, |buffer, _| {
 2161                                // it may have been removed from history if push_to_history was
 2162                                // false in deserialize_workspace_edit. If so push it so we
 2163                                // can merge it with the format transaction
 2164                                // and pop the combined transaction off the history stack
 2165                                // later if push_to_history is false
 2166                                if buffer.get_transaction(transaction.id).is_none() {
 2167                                    buffer.push_transaction(transaction, Instant::now());
 2168                                }
 2169                                buffer.merge_transactions(
 2170                                    transaction_id_project_transaction,
 2171                                    formatting_transaction_id,
 2172                                );
 2173                            });
 2174                        }
 2175
 2176                        if project_transaction_command.0.is_empty() {
 2177                            continue;
 2178                        }
 2179
 2180                        let mut extra_buffers = String::new();
 2181                        for buffer in project_transaction_command.0.keys() {
 2182                            buffer.read_with(cx, |b, cx| {
 2183                                let Some(path) = b.project_path(cx) else {
 2184                                    return;
 2185                                };
 2186
 2187                                if !extra_buffers.is_empty() {
 2188                                    extra_buffers.push_str(", ");
 2189                                }
 2190                                extra_buffers.push_str(path.path.as_unix_str());
 2191                            });
 2192                        }
 2193                        zlog::warn!(
 2194                            logger =>
 2195                            "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2196                            &command.command,
 2197                            extra_buffers,
 2198                        );
 2199                        // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2200                        // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2201                        // add it so it's included, and merge it into the format transaction when its created later
 2202                    }
 2203                }
 2204            }
 2205        }
 2206
 2207        Ok(())
 2208    }
 2209
 2210    pub async fn format_ranges_via_lsp(
 2211        this: &WeakEntity<LspStore>,
 2212        buffer_handle: &Entity<Buffer>,
 2213        ranges: &[Range<Anchor>],
 2214        abs_path: &Path,
 2215        language_server: &Arc<LanguageServer>,
 2216        settings: &LanguageSettings,
 2217        cx: &mut AsyncApp,
 2218    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2219        let capabilities = &language_server.capabilities();
 2220        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2221        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2222            anyhow::bail!(
 2223                "{} language server does not support range formatting",
 2224                language_server.name()
 2225            );
 2226        }
 2227
 2228        let uri = file_path_to_lsp_url(abs_path)?;
 2229        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2230
 2231        let request_timeout = cx.update(|app| {
 2232            ProjectSettings::get_global(app)
 2233                .global_lsp_settings
 2234                .get_request_timeout()
 2235        });
 2236        let lsp_edits = {
 2237            let mut lsp_ranges = Vec::new();
 2238            this.update(cx, |_this, cx| {
 2239                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2240                // not have been sent to the language server. This seems like a fairly systemic
 2241                // issue, though, the resolution probably is not specific to formatting.
 2242                //
 2243                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2244                // LSP.
 2245                let snapshot = buffer_handle.read(cx).snapshot();
 2246                for range in ranges {
 2247                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2248                }
 2249                anyhow::Ok(())
 2250            })??;
 2251
 2252            let mut edits = None;
 2253            for range in lsp_ranges {
 2254                if let Some(mut edit) = language_server
 2255                    .request::<lsp::request::RangeFormatting>(
 2256                        lsp::DocumentRangeFormattingParams {
 2257                            text_document: text_document.clone(),
 2258                            range,
 2259                            options: lsp_command::lsp_formatting_options(settings),
 2260                            work_done_progress_params: Default::default(),
 2261                        },
 2262                        request_timeout,
 2263                    )
 2264                    .await
 2265                    .into_response()?
 2266                {
 2267                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2268                }
 2269            }
 2270            edits
 2271        };
 2272
 2273        if let Some(lsp_edits) = lsp_edits {
 2274            this.update(cx, |this, cx| {
 2275                this.as_local_mut().unwrap().edits_from_lsp(
 2276                    buffer_handle,
 2277                    lsp_edits,
 2278                    language_server.server_id(),
 2279                    None,
 2280                    cx,
 2281                )
 2282            })?
 2283            .await
 2284        } else {
 2285            Ok(Vec::with_capacity(0))
 2286        }
 2287    }
 2288
 2289    fn server_supports_formatting(server: &Arc<LanguageServer>) -> bool {
 2290        let capabilities = server.capabilities();
 2291        let formatting = capabilities.document_formatting_provider.as_ref();
 2292        let range_formatting = capabilities.document_range_formatting_provider.as_ref();
 2293        matches!(formatting, Some(p) if *p != OneOf::Left(false))
 2294            || matches!(range_formatting, Some(p) if *p != OneOf::Left(false))
 2295    }
 2296
 2297    async fn format_via_lsp(
 2298        this: &WeakEntity<LspStore>,
 2299        buffer: &Entity<Buffer>,
 2300        abs_path: &Path,
 2301        language_server: &Arc<LanguageServer>,
 2302        settings: &LanguageSettings,
 2303        cx: &mut AsyncApp,
 2304    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2305        let logger = zlog::scoped!("lsp_format");
 2306        zlog::debug!(logger => "Formatting via LSP");
 2307
 2308        let uri = file_path_to_lsp_url(abs_path)?;
 2309        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2310        let capabilities = &language_server.capabilities();
 2311
 2312        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2313        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2314
 2315        let request_timeout = cx.update(|app| {
 2316            ProjectSettings::get_global(app)
 2317                .global_lsp_settings
 2318                .get_request_timeout()
 2319        });
 2320
 2321        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2322            let _timer = zlog::time!(logger => "format-full");
 2323            language_server
 2324                .request::<lsp::request::Formatting>(
 2325                    lsp::DocumentFormattingParams {
 2326                        text_document,
 2327                        options: lsp_command::lsp_formatting_options(settings),
 2328                        work_done_progress_params: Default::default(),
 2329                    },
 2330                    request_timeout,
 2331                )
 2332                .await
 2333                .into_response()?
 2334        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2335            let _timer = zlog::time!(logger => "format-range");
 2336            let buffer_start = lsp::Position::new(0, 0);
 2337            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2338            language_server
 2339                .request::<lsp::request::RangeFormatting>(
 2340                    lsp::DocumentRangeFormattingParams {
 2341                        text_document: text_document.clone(),
 2342                        range: lsp::Range::new(buffer_start, buffer_end),
 2343                        options: lsp_command::lsp_formatting_options(settings),
 2344                        work_done_progress_params: Default::default(),
 2345                    },
 2346                    request_timeout,
 2347                )
 2348                .await
 2349                .into_response()?
 2350        } else {
 2351            None
 2352        };
 2353
 2354        if let Some(lsp_edits) = lsp_edits {
 2355            this.update(cx, |this, cx| {
 2356                this.as_local_mut().unwrap().edits_from_lsp(
 2357                    buffer,
 2358                    lsp_edits,
 2359                    language_server.server_id(),
 2360                    None,
 2361                    cx,
 2362                )
 2363            })?
 2364            .await
 2365        } else {
 2366            Ok(Vec::with_capacity(0))
 2367        }
 2368    }
 2369
 2370    async fn format_via_external_command(
 2371        buffer: &FormattableBuffer,
 2372        command: &str,
 2373        arguments: Option<&[String]>,
 2374        cx: &mut AsyncApp,
 2375    ) -> Result<Option<Diff>> {
 2376        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2377            let file = File::from_dyn(buffer.file())?;
 2378            let worktree = file.worktree.read(cx);
 2379            let mut worktree_path = worktree.abs_path().to_path_buf();
 2380            if worktree.root_entry()?.is_file() {
 2381                worktree_path.pop();
 2382            }
 2383            Some(worktree_path)
 2384        });
 2385
 2386        use util::command::Stdio;
 2387        let mut child = util::command::new_command(command);
 2388
 2389        if let Some(buffer_env) = buffer.env.as_ref() {
 2390            child.envs(buffer_env);
 2391        }
 2392
 2393        if let Some(working_dir_path) = working_dir_path {
 2394            child.current_dir(working_dir_path);
 2395        }
 2396
 2397        if let Some(arguments) = arguments {
 2398            child.args(arguments.iter().map(|arg| {
 2399                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2400                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2401                } else {
 2402                    arg.replace("{buffer_path}", "Untitled")
 2403                }
 2404            }));
 2405        }
 2406
 2407        let mut child = child
 2408            .stdin(Stdio::piped())
 2409            .stdout(Stdio::piped())
 2410            .stderr(Stdio::piped())
 2411            .spawn()?;
 2412
 2413        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2414        let text = buffer
 2415            .handle
 2416            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2417        for chunk in text.chunks() {
 2418            stdin.write_all(chunk.as_bytes()).await?;
 2419        }
 2420        stdin.flush().await?;
 2421
 2422        let output = child.output().await?;
 2423        anyhow::ensure!(
 2424            output.status.success(),
 2425            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2426            output.status.code(),
 2427            String::from_utf8_lossy(&output.stdout),
 2428            String::from_utf8_lossy(&output.stderr),
 2429        );
 2430
 2431        let stdout = String::from_utf8(output.stdout)?;
 2432        Ok(Some(
 2433            buffer
 2434                .handle
 2435                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2436                .await,
 2437        ))
 2438    }
 2439
 2440    async fn try_resolve_code_action(
 2441        lang_server: &LanguageServer,
 2442        action: &mut CodeAction,
 2443        request_timeout: Duration,
 2444    ) -> anyhow::Result<()> {
 2445        match &mut action.lsp_action {
 2446            LspAction::Action(lsp_action) => {
 2447                if !action.resolved
 2448                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2449                    && lsp_action.data.is_some()
 2450                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2451                {
 2452                    **lsp_action = lang_server
 2453                        .request::<lsp::request::CodeActionResolveRequest>(
 2454                            *lsp_action.clone(),
 2455                            request_timeout,
 2456                        )
 2457                        .await
 2458                        .into_response()?;
 2459                }
 2460            }
 2461            LspAction::CodeLens(lens) => {
 2462                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2463                    *lens = lang_server
 2464                        .request::<lsp::request::CodeLensResolve>(lens.clone(), request_timeout)
 2465                        .await
 2466                        .into_response()?;
 2467                }
 2468            }
 2469            LspAction::Command(_) => {}
 2470        }
 2471
 2472        action.resolved = true;
 2473        anyhow::Ok(())
 2474    }
 2475
 2476    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2477        let buffer = buffer_handle.read(cx);
 2478
 2479        let file = buffer.file().cloned();
 2480
 2481        let Some(file) = File::from_dyn(file.as_ref()) else {
 2482            return;
 2483        };
 2484        if !file.is_local() {
 2485            return;
 2486        }
 2487        let path = ProjectPath::from_file(file, cx);
 2488        let worktree_id = file.worktree_id(cx);
 2489        let language = buffer.language().cloned();
 2490
 2491        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2492            for (server_id, diagnostics) in
 2493                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2494            {
 2495                self.update_buffer_diagnostics(
 2496                    buffer_handle,
 2497                    server_id,
 2498                    None,
 2499                    None,
 2500                    None,
 2501                    Vec::new(),
 2502                    diagnostics,
 2503                    cx,
 2504                )
 2505                .log_err();
 2506            }
 2507        }
 2508        let Some(language) = language else {
 2509            return;
 2510        };
 2511        let Some(snapshot) = self
 2512            .worktree_store
 2513            .read(cx)
 2514            .worktree_for_id(worktree_id, cx)
 2515            .map(|worktree| worktree.read(cx).snapshot())
 2516        else {
 2517            return;
 2518        };
 2519        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2520
 2521        for server_id in
 2522            self.lsp_tree
 2523                .get(path, language.name(), language.manifest(), &delegate, cx)
 2524        {
 2525            let server = self
 2526                .language_servers
 2527                .get(&server_id)
 2528                .and_then(|server_state| {
 2529                    if let LanguageServerState::Running { server, .. } = server_state {
 2530                        Some(server.clone())
 2531                    } else {
 2532                        None
 2533                    }
 2534                });
 2535            let server = match server {
 2536                Some(server) => server,
 2537                None => continue,
 2538            };
 2539
 2540            buffer_handle.update(cx, |buffer, cx| {
 2541                buffer.set_completion_triggers(
 2542                    server.server_id(),
 2543                    server
 2544                        .capabilities()
 2545                        .completion_provider
 2546                        .as_ref()
 2547                        .and_then(|provider| {
 2548                            provider
 2549                                .trigger_characters
 2550                                .as_ref()
 2551                                .map(|characters| characters.iter().cloned().collect())
 2552                        })
 2553                        .unwrap_or_default(),
 2554                    cx,
 2555                );
 2556            });
 2557        }
 2558    }
 2559
 2560    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2561        buffer.update(cx, |buffer, cx| {
 2562            let Some(language) = buffer.language() else {
 2563                return;
 2564            };
 2565            let path = ProjectPath {
 2566                worktree_id: old_file.worktree_id(cx),
 2567                path: old_file.path.clone(),
 2568            };
 2569            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2570                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2571                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2572            }
 2573        });
 2574    }
 2575
 2576    fn update_buffer_diagnostics(
 2577        &mut self,
 2578        buffer: &Entity<Buffer>,
 2579        server_id: LanguageServerId,
 2580        registration_id: Option<Option<SharedString>>,
 2581        result_id: Option<SharedString>,
 2582        version: Option<i32>,
 2583        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2584        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2585        cx: &mut Context<LspStore>,
 2586    ) -> Result<()> {
 2587        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2588            Ordering::Equal
 2589                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2590                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2591                .then_with(|| a.severity.cmp(&b.severity))
 2592                .then_with(|| a.message.cmp(&b.message))
 2593        }
 2594
 2595        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2596        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2597        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2598
 2599        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2600            Ordering::Equal
 2601                .then_with(|| a.range.start.cmp(&b.range.start))
 2602                .then_with(|| b.range.end.cmp(&a.range.end))
 2603                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2604        });
 2605
 2606        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2607
 2608        let edits_since_save = std::cell::LazyCell::new(|| {
 2609            let saved_version = buffer.read(cx).saved_version();
 2610            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2611        });
 2612
 2613        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2614
 2615        for (new_diagnostic, entry) in diagnostics {
 2616            let start;
 2617            let end;
 2618            if new_diagnostic && entry.diagnostic.is_disk_based {
 2619                // Some diagnostics are based on files on disk instead of buffers'
 2620                // current contents. Adjust these diagnostics' ranges to reflect
 2621                // any unsaved edits.
 2622                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2623                // and were properly adjusted on reuse.
 2624                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2625                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2626            } else {
 2627                start = entry.range.start;
 2628                end = entry.range.end;
 2629            }
 2630
 2631            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2632                ..snapshot.clip_point_utf16(end, Bias::Right);
 2633
 2634            // Expand empty ranges by one codepoint
 2635            if range.start == range.end {
 2636                // This will be go to the next boundary when being clipped
 2637                range.end.column += 1;
 2638                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2639                if range.start == range.end && range.end.column > 0 {
 2640                    range.start.column -= 1;
 2641                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2642                }
 2643            }
 2644
 2645            sanitized_diagnostics.push(DiagnosticEntry {
 2646                range,
 2647                diagnostic: entry.diagnostic,
 2648            });
 2649        }
 2650        drop(edits_since_save);
 2651
 2652        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2653        buffer.update(cx, |buffer, cx| {
 2654            if let Some(registration_id) = registration_id {
 2655                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2656                    self.buffer_pull_diagnostics_result_ids
 2657                        .entry(server_id)
 2658                        .or_default()
 2659                        .entry(registration_id)
 2660                        .or_default()
 2661                        .insert(abs_path, result_id);
 2662                }
 2663            }
 2664
 2665            buffer.update_diagnostics(server_id, set, cx)
 2666        });
 2667
 2668        Ok(())
 2669    }
 2670
 2671    fn register_language_server_for_invisible_worktree(
 2672        &mut self,
 2673        worktree: &Entity<Worktree>,
 2674        language_server_id: LanguageServerId,
 2675        cx: &mut App,
 2676    ) {
 2677        let worktree = worktree.read(cx);
 2678        let worktree_id = worktree.id();
 2679        debug_assert!(!worktree.is_visible());
 2680        let Some(mut origin_seed) = self
 2681            .language_server_ids
 2682            .iter()
 2683            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2684        else {
 2685            return;
 2686        };
 2687        origin_seed.worktree_id = worktree_id;
 2688        self.language_server_ids
 2689            .entry(origin_seed)
 2690            .or_insert_with(|| UnifiedLanguageServer {
 2691                id: language_server_id,
 2692                project_roots: Default::default(),
 2693            });
 2694    }
 2695
 2696    fn register_buffer_with_language_servers(
 2697        &mut self,
 2698        buffer_handle: &Entity<Buffer>,
 2699        only_register_servers: HashSet<LanguageServerSelector>,
 2700        cx: &mut Context<LspStore>,
 2701    ) {
 2702        let buffer = buffer_handle.read(cx);
 2703        let buffer_id = buffer.remote_id();
 2704
 2705        let Some(file) = File::from_dyn(buffer.file()) else {
 2706            return;
 2707        };
 2708        if !file.is_local() {
 2709            return;
 2710        }
 2711
 2712        let abs_path = file.abs_path(cx);
 2713        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2714            return;
 2715        };
 2716        let initial_snapshot = buffer.text_snapshot();
 2717        let worktree_id = file.worktree_id(cx);
 2718
 2719        let Some(language) = buffer.language().cloned() else {
 2720            return;
 2721        };
 2722        let path: Arc<RelPath> = file
 2723            .path()
 2724            .parent()
 2725            .map(Arc::from)
 2726            .unwrap_or_else(|| file.path().clone());
 2727        let Some(worktree) = self
 2728            .worktree_store
 2729            .read(cx)
 2730            .worktree_for_id(worktree_id, cx)
 2731        else {
 2732            return;
 2733        };
 2734        let language_name = language.name();
 2735        let (reused, delegate, servers) = self
 2736            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2737            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2738            .unwrap_or_else(|| {
 2739                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2740                let delegate: Arc<dyn ManifestDelegate> =
 2741                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2742
 2743                let servers = self
 2744                    .lsp_tree
 2745                    .walk(
 2746                        ProjectPath { worktree_id, path },
 2747                        language.name(),
 2748                        language.manifest(),
 2749                        &delegate,
 2750                        cx,
 2751                    )
 2752                    .collect::<Vec<_>>();
 2753                (false, lsp_delegate, servers)
 2754            });
 2755        let servers_and_adapters = servers
 2756            .into_iter()
 2757            .filter_map(|server_node| {
 2758                if reused && server_node.server_id().is_none() {
 2759                    return None;
 2760                }
 2761                if !only_register_servers.is_empty() {
 2762                    if let Some(server_id) = server_node.server_id()
 2763                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2764                    {
 2765                        return None;
 2766                    }
 2767                    if let Some(name) = server_node.name()
 2768                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2769                    {
 2770                        return None;
 2771                    }
 2772                }
 2773
 2774                let server_id = server_node.server_id_or_init(|disposition| {
 2775                    let path = &disposition.path;
 2776
 2777                    {
 2778                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2779
 2780                        let server_id = self.get_or_insert_language_server(
 2781                            &worktree,
 2782                            delegate.clone(),
 2783                            disposition,
 2784                            &language_name,
 2785                            cx,
 2786                        );
 2787
 2788                        if let Some(state) = self.language_servers.get(&server_id)
 2789                            && let Ok(uri) = uri
 2790                        {
 2791                            state.add_workspace_folder(uri);
 2792                        };
 2793                        server_id
 2794                    }
 2795                })?;
 2796                let server_state = self.language_servers.get(&server_id)?;
 2797                if let LanguageServerState::Running {
 2798                    server, adapter, ..
 2799                } = server_state
 2800                {
 2801                    Some((server.clone(), adapter.clone()))
 2802                } else {
 2803                    None
 2804                }
 2805            })
 2806            .collect::<Vec<_>>();
 2807        for (server, adapter) in servers_and_adapters {
 2808            buffer_handle.update(cx, |buffer, cx| {
 2809                buffer.set_completion_triggers(
 2810                    server.server_id(),
 2811                    server
 2812                        .capabilities()
 2813                        .completion_provider
 2814                        .as_ref()
 2815                        .and_then(|provider| {
 2816                            provider
 2817                                .trigger_characters
 2818                                .as_ref()
 2819                                .map(|characters| characters.iter().cloned().collect())
 2820                        })
 2821                        .unwrap_or_default(),
 2822                    cx,
 2823                );
 2824            });
 2825
 2826            let snapshot = LspBufferSnapshot {
 2827                version: 0,
 2828                snapshot: initial_snapshot.clone(),
 2829            };
 2830
 2831            let mut registered = false;
 2832            self.buffer_snapshots
 2833                .entry(buffer_id)
 2834                .or_default()
 2835                .entry(server.server_id())
 2836                .or_insert_with(|| {
 2837                    registered = true;
 2838                    server.register_buffer(
 2839                        uri.clone(),
 2840                        adapter.language_id(&language.name()),
 2841                        0,
 2842                        initial_snapshot.text(),
 2843                    );
 2844
 2845                    vec![snapshot]
 2846                });
 2847
 2848            self.buffers_opened_in_servers
 2849                .entry(buffer_id)
 2850                .or_default()
 2851                .insert(server.server_id());
 2852            if registered {
 2853                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2854                    language_server_id: server.server_id(),
 2855                    name: None,
 2856                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2857                        proto::RegisteredForBuffer {
 2858                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2859                            buffer_id: buffer_id.to_proto(),
 2860                        },
 2861                    ),
 2862                });
 2863            }
 2864        }
 2865    }
 2866
 2867    fn reuse_existing_language_server<'lang_name>(
 2868        &self,
 2869        server_tree: &LanguageServerTree,
 2870        worktree: &Entity<Worktree>,
 2871        language_name: &'lang_name LanguageName,
 2872        cx: &mut App,
 2873    ) -> Option<(
 2874        Arc<LocalLspAdapterDelegate>,
 2875        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2876    )> {
 2877        if worktree.read(cx).is_visible() {
 2878            return None;
 2879        }
 2880
 2881        let worktree_store = self.worktree_store.read(cx);
 2882        let servers = server_tree
 2883            .instances
 2884            .iter()
 2885            .filter(|(worktree_id, _)| {
 2886                worktree_store
 2887                    .worktree_for_id(**worktree_id, cx)
 2888                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2889            })
 2890            .flat_map(|(worktree_id, servers)| {
 2891                servers
 2892                    .roots
 2893                    .iter()
 2894                    .flat_map(|(_, language_servers)| language_servers)
 2895                    .map(move |(_, (server_node, server_languages))| {
 2896                        (worktree_id, server_node, server_languages)
 2897                    })
 2898                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2899                    .map(|(worktree_id, server_node, _)| {
 2900                        (
 2901                            *worktree_id,
 2902                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2903                        )
 2904                    })
 2905            })
 2906            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2907                acc.entry(worktree_id)
 2908                    .or_insert_with(Vec::new)
 2909                    .push(server_node);
 2910                acc
 2911            })
 2912            .into_values()
 2913            .max_by_key(|servers| servers.len())?;
 2914
 2915        let worktree_id = worktree.read(cx).id();
 2916        let apply = move |tree: &mut LanguageServerTree| {
 2917            for server_node in &servers {
 2918                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2919            }
 2920            servers
 2921        };
 2922
 2923        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2924        Some((delegate, apply))
 2925    }
 2926
 2927    pub(crate) fn unregister_old_buffer_from_language_servers(
 2928        &mut self,
 2929        buffer: &Entity<Buffer>,
 2930        old_file: &File,
 2931        cx: &mut App,
 2932    ) {
 2933        let old_path = match old_file.as_local() {
 2934            Some(local) => local.abs_path(cx),
 2935            None => return,
 2936        };
 2937
 2938        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2939            debug_panic!("{old_path:?} is not parseable as an URI");
 2940            return;
 2941        };
 2942        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2943    }
 2944
 2945    pub(crate) fn unregister_buffer_from_language_servers(
 2946        &mut self,
 2947        buffer: &Entity<Buffer>,
 2948        file_url: &lsp::Uri,
 2949        cx: &mut App,
 2950    ) {
 2951        buffer.update(cx, |buffer, cx| {
 2952            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2953
 2954            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2955                if snapshots
 2956                    .as_mut()
 2957                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2958                {
 2959                    language_server.unregister_buffer(file_url.clone());
 2960                }
 2961            }
 2962        });
 2963    }
 2964
 2965    fn buffer_snapshot_for_lsp_version(
 2966        &mut self,
 2967        buffer: &Entity<Buffer>,
 2968        server_id: LanguageServerId,
 2969        version: Option<i32>,
 2970        cx: &App,
 2971    ) -> Result<TextBufferSnapshot> {
 2972        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2973
 2974        if let Some(version) = version {
 2975            let buffer_id = buffer.read(cx).remote_id();
 2976            let snapshots = if let Some(snapshots) = self
 2977                .buffer_snapshots
 2978                .get_mut(&buffer_id)
 2979                .and_then(|m| m.get_mut(&server_id))
 2980            {
 2981                snapshots
 2982            } else if version == 0 {
 2983                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2984                // We detect this case and treat it as if the version was `None`.
 2985                return Ok(buffer.read(cx).text_snapshot());
 2986            } else {
 2987                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2988            };
 2989
 2990            let found_snapshot = snapshots
 2991                    .binary_search_by_key(&version, |e| e.version)
 2992                    .map(|ix| snapshots[ix].snapshot.clone())
 2993                    .map_err(|_| {
 2994                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2995                    })?;
 2996
 2997            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2998            Ok(found_snapshot)
 2999        } else {
 3000            Ok((buffer.read(cx)).text_snapshot())
 3001        }
 3002    }
 3003
 3004    async fn get_server_code_actions_from_action_kinds(
 3005        lsp_store: &WeakEntity<LspStore>,
 3006        language_server_id: LanguageServerId,
 3007        code_action_kinds: Vec<lsp::CodeActionKind>,
 3008        buffer: &Entity<Buffer>,
 3009        cx: &mut AsyncApp,
 3010    ) -> Result<Vec<CodeAction>> {
 3011        let actions = lsp_store
 3012            .update(cx, move |this, cx| {
 3013                let request = GetCodeActions {
 3014                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 3015                    kinds: Some(code_action_kinds),
 3016                };
 3017                let server = LanguageServerToQuery::Other(language_server_id);
 3018                this.request_lsp(buffer.clone(), server, request, cx)
 3019            })?
 3020            .await?;
 3021        Ok(actions)
 3022    }
 3023
 3024    pub async fn execute_code_actions_on_server(
 3025        lsp_store: &WeakEntity<LspStore>,
 3026        language_server: &Arc<LanguageServer>,
 3027        actions: Vec<CodeAction>,
 3028        push_to_history: bool,
 3029        project_transaction: &mut ProjectTransaction,
 3030        cx: &mut AsyncApp,
 3031    ) -> anyhow::Result<()> {
 3032        let request_timeout = cx.update(|app| {
 3033            ProjectSettings::get_global(app)
 3034                .global_lsp_settings
 3035                .get_request_timeout()
 3036        });
 3037
 3038        for mut action in actions {
 3039            Self::try_resolve_code_action(language_server, &mut action, request_timeout)
 3040                .await
 3041                .context("resolving a formatting code action")?;
 3042
 3043            if let Some(edit) = action.lsp_action.edit() {
 3044                if edit.changes.is_none() && edit.document_changes.is_none() {
 3045                    continue;
 3046                }
 3047
 3048                let new = Self::deserialize_workspace_edit(
 3049                    lsp_store.upgrade().context("project dropped")?,
 3050                    edit.clone(),
 3051                    push_to_history,
 3052                    language_server.clone(),
 3053                    cx,
 3054                )
 3055                .await?;
 3056                project_transaction.0.extend(new.0);
 3057            }
 3058
 3059            let Some(command) = action.lsp_action.command() else {
 3060                continue;
 3061            };
 3062
 3063            let server_capabilities = language_server.capabilities();
 3064            let available_commands = server_capabilities
 3065                .execute_command_provider
 3066                .as_ref()
 3067                .map(|options| options.commands.as_slice())
 3068                .unwrap_or_default();
 3069            if !available_commands.contains(&command.command) {
 3070                log::warn!(
 3071                    "Cannot execute a command {} not listed in the language server capabilities",
 3072                    command.command
 3073                );
 3074                continue;
 3075            }
 3076
 3077            lsp_store.update(cx, |lsp_store, _| {
 3078                if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 3079                    mode.last_workspace_edits_by_language_server
 3080                        .remove(&language_server.server_id());
 3081                }
 3082            })?;
 3083
 3084            language_server
 3085                .request::<lsp::request::ExecuteCommand>(
 3086                    lsp::ExecuteCommandParams {
 3087                        command: command.command.clone(),
 3088                        arguments: command.arguments.clone().unwrap_or_default(),
 3089                        ..Default::default()
 3090                    },
 3091                    request_timeout,
 3092                )
 3093                .await
 3094                .into_response()
 3095                .context("execute command")?;
 3096
 3097            lsp_store.update(cx, |this, _| {
 3098                if let LspStoreMode::Local(mode) = &mut this.mode {
 3099                    project_transaction.0.extend(
 3100                        mode.last_workspace_edits_by_language_server
 3101                            .remove(&language_server.server_id())
 3102                            .unwrap_or_default()
 3103                            .0,
 3104                    )
 3105                }
 3106            })?;
 3107        }
 3108        Ok(())
 3109    }
 3110
 3111    pub async fn deserialize_text_edits(
 3112        this: Entity<LspStore>,
 3113        buffer_to_edit: Entity<Buffer>,
 3114        edits: Vec<lsp::TextEdit>,
 3115        push_to_history: bool,
 3116        _: Arc<CachedLspAdapter>,
 3117        language_server: Arc<LanguageServer>,
 3118        cx: &mut AsyncApp,
 3119    ) -> Result<Option<Transaction>> {
 3120        let edits = this
 3121            .update(cx, |this, cx| {
 3122                this.as_local_mut().unwrap().edits_from_lsp(
 3123                    &buffer_to_edit,
 3124                    edits,
 3125                    language_server.server_id(),
 3126                    None,
 3127                    cx,
 3128                )
 3129            })
 3130            .await?;
 3131
 3132        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3133            buffer.finalize_last_transaction();
 3134            buffer.start_transaction();
 3135            for (range, text) in edits {
 3136                buffer.edit([(range, text)], None, cx);
 3137            }
 3138
 3139            if buffer.end_transaction(cx).is_some() {
 3140                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3141                if !push_to_history {
 3142                    buffer.forget_transaction(transaction.id);
 3143                }
 3144                Some(transaction)
 3145            } else {
 3146                None
 3147            }
 3148        });
 3149
 3150        Ok(transaction)
 3151    }
 3152
 3153    #[allow(clippy::type_complexity)]
 3154    pub fn edits_from_lsp(
 3155        &mut self,
 3156        buffer: &Entity<Buffer>,
 3157        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3158        server_id: LanguageServerId,
 3159        version: Option<i32>,
 3160        cx: &mut Context<LspStore>,
 3161    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3162        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3163        cx.background_spawn(async move {
 3164            let snapshot = snapshot?;
 3165            let mut lsp_edits = lsp_edits
 3166                .into_iter()
 3167                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3168                .collect::<Vec<_>>();
 3169
 3170            lsp_edits.sort_unstable_by_key(|(range, _)| (range.start, range.end));
 3171
 3172            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3173            let mut edits = Vec::new();
 3174            while let Some((range, mut new_text)) = lsp_edits.next() {
 3175                // Clip invalid ranges provided by the language server.
 3176                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3177                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3178
 3179                // Combine any LSP edits that are adjacent.
 3180                //
 3181                // Also, combine LSP edits that are separated from each other by only
 3182                // a newline. This is important because for some code actions,
 3183                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3184                // are separated by unchanged newline characters.
 3185                //
 3186                // In order for the diffing logic below to work properly, any edits that
 3187                // cancel each other out must be combined into one.
 3188                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3189                    if next_range.start.0 > range.end {
 3190                        if next_range.start.0.row > range.end.row + 1
 3191                            || next_range.start.0.column > 0
 3192                            || snapshot.clip_point_utf16(
 3193                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3194                                Bias::Left,
 3195                            ) > range.end
 3196                        {
 3197                            break;
 3198                        }
 3199                        new_text.push('\n');
 3200                    }
 3201                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3202                    new_text.push_str(next_text);
 3203                    lsp_edits.next();
 3204                }
 3205
 3206                // For multiline edits, perform a diff of the old and new text so that
 3207                // we can identify the changes more precisely, preserving the locations
 3208                // of any anchors positioned in the unchanged regions.
 3209                if range.end.row > range.start.row {
 3210                    let offset = range.start.to_offset(&snapshot);
 3211                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3212                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3213                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3214                        (
 3215                            snapshot.anchor_after(offset + range.start)
 3216                                ..snapshot.anchor_before(offset + range.end),
 3217                            replacement,
 3218                        )
 3219                    }));
 3220                } else if range.end == range.start {
 3221                    let anchor = snapshot.anchor_after(range.start);
 3222                    edits.push((anchor..anchor, new_text.into()));
 3223                } else {
 3224                    let edit_start = snapshot.anchor_after(range.start);
 3225                    let edit_end = snapshot.anchor_before(range.end);
 3226                    edits.push((edit_start..edit_end, new_text.into()));
 3227                }
 3228            }
 3229
 3230            Ok(edits)
 3231        })
 3232    }
 3233
 3234    pub(crate) async fn deserialize_workspace_edit(
 3235        this: Entity<LspStore>,
 3236        edit: lsp::WorkspaceEdit,
 3237        push_to_history: bool,
 3238        language_server: Arc<LanguageServer>,
 3239        cx: &mut AsyncApp,
 3240    ) -> Result<ProjectTransaction> {
 3241        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3242
 3243        let mut operations = Vec::new();
 3244        if let Some(document_changes) = edit.document_changes {
 3245            match document_changes {
 3246                lsp::DocumentChanges::Edits(edits) => {
 3247                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3248                }
 3249                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3250            }
 3251        } else if let Some(changes) = edit.changes {
 3252            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3253                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3254                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3255                        uri,
 3256                        version: None,
 3257                    },
 3258                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3259                })
 3260            }));
 3261        }
 3262
 3263        let mut project_transaction = ProjectTransaction::default();
 3264        for operation in operations {
 3265            match operation {
 3266                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3267                    let abs_path = op
 3268                        .uri
 3269                        .to_file_path()
 3270                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3271
 3272                    if let Some(parent_path) = abs_path.parent() {
 3273                        fs.create_dir(parent_path).await?;
 3274                    }
 3275                    if abs_path.ends_with("/") {
 3276                        fs.create_dir(&abs_path).await?;
 3277                    } else {
 3278                        fs.create_file(
 3279                            &abs_path,
 3280                            op.options
 3281                                .map(|options| fs::CreateOptions {
 3282                                    overwrite: options.overwrite.unwrap_or(false),
 3283                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3284                                })
 3285                                .unwrap_or_default(),
 3286                        )
 3287                        .await?;
 3288                    }
 3289                }
 3290
 3291                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3292                    let source_abs_path = op
 3293                        .old_uri
 3294                        .to_file_path()
 3295                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3296                    let target_abs_path = op
 3297                        .new_uri
 3298                        .to_file_path()
 3299                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3300
 3301                    let options = fs::RenameOptions {
 3302                        overwrite: op
 3303                            .options
 3304                            .as_ref()
 3305                            .and_then(|options| options.overwrite)
 3306                            .unwrap_or(false),
 3307                        ignore_if_exists: op
 3308                            .options
 3309                            .as_ref()
 3310                            .and_then(|options| options.ignore_if_exists)
 3311                            .unwrap_or(false),
 3312                        create_parents: true,
 3313                    };
 3314
 3315                    fs.rename(&source_abs_path, &target_abs_path, options)
 3316                        .await?;
 3317                }
 3318
 3319                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3320                    let abs_path = op
 3321                        .uri
 3322                        .to_file_path()
 3323                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3324                    let options = op
 3325                        .options
 3326                        .map(|options| fs::RemoveOptions {
 3327                            recursive: options.recursive.unwrap_or(false),
 3328                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3329                        })
 3330                        .unwrap_or_default();
 3331                    if abs_path.ends_with("/") {
 3332                        fs.remove_dir(&abs_path, options).await?;
 3333                    } else {
 3334                        fs.remove_file(&abs_path, options).await?;
 3335                    }
 3336                }
 3337
 3338                lsp::DocumentChangeOperation::Edit(op) => {
 3339                    let buffer_to_edit = this
 3340                        .update(cx, |this, cx| {
 3341                            this.open_local_buffer_via_lsp(
 3342                                op.text_document.uri.clone(),
 3343                                language_server.server_id(),
 3344                                cx,
 3345                            )
 3346                        })
 3347                        .await?;
 3348
 3349                    let edits = this
 3350                        .update(cx, |this, cx| {
 3351                            let path = buffer_to_edit.read(cx).project_path(cx);
 3352                            let active_entry = this.active_entry;
 3353                            let is_active_entry = path.is_some_and(|project_path| {
 3354                                this.worktree_store
 3355                                    .read(cx)
 3356                                    .entry_for_path(&project_path, cx)
 3357                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3358                            });
 3359                            let local = this.as_local_mut().unwrap();
 3360
 3361                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3362                            for edit in op.edits {
 3363                                match edit {
 3364                                    Edit::Plain(edit) => {
 3365                                        if !edits.contains(&edit) {
 3366                                            edits.push(edit)
 3367                                        }
 3368                                    }
 3369                                    Edit::Annotated(edit) => {
 3370                                        if !edits.contains(&edit.text_edit) {
 3371                                            edits.push(edit.text_edit)
 3372                                        }
 3373                                    }
 3374                                    Edit::Snippet(edit) => {
 3375                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3376                                        else {
 3377                                            continue;
 3378                                        };
 3379
 3380                                        if is_active_entry {
 3381                                            snippet_edits.push((edit.range, snippet));
 3382                                        } else {
 3383                                            // Since this buffer is not focused, apply a normal edit.
 3384                                            let new_edit = TextEdit {
 3385                                                range: edit.range,
 3386                                                new_text: snippet.text,
 3387                                            };
 3388                                            if !edits.contains(&new_edit) {
 3389                                                edits.push(new_edit);
 3390                                            }
 3391                                        }
 3392                                    }
 3393                                }
 3394                            }
 3395                            if !snippet_edits.is_empty() {
 3396                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3397                                let version = if let Some(buffer_version) = op.text_document.version
 3398                                {
 3399                                    local
 3400                                        .buffer_snapshot_for_lsp_version(
 3401                                            &buffer_to_edit,
 3402                                            language_server.server_id(),
 3403                                            Some(buffer_version),
 3404                                            cx,
 3405                                        )
 3406                                        .ok()
 3407                                        .map(|snapshot| snapshot.version)
 3408                                } else {
 3409                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3410                                };
 3411
 3412                                let most_recent_edit =
 3413                                    version.and_then(|version| version.most_recent());
 3414                                // Check if the edit that triggered that edit has been made by this participant.
 3415
 3416                                if let Some(most_recent_edit) = most_recent_edit {
 3417                                    cx.emit(LspStoreEvent::SnippetEdit {
 3418                                        buffer_id,
 3419                                        edits: snippet_edits,
 3420                                        most_recent_edit,
 3421                                    });
 3422                                }
 3423                            }
 3424
 3425                            local.edits_from_lsp(
 3426                                &buffer_to_edit,
 3427                                edits,
 3428                                language_server.server_id(),
 3429                                op.text_document.version,
 3430                                cx,
 3431                            )
 3432                        })
 3433                        .await?;
 3434
 3435                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3436                        buffer.finalize_last_transaction();
 3437                        buffer.start_transaction();
 3438                        for (range, text) in edits {
 3439                            buffer.edit([(range, text)], None, cx);
 3440                        }
 3441
 3442                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3443                            if push_to_history {
 3444                                buffer.finalize_last_transaction();
 3445                                buffer.get_transaction(transaction_id).cloned()
 3446                            } else {
 3447                                buffer.forget_transaction(transaction_id)
 3448                            }
 3449                        })
 3450                    });
 3451                    if let Some(transaction) = transaction {
 3452                        project_transaction.0.insert(buffer_to_edit, transaction);
 3453                    }
 3454                }
 3455            }
 3456        }
 3457
 3458        Ok(project_transaction)
 3459    }
 3460
 3461    async fn on_lsp_workspace_edit(
 3462        this: WeakEntity<LspStore>,
 3463        params: lsp::ApplyWorkspaceEditParams,
 3464        server_id: LanguageServerId,
 3465        cx: &mut AsyncApp,
 3466    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3467        let this = this.upgrade().context("project project closed")?;
 3468        let language_server = this
 3469            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3470            .context("language server not found")?;
 3471        let transaction = Self::deserialize_workspace_edit(
 3472            this.clone(),
 3473            params.edit,
 3474            true,
 3475            language_server.clone(),
 3476            cx,
 3477        )
 3478        .await
 3479        .log_err();
 3480        this.update(cx, |this, cx| {
 3481            if let Some(transaction) = transaction {
 3482                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3483
 3484                this.as_local_mut()
 3485                    .unwrap()
 3486                    .last_workspace_edits_by_language_server
 3487                    .insert(server_id, transaction);
 3488            }
 3489        });
 3490        Ok(lsp::ApplyWorkspaceEditResponse {
 3491            applied: true,
 3492            failed_change: None,
 3493            failure_reason: None,
 3494        })
 3495    }
 3496
 3497    fn remove_worktree(
 3498        &mut self,
 3499        id_to_remove: WorktreeId,
 3500        cx: &mut Context<LspStore>,
 3501    ) -> Vec<LanguageServerId> {
 3502        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3503        self.diagnostics.remove(&id_to_remove);
 3504        self.prettier_store.update(cx, |prettier_store, cx| {
 3505            prettier_store.remove_worktree(id_to_remove, cx);
 3506        });
 3507
 3508        let mut servers_to_remove = BTreeSet::default();
 3509        let mut servers_to_preserve = HashSet::default();
 3510        for (seed, state) in &self.language_server_ids {
 3511            if seed.worktree_id == id_to_remove {
 3512                servers_to_remove.insert(state.id);
 3513            } else {
 3514                servers_to_preserve.insert(state.id);
 3515            }
 3516        }
 3517        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3518        self.language_server_ids
 3519            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3520        for server_id_to_remove in &servers_to_remove {
 3521            self.language_server_watched_paths
 3522                .remove(server_id_to_remove);
 3523            self.language_server_paths_watched_for_rename
 3524                .remove(server_id_to_remove);
 3525            self.last_workspace_edits_by_language_server
 3526                .remove(server_id_to_remove);
 3527            self.language_servers.remove(server_id_to_remove);
 3528            self.buffer_pull_diagnostics_result_ids
 3529                .remove(server_id_to_remove);
 3530            self.workspace_pull_diagnostics_result_ids
 3531                .remove(server_id_to_remove);
 3532            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3533                buffer_servers.remove(server_id_to_remove);
 3534            }
 3535            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3536        }
 3537        servers_to_remove.into_iter().collect()
 3538    }
 3539
 3540    fn rebuild_watched_paths_inner<'a>(
 3541        &'a self,
 3542        language_server_id: LanguageServerId,
 3543        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3544        cx: &mut Context<LspStore>,
 3545    ) -> LanguageServerWatchedPathsBuilder {
 3546        let worktrees = self
 3547            .worktree_store
 3548            .read(cx)
 3549            .worktrees()
 3550            .filter_map(|worktree| {
 3551                self.language_servers_for_worktree(worktree.read(cx).id())
 3552                    .find(|server| server.server_id() == language_server_id)
 3553                    .map(|_| worktree)
 3554            })
 3555            .collect::<Vec<_>>();
 3556
 3557        let mut worktree_globs = HashMap::default();
 3558        let mut abs_globs = HashMap::default();
 3559        log::trace!(
 3560            "Processing new watcher paths for language server with id {}",
 3561            language_server_id
 3562        );
 3563
 3564        for watcher in watchers {
 3565            if let Some((worktree, literal_prefix, pattern)) =
 3566                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3567            {
 3568                worktree.update(cx, |worktree, _| {
 3569                    if let Some((tree, glob)) =
 3570                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3571                    {
 3572                        tree.add_path_prefix_to_scan(literal_prefix);
 3573                        worktree_globs
 3574                            .entry(tree.id())
 3575                            .or_insert_with(GlobSetBuilder::new)
 3576                            .add(glob);
 3577                    }
 3578                });
 3579            } else {
 3580                let (path, pattern) = match &watcher.glob_pattern {
 3581                    lsp::GlobPattern::String(s) => {
 3582                        let watcher_path = SanitizedPath::new(s);
 3583                        let path = glob_literal_prefix(watcher_path.as_path());
 3584                        let pattern = watcher_path
 3585                            .as_path()
 3586                            .strip_prefix(&path)
 3587                            .map(|p| p.to_string_lossy().into_owned())
 3588                            .unwrap_or_else(|e| {
 3589                                debug_panic!(
 3590                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3591                                    s,
 3592                                    path.display(),
 3593                                    e
 3594                                );
 3595                                watcher_path.as_path().to_string_lossy().into_owned()
 3596                            });
 3597                        (path, pattern)
 3598                    }
 3599                    lsp::GlobPattern::Relative(rp) => {
 3600                        let Ok(mut base_uri) = match &rp.base_uri {
 3601                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3602                            lsp::OneOf::Right(base_uri) => base_uri,
 3603                        }
 3604                        .to_file_path() else {
 3605                            continue;
 3606                        };
 3607
 3608                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3609                        let pattern = Path::new(&rp.pattern)
 3610                            .strip_prefix(&path)
 3611                            .map(|p| p.to_string_lossy().into_owned())
 3612                            .unwrap_or_else(|e| {
 3613                                debug_panic!(
 3614                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3615                                    rp.pattern,
 3616                                    path.display(),
 3617                                    e
 3618                                );
 3619                                rp.pattern.clone()
 3620                            });
 3621                        base_uri.push(path);
 3622                        (base_uri, pattern)
 3623                    }
 3624                };
 3625
 3626                if let Some(glob) = Glob::new(&pattern).log_err() {
 3627                    if !path
 3628                        .components()
 3629                        .any(|c| matches!(c, path::Component::Normal(_)))
 3630                    {
 3631                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3632                        // rather than adding a new watcher for `/`.
 3633                        for worktree in &worktrees {
 3634                            worktree_globs
 3635                                .entry(worktree.read(cx).id())
 3636                                .or_insert_with(GlobSetBuilder::new)
 3637                                .add(glob.clone());
 3638                        }
 3639                    } else {
 3640                        abs_globs
 3641                            .entry(path.into())
 3642                            .or_insert_with(GlobSetBuilder::new)
 3643                            .add(glob);
 3644                    }
 3645                }
 3646            }
 3647        }
 3648
 3649        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3650        for (worktree_id, builder) in worktree_globs {
 3651            if let Ok(globset) = builder.build() {
 3652                watch_builder.watch_worktree(worktree_id, globset);
 3653            }
 3654        }
 3655        for (abs_path, builder) in abs_globs {
 3656            if let Ok(globset) = builder.build() {
 3657                watch_builder.watch_abs_path(abs_path, globset);
 3658            }
 3659        }
 3660        watch_builder
 3661    }
 3662
 3663    fn worktree_and_path_for_file_watcher(
 3664        worktrees: &[Entity<Worktree>],
 3665        watcher: &FileSystemWatcher,
 3666        cx: &App,
 3667    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3668        worktrees.iter().find_map(|worktree| {
 3669            let tree = worktree.read(cx);
 3670            let worktree_root_path = tree.abs_path();
 3671            let path_style = tree.path_style();
 3672            match &watcher.glob_pattern {
 3673                lsp::GlobPattern::String(s) => {
 3674                    let watcher_path = SanitizedPath::new(s);
 3675                    let relative = watcher_path
 3676                        .as_path()
 3677                        .strip_prefix(&worktree_root_path)
 3678                        .ok()?;
 3679                    let literal_prefix = glob_literal_prefix(relative);
 3680                    Some((
 3681                        worktree.clone(),
 3682                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3683                        relative.to_string_lossy().into_owned(),
 3684                    ))
 3685                }
 3686                lsp::GlobPattern::Relative(rp) => {
 3687                    let base_uri = match &rp.base_uri {
 3688                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3689                        lsp::OneOf::Right(base_uri) => base_uri,
 3690                    }
 3691                    .to_file_path()
 3692                    .ok()?;
 3693                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3694                    let mut literal_prefix = relative.to_owned();
 3695                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3696                    Some((
 3697                        worktree.clone(),
 3698                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3699                        rp.pattern.clone(),
 3700                    ))
 3701                }
 3702            }
 3703        })
 3704    }
 3705
 3706    fn rebuild_watched_paths(
 3707        &mut self,
 3708        language_server_id: LanguageServerId,
 3709        cx: &mut Context<LspStore>,
 3710    ) {
 3711        let Some(registrations) = self
 3712            .language_server_dynamic_registrations
 3713            .get(&language_server_id)
 3714        else {
 3715            return;
 3716        };
 3717
 3718        let watch_builder = self.rebuild_watched_paths_inner(
 3719            language_server_id,
 3720            registrations.did_change_watched_files.values().flatten(),
 3721            cx,
 3722        );
 3723        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3724        self.language_server_watched_paths
 3725            .insert(language_server_id, watcher);
 3726
 3727        cx.notify();
 3728    }
 3729
 3730    fn on_lsp_did_change_watched_files(
 3731        &mut self,
 3732        language_server_id: LanguageServerId,
 3733        registration_id: &str,
 3734        params: DidChangeWatchedFilesRegistrationOptions,
 3735        cx: &mut Context<LspStore>,
 3736    ) {
 3737        let registrations = self
 3738            .language_server_dynamic_registrations
 3739            .entry(language_server_id)
 3740            .or_default();
 3741
 3742        registrations
 3743            .did_change_watched_files
 3744            .insert(registration_id.to_string(), params.watchers);
 3745
 3746        self.rebuild_watched_paths(language_server_id, cx);
 3747    }
 3748
 3749    fn on_lsp_unregister_did_change_watched_files(
 3750        &mut self,
 3751        language_server_id: LanguageServerId,
 3752        registration_id: &str,
 3753        cx: &mut Context<LspStore>,
 3754    ) {
 3755        let registrations = self
 3756            .language_server_dynamic_registrations
 3757            .entry(language_server_id)
 3758            .or_default();
 3759
 3760        if registrations
 3761            .did_change_watched_files
 3762            .remove(registration_id)
 3763            .is_some()
 3764        {
 3765            log::info!(
 3766                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3767                language_server_id,
 3768                registration_id
 3769            );
 3770        } else {
 3771            log::warn!(
 3772                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3773                language_server_id,
 3774                registration_id
 3775            );
 3776        }
 3777
 3778        self.rebuild_watched_paths(language_server_id, cx);
 3779    }
 3780
 3781    async fn initialization_options_for_adapter(
 3782        adapter: Arc<dyn LspAdapter>,
 3783        delegate: &Arc<dyn LspAdapterDelegate>,
 3784        cx: &mut AsyncApp,
 3785    ) -> Result<Option<serde_json::Value>> {
 3786        let Some(mut initialization_config) =
 3787            adapter.clone().initialization_options(delegate, cx).await?
 3788        else {
 3789            return Ok(None);
 3790        };
 3791
 3792        for other_adapter in delegate.registered_lsp_adapters() {
 3793            if other_adapter.name() == adapter.name() {
 3794                continue;
 3795            }
 3796            if let Ok(Some(target_config)) = other_adapter
 3797                .clone()
 3798                .additional_initialization_options(adapter.name(), delegate)
 3799                .await
 3800            {
 3801                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3802            }
 3803        }
 3804
 3805        Ok(Some(initialization_config))
 3806    }
 3807
 3808    async fn workspace_configuration_for_adapter(
 3809        adapter: Arc<dyn LspAdapter>,
 3810        delegate: &Arc<dyn LspAdapterDelegate>,
 3811        toolchain: Option<Toolchain>,
 3812        requested_uri: Option<Uri>,
 3813        cx: &mut AsyncApp,
 3814    ) -> Result<serde_json::Value> {
 3815        let mut workspace_config = adapter
 3816            .clone()
 3817            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3818            .await?;
 3819
 3820        for other_adapter in delegate.registered_lsp_adapters() {
 3821            if other_adapter.name() == adapter.name() {
 3822                continue;
 3823            }
 3824            if let Ok(Some(target_config)) = other_adapter
 3825                .clone()
 3826                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3827                .await
 3828            {
 3829                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3830            }
 3831        }
 3832
 3833        Ok(workspace_config)
 3834    }
 3835
 3836    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3837        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3838            Some(server.clone())
 3839        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3840            Some(Arc::clone(server))
 3841        } else {
 3842            None
 3843        }
 3844    }
 3845}
 3846
 3847fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3848    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3849        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3850            language_server_id: server.server_id(),
 3851            name: Some(server.name()),
 3852            message: proto::update_language_server::Variant::MetadataUpdated(
 3853                proto::ServerMetadataUpdated {
 3854                    capabilities: Some(capabilities),
 3855                    binary: Some(proto::LanguageServerBinaryInfo {
 3856                        path: server.binary().path.to_string_lossy().into_owned(),
 3857                        arguments: server
 3858                            .binary()
 3859                            .arguments
 3860                            .iter()
 3861                            .map(|arg| arg.to_string_lossy().into_owned())
 3862                            .collect(),
 3863                    }),
 3864                    configuration: serde_json::to_string(server.configuration()).ok(),
 3865                    workspace_folders: server
 3866                        .workspace_folders()
 3867                        .iter()
 3868                        .map(|uri| uri.to_string())
 3869                        .collect(),
 3870                },
 3871            ),
 3872        });
 3873    }
 3874}
 3875
 3876#[derive(Debug)]
 3877pub struct FormattableBuffer {
 3878    handle: Entity<Buffer>,
 3879    abs_path: Option<PathBuf>,
 3880    env: Option<HashMap<String, String>>,
 3881    ranges: Option<Vec<Range<Anchor>>>,
 3882}
 3883
 3884pub struct RemoteLspStore {
 3885    upstream_client: Option<AnyProtoClient>,
 3886    upstream_project_id: u64,
 3887}
 3888
 3889pub(crate) enum LspStoreMode {
 3890    Local(LocalLspStore),   // ssh host and collab host
 3891    Remote(RemoteLspStore), // collab guest
 3892}
 3893
 3894impl LspStoreMode {
 3895    fn is_local(&self) -> bool {
 3896        matches!(self, LspStoreMode::Local(_))
 3897    }
 3898}
 3899
 3900pub struct LspStore {
 3901    mode: LspStoreMode,
 3902    last_formatting_failure: Option<String>,
 3903    downstream_client: Option<(AnyProtoClient, u64)>,
 3904    nonce: u128,
 3905    buffer_store: Entity<BufferStore>,
 3906    worktree_store: Entity<WorktreeStore>,
 3907    pub languages: Arc<LanguageRegistry>,
 3908    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3909    active_entry: Option<ProjectEntryId>,
 3910    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3911    _maintain_buffer_languages: Task<()>,
 3912    diagnostic_summaries:
 3913        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3914    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3915    semantic_token_config: SemanticTokenConfig,
 3916    lsp_data: HashMap<BufferId, BufferLspData>,
 3917    next_hint_id: Arc<AtomicUsize>,
 3918}
 3919
 3920#[derive(Debug)]
 3921pub struct BufferLspData {
 3922    buffer_version: Global,
 3923    document_colors: Option<DocumentColorData>,
 3924    code_lens: Option<CodeLensData>,
 3925    semantic_tokens: Option<SemanticTokensData>,
 3926    folding_ranges: Option<FoldingRangeData>,
 3927    document_symbols: Option<DocumentSymbolsData>,
 3928    inlay_hints: BufferInlayHints,
 3929    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3930    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3931}
 3932
 3933#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3934struct LspKey {
 3935    request_type: TypeId,
 3936    server_queried: Option<LanguageServerId>,
 3937}
 3938
 3939impl BufferLspData {
 3940    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3941        Self {
 3942            buffer_version: buffer.read(cx).version(),
 3943            document_colors: None,
 3944            code_lens: None,
 3945            semantic_tokens: None,
 3946            folding_ranges: None,
 3947            document_symbols: None,
 3948            inlay_hints: BufferInlayHints::new(buffer, cx),
 3949            lsp_requests: HashMap::default(),
 3950            chunk_lsp_requests: HashMap::default(),
 3951        }
 3952    }
 3953
 3954    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3955        if let Some(document_colors) = &mut self.document_colors {
 3956            document_colors.remove_server_data(for_server);
 3957        }
 3958
 3959        if let Some(code_lens) = &mut self.code_lens {
 3960            code_lens.remove_server_data(for_server);
 3961        }
 3962
 3963        self.inlay_hints.remove_server_data(for_server);
 3964
 3965        if let Some(semantic_tokens) = &mut self.semantic_tokens {
 3966            semantic_tokens.raw_tokens.servers.remove(&for_server);
 3967            semantic_tokens
 3968                .latest_invalidation_requests
 3969                .remove(&for_server);
 3970        }
 3971
 3972        if let Some(folding_ranges) = &mut self.folding_ranges {
 3973            folding_ranges.ranges.remove(&for_server);
 3974        }
 3975
 3976        if let Some(document_symbols) = &mut self.document_symbols {
 3977            document_symbols.remove_server_data(for_server);
 3978        }
 3979    }
 3980
 3981    #[cfg(any(test, feature = "test-support"))]
 3982    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3983        &self.inlay_hints
 3984    }
 3985}
 3986
 3987#[derive(Debug)]
 3988pub enum LspStoreEvent {
 3989    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3990    LanguageServerRemoved(LanguageServerId),
 3991    LanguageServerUpdate {
 3992        language_server_id: LanguageServerId,
 3993        name: Option<LanguageServerName>,
 3994        message: proto::update_language_server::Variant,
 3995    },
 3996    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3997    LanguageServerPrompt(LanguageServerPromptRequest),
 3998    LanguageDetected {
 3999        buffer: Entity<Buffer>,
 4000        new_language: Option<Arc<Language>>,
 4001    },
 4002    Notification(String),
 4003    RefreshInlayHints {
 4004        server_id: LanguageServerId,
 4005        request_id: Option<usize>,
 4006    },
 4007    RefreshSemanticTokens {
 4008        server_id: LanguageServerId,
 4009        request_id: Option<usize>,
 4010    },
 4011    RefreshCodeLens,
 4012    DiagnosticsUpdated {
 4013        server_id: LanguageServerId,
 4014        paths: Vec<ProjectPath>,
 4015    },
 4016    DiskBasedDiagnosticsStarted {
 4017        language_server_id: LanguageServerId,
 4018    },
 4019    DiskBasedDiagnosticsFinished {
 4020        language_server_id: LanguageServerId,
 4021    },
 4022    SnippetEdit {
 4023        buffer_id: BufferId,
 4024        edits: Vec<(lsp::Range, Snippet)>,
 4025        most_recent_edit: clock::Lamport,
 4026    },
 4027    WorkspaceEditApplied(ProjectTransaction),
 4028}
 4029
 4030#[derive(Clone, Debug, Serialize)]
 4031pub struct LanguageServerStatus {
 4032    pub name: LanguageServerName,
 4033    pub server_version: Option<SharedString>,
 4034    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 4035    pub has_pending_diagnostic_updates: bool,
 4036    pub progress_tokens: HashSet<ProgressToken>,
 4037    pub worktree: Option<WorktreeId>,
 4038    pub binary: Option<LanguageServerBinary>,
 4039    pub configuration: Option<Value>,
 4040    pub workspace_folders: BTreeSet<Uri>,
 4041    pub process_id: Option<u32>,
 4042}
 4043
 4044#[derive(Clone, Debug)]
 4045struct CoreSymbol {
 4046    pub language_server_name: LanguageServerName,
 4047    pub source_worktree_id: WorktreeId,
 4048    pub source_language_server_id: LanguageServerId,
 4049    pub path: SymbolLocation,
 4050    pub name: String,
 4051    pub kind: lsp::SymbolKind,
 4052    pub range: Range<Unclipped<PointUtf16>>,
 4053    pub container_name: Option<String>,
 4054}
 4055
 4056#[derive(Clone, Debug, PartialEq, Eq)]
 4057pub enum SymbolLocation {
 4058    InProject(ProjectPath),
 4059    OutsideProject {
 4060        abs_path: Arc<Path>,
 4061        signature: [u8; 32],
 4062    },
 4063}
 4064
 4065impl SymbolLocation {
 4066    fn file_name(&self) -> Option<&str> {
 4067        match self {
 4068            Self::InProject(path) => path.path.file_name(),
 4069            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 4070        }
 4071    }
 4072}
 4073
 4074impl LspStore {
 4075    pub fn init(client: &AnyProtoClient) {
 4076        client.add_entity_request_handler(Self::handle_lsp_query);
 4077        client.add_entity_message_handler(Self::handle_lsp_query_response);
 4078        client.add_entity_request_handler(Self::handle_restart_language_servers);
 4079        client.add_entity_request_handler(Self::handle_stop_language_servers);
 4080        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 4081        client.add_entity_message_handler(Self::handle_start_language_server);
 4082        client.add_entity_message_handler(Self::handle_update_language_server);
 4083        client.add_entity_message_handler(Self::handle_language_server_log);
 4084        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 4085        client.add_entity_request_handler(Self::handle_format_buffers);
 4086        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 4087        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 4088        client.add_entity_request_handler(Self::handle_apply_code_action);
 4089        client.add_entity_request_handler(Self::handle_get_project_symbols);
 4090        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 4091        client.add_entity_request_handler(Self::handle_get_color_presentation);
 4092        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 4093        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 4094        client.add_entity_request_handler(Self::handle_refresh_semantic_tokens);
 4095        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 4096        client.add_entity_request_handler(Self::handle_on_type_formatting);
 4097        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 4098        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 4099        client.add_entity_request_handler(Self::handle_rename_project_entry);
 4100        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 4101        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 4102        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 4103        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 4104        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 4105        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 4106        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 4107
 4108        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 4109        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 4110        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 4111        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 4112        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 4113        client.add_entity_request_handler(
 4114            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 4115        );
 4116        client.add_entity_request_handler(
 4117            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 4118        );
 4119        client.add_entity_request_handler(
 4120            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 4121        );
 4122    }
 4123
 4124    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 4125        match &self.mode {
 4126            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 4127            _ => None,
 4128        }
 4129    }
 4130
 4131    pub fn as_local(&self) -> Option<&LocalLspStore> {
 4132        match &self.mode {
 4133            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4134            _ => None,
 4135        }
 4136    }
 4137
 4138    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 4139        match &mut self.mode {
 4140            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4141            _ => None,
 4142        }
 4143    }
 4144
 4145    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4146        match &self.mode {
 4147            LspStoreMode::Remote(RemoteLspStore {
 4148                upstream_client: Some(upstream_client),
 4149                upstream_project_id,
 4150                ..
 4151            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4152
 4153            LspStoreMode::Remote(RemoteLspStore {
 4154                upstream_client: None,
 4155                ..
 4156            }) => None,
 4157            LspStoreMode::Local(_) => None,
 4158        }
 4159    }
 4160
 4161    pub fn new_local(
 4162        buffer_store: Entity<BufferStore>,
 4163        worktree_store: Entity<WorktreeStore>,
 4164        prettier_store: Entity<PrettierStore>,
 4165        toolchain_store: Entity<LocalToolchainStore>,
 4166        environment: Entity<ProjectEnvironment>,
 4167        manifest_tree: Entity<ManifestTree>,
 4168        languages: Arc<LanguageRegistry>,
 4169        http_client: Arc<dyn HttpClient>,
 4170        fs: Arc<dyn Fs>,
 4171        cx: &mut Context<Self>,
 4172    ) -> Self {
 4173        let yarn = YarnPathStore::new(fs.clone(), cx);
 4174        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4175            .detach();
 4176        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4177            .detach();
 4178        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4179            .detach();
 4180        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4181            .detach();
 4182        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4183            .detach();
 4184        subscribe_to_binary_statuses(&languages, cx).detach();
 4185
 4186        let _maintain_workspace_config = {
 4187            let (sender, receiver) = watch::channel();
 4188            (Self::maintain_workspace_config(receiver, cx), sender)
 4189        };
 4190
 4191        Self {
 4192            mode: LspStoreMode::Local(LocalLspStore {
 4193                weak: cx.weak_entity(),
 4194                worktree_store: worktree_store.clone(),
 4195
 4196                supplementary_language_servers: Default::default(),
 4197                languages: languages.clone(),
 4198                language_server_ids: Default::default(),
 4199                language_servers: Default::default(),
 4200                last_workspace_edits_by_language_server: Default::default(),
 4201                language_server_watched_paths: Default::default(),
 4202                language_server_paths_watched_for_rename: Default::default(),
 4203                language_server_dynamic_registrations: Default::default(),
 4204                buffers_being_formatted: Default::default(),
 4205                buffers_to_refresh_hash_set: HashSet::default(),
 4206                buffers_to_refresh_queue: VecDeque::new(),
 4207                _background_diagnostics_worker: Task::ready(()).shared(),
 4208                buffer_snapshots: Default::default(),
 4209                prettier_store,
 4210                environment,
 4211                http_client,
 4212                fs,
 4213                yarn,
 4214                next_diagnostic_group_id: Default::default(),
 4215                diagnostics: Default::default(),
 4216                _subscription: cx.on_app_quit(|this, _| {
 4217                    this.as_local_mut()
 4218                        .unwrap()
 4219                        .shutdown_language_servers_on_quit()
 4220                }),
 4221                lsp_tree: LanguageServerTree::new(
 4222                    manifest_tree,
 4223                    languages.clone(),
 4224                    toolchain_store.clone(),
 4225                ),
 4226                toolchain_store,
 4227                registered_buffers: HashMap::default(),
 4228                buffers_opened_in_servers: HashMap::default(),
 4229                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4230                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4231                restricted_worktrees_tasks: HashMap::default(),
 4232                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4233                    .manifest_file_names(),
 4234            }),
 4235            last_formatting_failure: None,
 4236            downstream_client: None,
 4237            buffer_store,
 4238            worktree_store,
 4239            languages: languages.clone(),
 4240            language_server_statuses: Default::default(),
 4241            nonce: StdRng::from_os_rng().random(),
 4242            diagnostic_summaries: HashMap::default(),
 4243            lsp_server_capabilities: HashMap::default(),
 4244            semantic_token_config: SemanticTokenConfig::new(cx),
 4245            lsp_data: HashMap::default(),
 4246            next_hint_id: Arc::default(),
 4247            active_entry: None,
 4248            _maintain_workspace_config,
 4249            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4250        }
 4251    }
 4252
 4253    fn send_lsp_proto_request<R: LspCommand>(
 4254        &self,
 4255        buffer: Entity<Buffer>,
 4256        client: AnyProtoClient,
 4257        upstream_project_id: u64,
 4258        request: R,
 4259        cx: &mut Context<LspStore>,
 4260    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4261        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4262            return Task::ready(Ok(R::Response::default()));
 4263        }
 4264        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4265        cx.spawn(async move |this, cx| {
 4266            let response = client.request(message).await?;
 4267            let this = this.upgrade().context("project dropped")?;
 4268            request
 4269                .response_from_proto(response, this, buffer, cx.clone())
 4270                .await
 4271        })
 4272    }
 4273
 4274    pub(super) fn new_remote(
 4275        buffer_store: Entity<BufferStore>,
 4276        worktree_store: Entity<WorktreeStore>,
 4277        languages: Arc<LanguageRegistry>,
 4278        upstream_client: AnyProtoClient,
 4279        project_id: u64,
 4280        cx: &mut Context<Self>,
 4281    ) -> Self {
 4282        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4283            .detach();
 4284        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4285            .detach();
 4286        subscribe_to_binary_statuses(&languages, cx).detach();
 4287        let _maintain_workspace_config = {
 4288            let (sender, receiver) = watch::channel();
 4289            (Self::maintain_workspace_config(receiver, cx), sender)
 4290        };
 4291        Self {
 4292            mode: LspStoreMode::Remote(RemoteLspStore {
 4293                upstream_client: Some(upstream_client),
 4294                upstream_project_id: project_id,
 4295            }),
 4296            downstream_client: None,
 4297            last_formatting_failure: None,
 4298            buffer_store,
 4299            worktree_store,
 4300            languages: languages.clone(),
 4301            language_server_statuses: Default::default(),
 4302            nonce: StdRng::from_os_rng().random(),
 4303            diagnostic_summaries: HashMap::default(),
 4304            lsp_server_capabilities: HashMap::default(),
 4305            semantic_token_config: SemanticTokenConfig::new(cx),
 4306            next_hint_id: Arc::default(),
 4307            lsp_data: HashMap::default(),
 4308            active_entry: None,
 4309
 4310            _maintain_workspace_config,
 4311            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4312        }
 4313    }
 4314
 4315    fn on_buffer_store_event(
 4316        &mut self,
 4317        _: Entity<BufferStore>,
 4318        event: &BufferStoreEvent,
 4319        cx: &mut Context<Self>,
 4320    ) {
 4321        match event {
 4322            BufferStoreEvent::BufferAdded(buffer) => {
 4323                self.on_buffer_added(buffer, cx).log_err();
 4324            }
 4325            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4326                let buffer_id = buffer.read(cx).remote_id();
 4327                if let Some(local) = self.as_local_mut()
 4328                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4329                {
 4330                    local.reset_buffer(buffer, old_file, cx);
 4331
 4332                    if local.registered_buffers.contains_key(&buffer_id) {
 4333                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4334                    }
 4335                }
 4336
 4337                self.detect_language_for_buffer(buffer, cx);
 4338                if let Some(local) = self.as_local_mut() {
 4339                    local.initialize_buffer(buffer, cx);
 4340                    if local.registered_buffers.contains_key(&buffer_id) {
 4341                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4342                    }
 4343                }
 4344            }
 4345            _ => {}
 4346        }
 4347    }
 4348
 4349    fn on_worktree_store_event(
 4350        &mut self,
 4351        _: Entity<WorktreeStore>,
 4352        event: &WorktreeStoreEvent,
 4353        cx: &mut Context<Self>,
 4354    ) {
 4355        match event {
 4356            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4357                if !worktree.read(cx).is_local() {
 4358                    return;
 4359                }
 4360                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4361                    worktree::Event::UpdatedEntries(changes) => {
 4362                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4363                    }
 4364                    worktree::Event::UpdatedGitRepositories(_)
 4365                    | worktree::Event::DeletedEntry(_) => {}
 4366                })
 4367                .detach()
 4368            }
 4369            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4370            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4371                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4372            }
 4373            WorktreeStoreEvent::WorktreeReleased(..)
 4374            | WorktreeStoreEvent::WorktreeOrderChanged
 4375            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4376            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4377            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4378        }
 4379    }
 4380
 4381    fn on_prettier_store_event(
 4382        &mut self,
 4383        _: Entity<PrettierStore>,
 4384        event: &PrettierStoreEvent,
 4385        cx: &mut Context<Self>,
 4386    ) {
 4387        match event {
 4388            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4389                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4390            }
 4391            PrettierStoreEvent::LanguageServerAdded {
 4392                new_server_id,
 4393                name,
 4394                prettier_server,
 4395            } => {
 4396                self.register_supplementary_language_server(
 4397                    *new_server_id,
 4398                    name.clone(),
 4399                    prettier_server.clone(),
 4400                    cx,
 4401                );
 4402            }
 4403        }
 4404    }
 4405
 4406    fn on_toolchain_store_event(
 4407        &mut self,
 4408        _: Entity<LocalToolchainStore>,
 4409        event: &ToolchainStoreEvent,
 4410        _: &mut Context<Self>,
 4411    ) {
 4412        if let ToolchainStoreEvent::ToolchainActivated = event {
 4413            self.request_workspace_config_refresh()
 4414        }
 4415    }
 4416
 4417    fn request_workspace_config_refresh(&mut self) {
 4418        *self._maintain_workspace_config.1.borrow_mut() = ();
 4419    }
 4420
 4421    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4422        self.as_local().map(|local| local.prettier_store.clone())
 4423    }
 4424
 4425    fn on_buffer_event(
 4426        &mut self,
 4427        buffer: Entity<Buffer>,
 4428        event: &language::BufferEvent,
 4429        cx: &mut Context<Self>,
 4430    ) {
 4431        match event {
 4432            language::BufferEvent::Edited { .. } => {
 4433                self.on_buffer_edited(buffer, cx);
 4434            }
 4435
 4436            language::BufferEvent::Saved => {
 4437                self.on_buffer_saved(buffer, cx);
 4438            }
 4439
 4440            _ => {}
 4441        }
 4442    }
 4443
 4444    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4445        buffer
 4446            .read(cx)
 4447            .set_language_registry(self.languages.clone());
 4448
 4449        cx.subscribe(buffer, |this, buffer, event, cx| {
 4450            this.on_buffer_event(buffer, event, cx);
 4451        })
 4452        .detach();
 4453
 4454        self.detect_language_for_buffer(buffer, cx);
 4455        if let Some(local) = self.as_local_mut() {
 4456            local.initialize_buffer(buffer, cx);
 4457        }
 4458
 4459        Ok(())
 4460    }
 4461
 4462    pub fn refresh_background_diagnostics_for_buffers(
 4463        &mut self,
 4464        buffers: HashSet<BufferId>,
 4465        cx: &mut Context<Self>,
 4466    ) -> Shared<Task<()>> {
 4467        let Some(local) = self.as_local_mut() else {
 4468            return Task::ready(()).shared();
 4469        };
 4470        for buffer in buffers {
 4471            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4472                local.buffers_to_refresh_queue.push_back(buffer);
 4473                if local.buffers_to_refresh_queue.len() == 1 {
 4474                    local._background_diagnostics_worker =
 4475                        Self::background_diagnostics_worker(cx).shared();
 4476                }
 4477            }
 4478        }
 4479
 4480        local._background_diagnostics_worker.clone()
 4481    }
 4482
 4483    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4484        let buffer_store = self.buffer_store.clone();
 4485        let local = self.as_local_mut()?;
 4486        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4487            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4488            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4489                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4490            }
 4491        }
 4492        None
 4493    }
 4494
 4495    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4496        cx.spawn(async move |this, cx| {
 4497            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4498                task.await.log_err();
 4499            }
 4500        })
 4501    }
 4502
 4503    pub(crate) fn register_buffer_with_language_servers(
 4504        &mut self,
 4505        buffer: &Entity<Buffer>,
 4506        only_register_servers: HashSet<LanguageServerSelector>,
 4507        ignore_refcounts: bool,
 4508        cx: &mut Context<Self>,
 4509    ) -> OpenLspBufferHandle {
 4510        let buffer_id = buffer.read(cx).remote_id();
 4511        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4512        if let Some(local) = self.as_local_mut() {
 4513            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4514            if !ignore_refcounts {
 4515                *refcount += 1;
 4516            }
 4517
 4518            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4519            // 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
 4520            // 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
 4521            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4522            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4523                return handle;
 4524            };
 4525            if !file.is_local() {
 4526                return handle;
 4527            }
 4528
 4529            if ignore_refcounts || *refcount == 1 {
 4530                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4531            }
 4532            if !ignore_refcounts {
 4533                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4534                    let refcount = {
 4535                        let local = lsp_store.as_local_mut().unwrap();
 4536                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4537                            debug_panic!("bad refcounting");
 4538                            return;
 4539                        };
 4540
 4541                        *refcount -= 1;
 4542                        *refcount
 4543                    };
 4544                    if refcount == 0 {
 4545                        lsp_store.lsp_data.remove(&buffer_id);
 4546                        let local = lsp_store.as_local_mut().unwrap();
 4547                        local.registered_buffers.remove(&buffer_id);
 4548
 4549                        local.buffers_opened_in_servers.remove(&buffer_id);
 4550                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4551                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4552
 4553                            let buffer_abs_path = file.abs_path(cx);
 4554                            for (_, buffer_pull_diagnostics_result_ids) in
 4555                                &mut local.buffer_pull_diagnostics_result_ids
 4556                            {
 4557                                buffer_pull_diagnostics_result_ids.retain(
 4558                                    |_, buffer_result_ids| {
 4559                                        buffer_result_ids.remove(&buffer_abs_path);
 4560                                        !buffer_result_ids.is_empty()
 4561                                    },
 4562                                );
 4563                            }
 4564
 4565                            let diagnostic_updates = local
 4566                                .language_servers
 4567                                .keys()
 4568                                .cloned()
 4569                                .map(|server_id| DocumentDiagnosticsUpdate {
 4570                                    diagnostics: DocumentDiagnostics {
 4571                                        document_abs_path: buffer_abs_path.clone(),
 4572                                        version: None,
 4573                                        diagnostics: Vec::new(),
 4574                                    },
 4575                                    result_id: None,
 4576                                    registration_id: None,
 4577                                    server_id,
 4578                                    disk_based_sources: Cow::Borrowed(&[]),
 4579                                })
 4580                                .collect::<Vec<_>>();
 4581
 4582                            lsp_store
 4583                                .merge_diagnostic_entries(
 4584                                    diagnostic_updates,
 4585                                    |_, diagnostic, _| {
 4586                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4587                                    },
 4588                                    cx,
 4589                                )
 4590                                .context("Clearing diagnostics for the closed buffer")
 4591                                .log_err();
 4592                        }
 4593                    }
 4594                })
 4595                .detach();
 4596            }
 4597        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4598            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4599            cx.background_spawn(async move {
 4600                upstream_client
 4601                    .request(proto::RegisterBufferWithLanguageServers {
 4602                        project_id: upstream_project_id,
 4603                        buffer_id,
 4604                        only_servers: only_register_servers
 4605                            .into_iter()
 4606                            .map(|selector| {
 4607                                let selector = match selector {
 4608                                    LanguageServerSelector::Id(language_server_id) => {
 4609                                        proto::language_server_selector::Selector::ServerId(
 4610                                            language_server_id.to_proto(),
 4611                                        )
 4612                                    }
 4613                                    LanguageServerSelector::Name(language_server_name) => {
 4614                                        proto::language_server_selector::Selector::Name(
 4615                                            language_server_name.to_string(),
 4616                                        )
 4617                                    }
 4618                                };
 4619                                proto::LanguageServerSelector {
 4620                                    selector: Some(selector),
 4621                                }
 4622                            })
 4623                            .collect(),
 4624                    })
 4625                    .await
 4626            })
 4627            .detach();
 4628        } else {
 4629            // Our remote connection got closed
 4630        }
 4631        handle
 4632    }
 4633
 4634    fn maintain_buffer_languages(
 4635        languages: Arc<LanguageRegistry>,
 4636        cx: &mut Context<Self>,
 4637    ) -> Task<()> {
 4638        let mut subscription = languages.subscribe();
 4639        let mut prev_reload_count = languages.reload_count();
 4640        cx.spawn(async move |this, cx| {
 4641            while let Some(()) = subscription.next().await {
 4642                if let Some(this) = this.upgrade() {
 4643                    // If the language registry has been reloaded, then remove and
 4644                    // re-assign the languages on all open buffers.
 4645                    let reload_count = languages.reload_count();
 4646                    if reload_count > prev_reload_count {
 4647                        prev_reload_count = reload_count;
 4648                        this.update(cx, |this, cx| {
 4649                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4650                                for buffer in buffer_store.buffers() {
 4651                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4652                                    {
 4653                                        buffer.update(cx, |buffer, cx| {
 4654                                            buffer.set_language_async(None, cx)
 4655                                        });
 4656                                        if let Some(local) = this.as_local_mut() {
 4657                                            local.reset_buffer(&buffer, &f, cx);
 4658
 4659                                            if local
 4660                                                .registered_buffers
 4661                                                .contains_key(&buffer.read(cx).remote_id())
 4662                                                && let Some(file_url) =
 4663                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4664                                            {
 4665                                                local.unregister_buffer_from_language_servers(
 4666                                                    &buffer, &file_url, cx,
 4667                                                );
 4668                                            }
 4669                                        }
 4670                                    }
 4671                                }
 4672                            });
 4673                        });
 4674                    }
 4675
 4676                    this.update(cx, |this, cx| {
 4677                        let mut plain_text_buffers = Vec::new();
 4678                        let mut buffers_with_unknown_injections = Vec::new();
 4679                        for handle in this.buffer_store.read(cx).buffers() {
 4680                            let buffer = handle.read(cx);
 4681                            if buffer.language().is_none()
 4682                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4683                            {
 4684                                plain_text_buffers.push(handle);
 4685                            } else if buffer.contains_unknown_injections() {
 4686                                buffers_with_unknown_injections.push(handle);
 4687                            }
 4688                        }
 4689
 4690                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4691                        // and reused later in the invisible worktrees.
 4692                        plain_text_buffers.sort_by_key(|buffer| {
 4693                            Reverse(
 4694                                File::from_dyn(buffer.read(cx).file())
 4695                                    .map(|file| file.worktree.read(cx).is_visible()),
 4696                            )
 4697                        });
 4698
 4699                        for buffer in plain_text_buffers {
 4700                            this.detect_language_for_buffer(&buffer, cx);
 4701                            if let Some(local) = this.as_local_mut() {
 4702                                local.initialize_buffer(&buffer, cx);
 4703                                if local
 4704                                    .registered_buffers
 4705                                    .contains_key(&buffer.read(cx).remote_id())
 4706                                {
 4707                                    local.register_buffer_with_language_servers(
 4708                                        &buffer,
 4709                                        HashSet::default(),
 4710                                        cx,
 4711                                    );
 4712                                }
 4713                            }
 4714                        }
 4715
 4716                        for buffer in buffers_with_unknown_injections {
 4717                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4718                        }
 4719                    });
 4720                }
 4721            }
 4722        })
 4723    }
 4724
 4725    fn detect_language_for_buffer(
 4726        &mut self,
 4727        buffer_handle: &Entity<Buffer>,
 4728        cx: &mut Context<Self>,
 4729    ) -> Option<language::AvailableLanguage> {
 4730        // If the buffer has a language, set it and start the language server if we haven't already.
 4731        let buffer = buffer_handle.read(cx);
 4732        let file = buffer.file()?;
 4733
 4734        let content = buffer.as_rope();
 4735        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4736        if let Some(available_language) = &available_language {
 4737            if let Some(Ok(Ok(new_language))) = self
 4738                .languages
 4739                .load_language(available_language)
 4740                .now_or_never()
 4741            {
 4742                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4743            }
 4744        } else {
 4745            cx.emit(LspStoreEvent::LanguageDetected {
 4746                buffer: buffer_handle.clone(),
 4747                new_language: None,
 4748            });
 4749        }
 4750
 4751        available_language
 4752    }
 4753
 4754    pub(crate) fn set_language_for_buffer(
 4755        &mut self,
 4756        buffer_entity: &Entity<Buffer>,
 4757        new_language: Arc<Language>,
 4758        cx: &mut Context<Self>,
 4759    ) {
 4760        let buffer = buffer_entity.read(cx);
 4761        let buffer_file = buffer.file().cloned();
 4762        let buffer_id = buffer.remote_id();
 4763        if let Some(local_store) = self.as_local_mut()
 4764            && local_store.registered_buffers.contains_key(&buffer_id)
 4765            && let Some(abs_path) =
 4766                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4767            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4768        {
 4769            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4770        }
 4771        buffer_entity.update(cx, |buffer, cx| {
 4772            if buffer
 4773                .language()
 4774                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4775            {
 4776                buffer.set_language_async(Some(new_language.clone()), cx);
 4777            }
 4778        });
 4779
 4780        let settings =
 4781            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4782        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4783
 4784        let worktree_id = if let Some(file) = buffer_file {
 4785            let worktree = file.worktree.clone();
 4786
 4787            if let Some(local) = self.as_local_mut()
 4788                && local.registered_buffers.contains_key(&buffer_id)
 4789            {
 4790                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4791            }
 4792            Some(worktree.read(cx).id())
 4793        } else {
 4794            None
 4795        };
 4796
 4797        if settings.prettier.allowed
 4798            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4799        {
 4800            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4801            if let Some(prettier_store) = prettier_store {
 4802                prettier_store.update(cx, |prettier_store, cx| {
 4803                    prettier_store.install_default_prettier(
 4804                        worktree_id,
 4805                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4806                        cx,
 4807                    )
 4808                })
 4809            }
 4810        }
 4811
 4812        cx.emit(LspStoreEvent::LanguageDetected {
 4813            buffer: buffer_entity.clone(),
 4814            new_language: Some(new_language),
 4815        })
 4816    }
 4817
 4818    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4819        self.buffer_store.clone()
 4820    }
 4821
 4822    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4823        self.active_entry = active_entry;
 4824    }
 4825
 4826    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4827        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4828            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4829        {
 4830            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4831                summaries
 4832                    .iter()
 4833                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4834            });
 4835            if let Some(summary) = summaries.next() {
 4836                client
 4837                    .send(proto::UpdateDiagnosticSummary {
 4838                        project_id: downstream_project_id,
 4839                        worktree_id: worktree.id().to_proto(),
 4840                        summary: Some(summary),
 4841                        more_summaries: summaries.collect(),
 4842                    })
 4843                    .log_err();
 4844            }
 4845        }
 4846    }
 4847
 4848    fn is_capable_for_proto_request<R>(
 4849        &self,
 4850        buffer: &Entity<Buffer>,
 4851        request: &R,
 4852        cx: &App,
 4853    ) -> bool
 4854    where
 4855        R: LspCommand,
 4856    {
 4857        self.check_if_capable_for_proto_request(
 4858            buffer,
 4859            |capabilities| {
 4860                request.check_capabilities(AdapterServerCapabilities {
 4861                    server_capabilities: capabilities.clone(),
 4862                    code_action_kinds: None,
 4863                })
 4864            },
 4865            cx,
 4866        )
 4867    }
 4868
 4869    fn check_if_capable_for_proto_request<F>(
 4870        &self,
 4871        buffer: &Entity<Buffer>,
 4872        check: F,
 4873        cx: &App,
 4874    ) -> bool
 4875    where
 4876        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4877    {
 4878        let Some(language) = buffer.read(cx).language().cloned() else {
 4879            return false;
 4880        };
 4881        let registered_language_servers = self
 4882            .languages
 4883            .lsp_adapters(&language.name())
 4884            .into_iter()
 4885            .map(|lsp_adapter| lsp_adapter.name())
 4886            .collect::<HashSet<_>>();
 4887        self.language_server_statuses
 4888            .iter()
 4889            .filter_map(|(server_id, server_status)| {
 4890                // Include servers that are either registered for this language OR
 4891                // available to be loaded (for SSH remote mode where adapters like
 4892                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4893                // but only loaded on the server side)
 4894                let is_relevant = registered_language_servers.contains(&server_status.name)
 4895                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4896                is_relevant.then_some(server_id)
 4897            })
 4898            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4899            .any(check)
 4900    }
 4901
 4902    fn all_capable_for_proto_request<F>(
 4903        &self,
 4904        buffer: &Entity<Buffer>,
 4905        mut check: F,
 4906        cx: &App,
 4907    ) -> Vec<(lsp::LanguageServerId, lsp::LanguageServerName)>
 4908    where
 4909        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4910    {
 4911        let Some(language) = buffer.read(cx).language().cloned() else {
 4912            return Vec::default();
 4913        };
 4914        let registered_language_servers = self
 4915            .languages
 4916            .lsp_adapters(&language.name())
 4917            .into_iter()
 4918            .map(|lsp_adapter| lsp_adapter.name())
 4919            .collect::<HashSet<_>>();
 4920        self.language_server_statuses
 4921            .iter()
 4922            .filter_map(|(server_id, server_status)| {
 4923                // Include servers that are either registered for this language OR
 4924                // available to be loaded (for SSH remote mode where adapters like
 4925                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4926                // but only loaded on the server side)
 4927                let is_relevant = registered_language_servers.contains(&server_status.name)
 4928                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4929                is_relevant.then_some((server_id, &server_status.name))
 4930            })
 4931            .filter_map(|(server_id, server_name)| {
 4932                self.lsp_server_capabilities
 4933                    .get(server_id)
 4934                    .map(|c| (server_id, server_name, c))
 4935            })
 4936            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4937            .map(|(server_id, server_name, _)| (*server_id, server_name.clone()))
 4938            .collect()
 4939    }
 4940
 4941    pub fn request_lsp<R>(
 4942        &mut self,
 4943        buffer: Entity<Buffer>,
 4944        server: LanguageServerToQuery,
 4945        request: R,
 4946        cx: &mut Context<Self>,
 4947    ) -> Task<Result<R::Response>>
 4948    where
 4949        R: LspCommand,
 4950        <R::LspRequest as lsp::request::Request>::Result: Send,
 4951        <R::LspRequest as lsp::request::Request>::Params: Send,
 4952    {
 4953        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4954            return self.send_lsp_proto_request(
 4955                buffer,
 4956                upstream_client,
 4957                upstream_project_id,
 4958                request,
 4959                cx,
 4960            );
 4961        }
 4962
 4963        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4964            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4965                local
 4966                    .language_servers_for_buffer(buffer, cx)
 4967                    .find(|(_, server)| {
 4968                        request.check_capabilities(server.adapter_server_capabilities())
 4969                    })
 4970                    .map(|(_, server)| server.clone())
 4971            }),
 4972            LanguageServerToQuery::Other(id) => self
 4973                .language_server_for_local_buffer(buffer, id, cx)
 4974                .and_then(|(_, server)| {
 4975                    request
 4976                        .check_capabilities(server.adapter_server_capabilities())
 4977                        .then(|| Arc::clone(server))
 4978                }),
 4979        }) else {
 4980            return Task::ready(Ok(Default::default()));
 4981        };
 4982
 4983        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4984
 4985        let Some(file) = file else {
 4986            return Task::ready(Ok(Default::default()));
 4987        };
 4988
 4989        let lsp_params = match request.to_lsp_params_or_response(
 4990            &file.abs_path(cx),
 4991            buffer.read(cx),
 4992            &language_server,
 4993            cx,
 4994        ) {
 4995            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4996            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4997            Err(err) => {
 4998                let message = format!(
 4999                    "{} via {} failed: {}",
 5000                    request.display_name(),
 5001                    language_server.name(),
 5002                    err
 5003                );
 5004                // rust-analyzer likes to error with this when its still loading up
 5005                if !message.ends_with("content modified") {
 5006                    log::warn!("{message}");
 5007                }
 5008                return Task::ready(Err(anyhow!(message)));
 5009            }
 5010        };
 5011
 5012        let status = request.status();
 5013        let request_timeout = ProjectSettings::get_global(cx)
 5014            .global_lsp_settings
 5015            .get_request_timeout();
 5016
 5017        cx.spawn(async move |this, cx| {
 5018            let lsp_request = language_server.request::<R::LspRequest>(lsp_params, request_timeout);
 5019
 5020            let id = lsp_request.id();
 5021            let _cleanup = if status.is_some() {
 5022                cx.update(|cx| {
 5023                    this.update(cx, |this, cx| {
 5024                        this.on_lsp_work_start(
 5025                            language_server.server_id(),
 5026                            ProgressToken::Number(id),
 5027                            LanguageServerProgress {
 5028                                is_disk_based_diagnostics_progress: false,
 5029                                is_cancellable: false,
 5030                                title: None,
 5031                                message: status.clone(),
 5032                                percentage: None,
 5033                                last_update_at: cx.background_executor().now(),
 5034                            },
 5035                            cx,
 5036                        );
 5037                    })
 5038                })
 5039                .log_err();
 5040
 5041                Some(defer(|| {
 5042                    cx.update(|cx| {
 5043                        this.update(cx, |this, cx| {
 5044                            this.on_lsp_work_end(
 5045                                language_server.server_id(),
 5046                                ProgressToken::Number(id),
 5047                                cx,
 5048                            );
 5049                        })
 5050                    })
 5051                    .log_err();
 5052                }))
 5053            } else {
 5054                None
 5055            };
 5056
 5057            let result = lsp_request.await.into_response();
 5058
 5059            let response = result.map_err(|err| {
 5060                let message = format!(
 5061                    "{} via {} failed: {}",
 5062                    request.display_name(),
 5063                    language_server.name(),
 5064                    err
 5065                );
 5066                // rust-analyzer likes to error with this when its still loading up
 5067                if !message.ends_with("content modified") {
 5068                    log::warn!("{message}");
 5069                }
 5070                anyhow::anyhow!(message)
 5071            })?;
 5072
 5073            request
 5074                .response_from_lsp(
 5075                    response,
 5076                    this.upgrade().context("no app context")?,
 5077                    buffer,
 5078                    language_server.server_id(),
 5079                    cx.clone(),
 5080                )
 5081                .await
 5082        })
 5083    }
 5084
 5085    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 5086        let mut language_formatters_to_check = Vec::new();
 5087        for buffer in self.buffer_store.read(cx).buffers() {
 5088            let buffer = buffer.read(cx);
 5089            let buffer_file = File::from_dyn(buffer.file());
 5090            let buffer_language = buffer.language();
 5091            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 5092            if buffer_language.is_some() {
 5093                language_formatters_to_check.push((
 5094                    buffer_file.map(|f| f.worktree_id(cx)),
 5095                    settings.into_owned(),
 5096                ));
 5097            }
 5098        }
 5099
 5100        self.request_workspace_config_refresh();
 5101
 5102        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 5103            prettier_store.update(cx, |prettier_store, cx| {
 5104                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 5105            })
 5106        }
 5107
 5108        let new_semantic_token_rules = crate::project_settings::ProjectSettings::get_global(cx)
 5109            .global_lsp_settings
 5110            .semantic_token_rules
 5111            .clone();
 5112        self.semantic_token_config
 5113            .update_rules(new_semantic_token_rules);
 5114        // Always clear cached stylizers so that changes to language-specific
 5115        // semantic token rules (e.g. from extension install/uninstall) are
 5116        // picked up. Stylizers are recreated lazily, so this is cheap.
 5117        self.semantic_token_config.clear_stylizers();
 5118
 5119        let new_global_semantic_tokens_mode =
 5120            all_language_settings(None, cx).defaults.semantic_tokens;
 5121        if self
 5122            .semantic_token_config
 5123            .update_global_mode(new_global_semantic_tokens_mode)
 5124        {
 5125            self.restart_all_language_servers(cx);
 5126        }
 5127
 5128        cx.notify();
 5129    }
 5130
 5131    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 5132        let buffer_store = self.buffer_store.clone();
 5133        let Some(local) = self.as_local_mut() else {
 5134            return;
 5135        };
 5136        let mut adapters = BTreeMap::default();
 5137        let get_adapter = {
 5138            let languages = local.languages.clone();
 5139            let environment = local.environment.clone();
 5140            let weak = local.weak.clone();
 5141            let worktree_store = local.worktree_store.clone();
 5142            let http_client = local.http_client.clone();
 5143            let fs = local.fs.clone();
 5144            move |worktree_id, cx: &mut App| {
 5145                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 5146                Some(LocalLspAdapterDelegate::new(
 5147                    languages.clone(),
 5148                    &environment,
 5149                    weak.clone(),
 5150                    &worktree,
 5151                    http_client.clone(),
 5152                    fs.clone(),
 5153                    cx,
 5154                ))
 5155            }
 5156        };
 5157
 5158        let mut messages_to_report = Vec::new();
 5159        let (new_tree, to_stop) = {
 5160            let mut rebase = local.lsp_tree.rebase();
 5161            let buffers = buffer_store
 5162                .read(cx)
 5163                .buffers()
 5164                .filter_map(|buffer| {
 5165                    let raw_buffer = buffer.read(cx);
 5166                    if !local
 5167                        .registered_buffers
 5168                        .contains_key(&raw_buffer.remote_id())
 5169                    {
 5170                        return None;
 5171                    }
 5172                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5173                    let language = raw_buffer.language().cloned()?;
 5174                    Some((file, language, raw_buffer.remote_id()))
 5175                })
 5176                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5177            for (file, language, buffer_id) in buffers {
 5178                let worktree_id = file.worktree_id(cx);
 5179                let Some(worktree) = local
 5180                    .worktree_store
 5181                    .read(cx)
 5182                    .worktree_for_id(worktree_id, cx)
 5183                else {
 5184                    continue;
 5185                };
 5186
 5187                if let Some((_, apply)) = local.reuse_existing_language_server(
 5188                    rebase.server_tree(),
 5189                    &worktree,
 5190                    &language.name(),
 5191                    cx,
 5192                ) {
 5193                    (apply)(rebase.server_tree());
 5194                } else if let Some(lsp_delegate) = adapters
 5195                    .entry(worktree_id)
 5196                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5197                    .clone()
 5198                {
 5199                    let delegate =
 5200                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5201                    let path = file
 5202                        .path()
 5203                        .parent()
 5204                        .map(Arc::from)
 5205                        .unwrap_or_else(|| file.path().clone());
 5206                    let worktree_path = ProjectPath { worktree_id, path };
 5207                    let abs_path = file.abs_path(cx);
 5208                    let nodes = rebase
 5209                        .walk(
 5210                            worktree_path,
 5211                            language.name(),
 5212                            language.manifest(),
 5213                            delegate.clone(),
 5214                            cx,
 5215                        )
 5216                        .collect::<Vec<_>>();
 5217                    for node in nodes {
 5218                        let server_id = node.server_id_or_init(|disposition| {
 5219                            let path = &disposition.path;
 5220                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5221                            let key = LanguageServerSeed {
 5222                                worktree_id,
 5223                                name: disposition.server_name.clone(),
 5224                                settings: LanguageServerSeedSettings {
 5225                                    binary: disposition.settings.binary.clone(),
 5226                                    initialization_options: disposition
 5227                                        .settings
 5228                                        .initialization_options
 5229                                        .clone(),
 5230                                },
 5231                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5232                                    path.worktree_id,
 5233                                    &path.path,
 5234                                    language.name(),
 5235                                ),
 5236                            };
 5237                            local.language_server_ids.remove(&key);
 5238
 5239                            let server_id = local.get_or_insert_language_server(
 5240                                &worktree,
 5241                                lsp_delegate.clone(),
 5242                                disposition,
 5243                                &language.name(),
 5244                                cx,
 5245                            );
 5246                            if let Some(state) = local.language_servers.get(&server_id)
 5247                                && let Ok(uri) = uri
 5248                            {
 5249                                state.add_workspace_folder(uri);
 5250                            };
 5251                            server_id
 5252                        });
 5253
 5254                        if let Some(language_server_id) = server_id {
 5255                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5256                                language_server_id,
 5257                                name: node.name(),
 5258                                message:
 5259                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5260                                        proto::RegisteredForBuffer {
 5261                                            buffer_abs_path: abs_path
 5262                                                .to_string_lossy()
 5263                                                .into_owned(),
 5264                                            buffer_id: buffer_id.to_proto(),
 5265                                        },
 5266                                    ),
 5267                            });
 5268                        }
 5269                    }
 5270                } else {
 5271                    continue;
 5272                }
 5273            }
 5274            rebase.finish()
 5275        };
 5276        for message in messages_to_report {
 5277            cx.emit(message);
 5278        }
 5279        local.lsp_tree = new_tree;
 5280        for (id, _) in to_stop {
 5281            self.stop_local_language_server(id, cx).detach();
 5282        }
 5283    }
 5284
 5285    pub fn apply_code_action(
 5286        &self,
 5287        buffer_handle: Entity<Buffer>,
 5288        mut action: CodeAction,
 5289        push_to_history: bool,
 5290        cx: &mut Context<Self>,
 5291    ) -> Task<Result<ProjectTransaction>> {
 5292        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5293            let request = proto::ApplyCodeAction {
 5294                project_id,
 5295                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5296                action: Some(Self::serialize_code_action(&action)),
 5297            };
 5298            let buffer_store = self.buffer_store();
 5299            cx.spawn(async move |_, cx| {
 5300                let response = upstream_client
 5301                    .request(request)
 5302                    .await?
 5303                    .transaction
 5304                    .context("missing transaction")?;
 5305
 5306                buffer_store
 5307                    .update(cx, |buffer_store, cx| {
 5308                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5309                    })
 5310                    .await
 5311            })
 5312        } else if self.mode.is_local() {
 5313            let Some((_, lang_server, request_timeout)) = buffer_handle.update(cx, |buffer, cx| {
 5314                let request_timeout = ProjectSettings::get_global(cx)
 5315                    .global_lsp_settings
 5316                    .get_request_timeout();
 5317                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5318                    .map(|(adapter, server)| (adapter.clone(), server.clone(), request_timeout))
 5319            }) else {
 5320                return Task::ready(Ok(ProjectTransaction::default()));
 5321            };
 5322
 5323            cx.spawn(async move |this, cx| {
 5324                LocalLspStore::try_resolve_code_action(&lang_server, &mut action, request_timeout)
 5325                    .await
 5326                    .context("resolving a code action")?;
 5327                if let Some(edit) = action.lsp_action.edit()
 5328                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5329                        return LocalLspStore::deserialize_workspace_edit(
 5330                            this.upgrade().context("no app present")?,
 5331                            edit.clone(),
 5332                            push_to_history,
 5333
 5334                            lang_server.clone(),
 5335                            cx,
 5336                        )
 5337                        .await;
 5338                    }
 5339
 5340                let Some(command) = action.lsp_action.command() else {
 5341                    return Ok(ProjectTransaction::default())
 5342                };
 5343
 5344                let server_capabilities = lang_server.capabilities();
 5345                let available_commands = server_capabilities
 5346                    .execute_command_provider
 5347                    .as_ref()
 5348                    .map(|options| options.commands.as_slice())
 5349                    .unwrap_or_default();
 5350
 5351                if !available_commands.contains(&command.command) {
 5352                    log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5353                    return Ok(ProjectTransaction::default())
 5354                }
 5355
 5356                let request_timeout = cx.update(|app|
 5357                    ProjectSettings::get_global(app)
 5358                    .global_lsp_settings
 5359                    .get_request_timeout()
 5360                );
 5361
 5362                this.update(cx, |this, _| {
 5363                    this.as_local_mut()
 5364                        .unwrap()
 5365                        .last_workspace_edits_by_language_server
 5366                        .remove(&lang_server.server_id());
 5367                })?;
 5368
 5369                let _result = lang_server
 5370                    .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5371                        command: command.command.clone(),
 5372                        arguments: command.arguments.clone().unwrap_or_default(),
 5373                        ..lsp::ExecuteCommandParams::default()
 5374                    }, request_timeout)
 5375                    .await.into_response()
 5376                    .context("execute command")?;
 5377
 5378                return this.update(cx, |this, _| {
 5379                    this.as_local_mut()
 5380                        .unwrap()
 5381                        .last_workspace_edits_by_language_server
 5382                        .remove(&lang_server.server_id())
 5383                        .unwrap_or_default()
 5384                });
 5385            })
 5386        } else {
 5387            Task::ready(Err(anyhow!("no upstream client and not local")))
 5388        }
 5389    }
 5390
 5391    pub fn apply_code_action_kind(
 5392        &mut self,
 5393        buffers: HashSet<Entity<Buffer>>,
 5394        kind: CodeActionKind,
 5395        push_to_history: bool,
 5396        cx: &mut Context<Self>,
 5397    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5398        if self.as_local().is_some() {
 5399            cx.spawn(async move |lsp_store, cx| {
 5400                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5401                let result = LocalLspStore::execute_code_action_kind_locally(
 5402                    lsp_store.clone(),
 5403                    buffers,
 5404                    kind,
 5405                    push_to_history,
 5406                    cx,
 5407                )
 5408                .await;
 5409                lsp_store.update(cx, |lsp_store, _| {
 5410                    lsp_store.update_last_formatting_failure(&result);
 5411                })?;
 5412                result
 5413            })
 5414        } else if let Some((client, project_id)) = self.upstream_client() {
 5415            let buffer_store = self.buffer_store();
 5416            cx.spawn(async move |lsp_store, cx| {
 5417                let result = client
 5418                    .request(proto::ApplyCodeActionKind {
 5419                        project_id,
 5420                        kind: kind.as_str().to_owned(),
 5421                        buffer_ids: buffers
 5422                            .iter()
 5423                            .map(|buffer| {
 5424                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5425                            })
 5426                            .collect(),
 5427                    })
 5428                    .await
 5429                    .and_then(|result| result.transaction.context("missing transaction"));
 5430                lsp_store.update(cx, |lsp_store, _| {
 5431                    lsp_store.update_last_formatting_failure(&result);
 5432                })?;
 5433
 5434                let transaction_response = result?;
 5435                buffer_store
 5436                    .update(cx, |buffer_store, cx| {
 5437                        buffer_store.deserialize_project_transaction(
 5438                            transaction_response,
 5439                            push_to_history,
 5440                            cx,
 5441                        )
 5442                    })
 5443                    .await
 5444            })
 5445        } else {
 5446            Task::ready(Ok(ProjectTransaction::default()))
 5447        }
 5448    }
 5449
 5450    pub fn resolved_hint(
 5451        &mut self,
 5452        buffer_id: BufferId,
 5453        id: InlayId,
 5454        cx: &mut Context<Self>,
 5455    ) -> Option<ResolvedHint> {
 5456        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5457
 5458        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5459        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5460        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5461        let (server_id, resolve_data) = match &hint.resolve_state {
 5462            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5463            ResolveState::Resolving => {
 5464                return Some(ResolvedHint::Resolving(
 5465                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5466                ));
 5467            }
 5468            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5469        };
 5470
 5471        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5472        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5473        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5474            id,
 5475            cx.spawn(async move |lsp_store, cx| {
 5476                let resolved_hint = resolve_task.await;
 5477                lsp_store
 5478                    .update(cx, |lsp_store, _| {
 5479                        if let Some(old_inlay_hint) = lsp_store
 5480                            .lsp_data
 5481                            .get_mut(&buffer_id)
 5482                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5483                        {
 5484                            match resolved_hint {
 5485                                Ok(resolved_hint) => {
 5486                                    *old_inlay_hint = resolved_hint;
 5487                                }
 5488                                Err(e) => {
 5489                                    old_inlay_hint.resolve_state =
 5490                                        ResolveState::CanResolve(server_id, resolve_data);
 5491                                    log::error!("Inlay hint resolve failed: {e:#}");
 5492                                }
 5493                            }
 5494                        }
 5495                    })
 5496                    .ok();
 5497            })
 5498            .shared(),
 5499        );
 5500        debug_assert!(
 5501            previous_task.is_none(),
 5502            "Did not change hint's resolve state after spawning its resolve"
 5503        );
 5504        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5505        None
 5506    }
 5507
 5508    pub(crate) fn linked_edits(
 5509        &mut self,
 5510        buffer: &Entity<Buffer>,
 5511        position: Anchor,
 5512        cx: &mut Context<Self>,
 5513    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5514        let snapshot = buffer.read(cx).snapshot();
 5515        let scope = snapshot.language_scope_at(position);
 5516        let Some(server_id) = self
 5517            .as_local()
 5518            .and_then(|local| {
 5519                buffer.update(cx, |buffer, cx| {
 5520                    local
 5521                        .language_servers_for_buffer(buffer, cx)
 5522                        .filter(|(_, server)| {
 5523                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5524                        })
 5525                        .filter(|(adapter, _)| {
 5526                            scope
 5527                                .as_ref()
 5528                                .map(|scope| scope.language_allowed(&adapter.name))
 5529                                .unwrap_or(true)
 5530                        })
 5531                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5532                        .next()
 5533                })
 5534            })
 5535            .or_else(|| {
 5536                self.upstream_client()
 5537                    .is_some()
 5538                    .then_some(LanguageServerToQuery::FirstCapable)
 5539            })
 5540            .filter(|_| {
 5541                maybe!({
 5542                    let language = buffer.read(cx).language_at(position)?;
 5543                    Some(
 5544                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5545                            .linked_edits,
 5546                    )
 5547                }) == Some(true)
 5548            })
 5549        else {
 5550            return Task::ready(Ok(Vec::new()));
 5551        };
 5552
 5553        self.request_lsp(
 5554            buffer.clone(),
 5555            server_id,
 5556            LinkedEditingRange { position },
 5557            cx,
 5558        )
 5559    }
 5560
 5561    fn apply_on_type_formatting(
 5562        &mut self,
 5563        buffer: Entity<Buffer>,
 5564        position: Anchor,
 5565        trigger: String,
 5566        cx: &mut Context<Self>,
 5567    ) -> Task<Result<Option<Transaction>>> {
 5568        if let Some((client, project_id)) = self.upstream_client() {
 5569            if !self.check_if_capable_for_proto_request(
 5570                &buffer,
 5571                |capabilities| {
 5572                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5573                },
 5574                cx,
 5575            ) {
 5576                return Task::ready(Ok(None));
 5577            }
 5578            let request = proto::OnTypeFormatting {
 5579                project_id,
 5580                buffer_id: buffer.read(cx).remote_id().into(),
 5581                position: Some(serialize_anchor(&position)),
 5582                trigger,
 5583                version: serialize_version(&buffer.read(cx).version()),
 5584            };
 5585            cx.background_spawn(async move {
 5586                client
 5587                    .request(request)
 5588                    .await?
 5589                    .transaction
 5590                    .map(language::proto::deserialize_transaction)
 5591                    .transpose()
 5592            })
 5593        } else if let Some(local) = self.as_local_mut() {
 5594            let buffer_id = buffer.read(cx).remote_id();
 5595            local.buffers_being_formatted.insert(buffer_id);
 5596            cx.spawn(async move |this, cx| {
 5597                let _cleanup = defer({
 5598                    let this = this.clone();
 5599                    let mut cx = cx.clone();
 5600                    move || {
 5601                        this.update(&mut cx, |this, _| {
 5602                            if let Some(local) = this.as_local_mut() {
 5603                                local.buffers_being_formatted.remove(&buffer_id);
 5604                            }
 5605                        })
 5606                        .ok();
 5607                    }
 5608                });
 5609
 5610                buffer
 5611                    .update(cx, |buffer, _| {
 5612                        buffer.wait_for_edits(Some(position.timestamp()))
 5613                    })
 5614                    .await?;
 5615                this.update(cx, |this, cx| {
 5616                    let position = position.to_point_utf16(buffer.read(cx));
 5617                    this.on_type_format(buffer, position, trigger, false, cx)
 5618                })?
 5619                .await
 5620            })
 5621        } else {
 5622            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5623        }
 5624    }
 5625
 5626    pub fn on_type_format<T: ToPointUtf16>(
 5627        &mut self,
 5628        buffer: Entity<Buffer>,
 5629        position: T,
 5630        trigger: String,
 5631        push_to_history: bool,
 5632        cx: &mut Context<Self>,
 5633    ) -> Task<Result<Option<Transaction>>> {
 5634        let position = position.to_point_utf16(buffer.read(cx));
 5635        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5636    }
 5637
 5638    fn on_type_format_impl(
 5639        &mut self,
 5640        buffer: Entity<Buffer>,
 5641        position: PointUtf16,
 5642        trigger: String,
 5643        push_to_history: bool,
 5644        cx: &mut Context<Self>,
 5645    ) -> Task<Result<Option<Transaction>>> {
 5646        let options = buffer.update(cx, |buffer, cx| {
 5647            lsp_command::lsp_formatting_options(
 5648                language_settings(
 5649                    buffer.language_at(position).map(|l| l.name()),
 5650                    buffer.file(),
 5651                    cx,
 5652                )
 5653                .as_ref(),
 5654            )
 5655        });
 5656
 5657        cx.spawn(async move |this, cx| {
 5658            if let Some(waiter) =
 5659                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5660            {
 5661                waiter.await?;
 5662            }
 5663            cx.update(|cx| {
 5664                this.update(cx, |this, cx| {
 5665                    this.request_lsp(
 5666                        buffer.clone(),
 5667                        LanguageServerToQuery::FirstCapable,
 5668                        OnTypeFormatting {
 5669                            position,
 5670                            trigger,
 5671                            options,
 5672                            push_to_history,
 5673                        },
 5674                        cx,
 5675                    )
 5676                })
 5677            })?
 5678            .await
 5679        })
 5680    }
 5681
 5682    pub fn definitions(
 5683        &mut self,
 5684        buffer: &Entity<Buffer>,
 5685        position: PointUtf16,
 5686        cx: &mut Context<Self>,
 5687    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5688        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5689            let request = GetDefinitions { position };
 5690            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5691                return Task::ready(Ok(None));
 5692            }
 5693
 5694            let request_timeout = ProjectSettings::get_global(cx)
 5695                .global_lsp_settings
 5696                .get_request_timeout();
 5697
 5698            let request_task = upstream_client.request_lsp(
 5699                project_id,
 5700                None,
 5701                request_timeout,
 5702                cx.background_executor().clone(),
 5703                request.to_proto(project_id, buffer.read(cx)),
 5704            );
 5705            let buffer = buffer.clone();
 5706            cx.spawn(async move |weak_lsp_store, cx| {
 5707                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5708                    return Ok(None);
 5709                };
 5710                let Some(responses) = request_task.await? else {
 5711                    return Ok(None);
 5712                };
 5713                let actions = join_all(responses.payload.into_iter().map(|response| {
 5714                    GetDefinitions { position }.response_from_proto(
 5715                        response.response,
 5716                        lsp_store.clone(),
 5717                        buffer.clone(),
 5718                        cx.clone(),
 5719                    )
 5720                }))
 5721                .await;
 5722
 5723                Ok(Some(
 5724                    actions
 5725                        .into_iter()
 5726                        .collect::<Result<Vec<Vec<_>>>>()?
 5727                        .into_iter()
 5728                        .flatten()
 5729                        .dedup()
 5730                        .collect(),
 5731                ))
 5732            })
 5733        } else {
 5734            let definitions_task = self.request_multiple_lsp_locally(
 5735                buffer,
 5736                Some(position),
 5737                GetDefinitions { position },
 5738                cx,
 5739            );
 5740            cx.background_spawn(async move {
 5741                Ok(Some(
 5742                    definitions_task
 5743                        .await
 5744                        .into_iter()
 5745                        .flat_map(|(_, definitions)| definitions)
 5746                        .dedup()
 5747                        .collect(),
 5748                ))
 5749            })
 5750        }
 5751    }
 5752
 5753    pub fn declarations(
 5754        &mut self,
 5755        buffer: &Entity<Buffer>,
 5756        position: PointUtf16,
 5757        cx: &mut Context<Self>,
 5758    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5759        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5760            let request = GetDeclarations { position };
 5761            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5762                return Task::ready(Ok(None));
 5763            }
 5764            let request_timeout = ProjectSettings::get_global(cx)
 5765                .global_lsp_settings
 5766                .get_request_timeout();
 5767            let request_task = upstream_client.request_lsp(
 5768                project_id,
 5769                None,
 5770                request_timeout,
 5771                cx.background_executor().clone(),
 5772                request.to_proto(project_id, buffer.read(cx)),
 5773            );
 5774            let buffer = buffer.clone();
 5775            cx.spawn(async move |weak_lsp_store, cx| {
 5776                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5777                    return Ok(None);
 5778                };
 5779                let Some(responses) = request_task.await? else {
 5780                    return Ok(None);
 5781                };
 5782                let actions = join_all(responses.payload.into_iter().map(|response| {
 5783                    GetDeclarations { position }.response_from_proto(
 5784                        response.response,
 5785                        lsp_store.clone(),
 5786                        buffer.clone(),
 5787                        cx.clone(),
 5788                    )
 5789                }))
 5790                .await;
 5791
 5792                Ok(Some(
 5793                    actions
 5794                        .into_iter()
 5795                        .collect::<Result<Vec<Vec<_>>>>()?
 5796                        .into_iter()
 5797                        .flatten()
 5798                        .dedup()
 5799                        .collect(),
 5800                ))
 5801            })
 5802        } else {
 5803            let declarations_task = self.request_multiple_lsp_locally(
 5804                buffer,
 5805                Some(position),
 5806                GetDeclarations { position },
 5807                cx,
 5808            );
 5809            cx.background_spawn(async move {
 5810                Ok(Some(
 5811                    declarations_task
 5812                        .await
 5813                        .into_iter()
 5814                        .flat_map(|(_, declarations)| declarations)
 5815                        .dedup()
 5816                        .collect(),
 5817                ))
 5818            })
 5819        }
 5820    }
 5821
 5822    pub fn type_definitions(
 5823        &mut self,
 5824        buffer: &Entity<Buffer>,
 5825        position: PointUtf16,
 5826        cx: &mut Context<Self>,
 5827    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5828        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5829            let request = GetTypeDefinitions { position };
 5830            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5831                return Task::ready(Ok(None));
 5832            }
 5833            let request_timeout = ProjectSettings::get_global(cx)
 5834                .global_lsp_settings
 5835                .get_request_timeout();
 5836            let request_task = upstream_client.request_lsp(
 5837                project_id,
 5838                None,
 5839                request_timeout,
 5840                cx.background_executor().clone(),
 5841                request.to_proto(project_id, buffer.read(cx)),
 5842            );
 5843            let buffer = buffer.clone();
 5844            cx.spawn(async move |weak_lsp_store, cx| {
 5845                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5846                    return Ok(None);
 5847                };
 5848                let Some(responses) = request_task.await? else {
 5849                    return Ok(None);
 5850                };
 5851                let actions = join_all(responses.payload.into_iter().map(|response| {
 5852                    GetTypeDefinitions { position }.response_from_proto(
 5853                        response.response,
 5854                        lsp_store.clone(),
 5855                        buffer.clone(),
 5856                        cx.clone(),
 5857                    )
 5858                }))
 5859                .await;
 5860
 5861                Ok(Some(
 5862                    actions
 5863                        .into_iter()
 5864                        .collect::<Result<Vec<Vec<_>>>>()?
 5865                        .into_iter()
 5866                        .flatten()
 5867                        .dedup()
 5868                        .collect(),
 5869                ))
 5870            })
 5871        } else {
 5872            let type_definitions_task = self.request_multiple_lsp_locally(
 5873                buffer,
 5874                Some(position),
 5875                GetTypeDefinitions { position },
 5876                cx,
 5877            );
 5878            cx.background_spawn(async move {
 5879                Ok(Some(
 5880                    type_definitions_task
 5881                        .await
 5882                        .into_iter()
 5883                        .flat_map(|(_, type_definitions)| type_definitions)
 5884                        .dedup()
 5885                        .collect(),
 5886                ))
 5887            })
 5888        }
 5889    }
 5890
 5891    pub fn implementations(
 5892        &mut self,
 5893        buffer: &Entity<Buffer>,
 5894        position: PointUtf16,
 5895        cx: &mut Context<Self>,
 5896    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5897        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5898            let request = GetImplementations { position };
 5899            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5900                return Task::ready(Ok(None));
 5901            }
 5902
 5903            let request_timeout = ProjectSettings::get_global(cx)
 5904                .global_lsp_settings
 5905                .get_request_timeout();
 5906            let request_task = upstream_client.request_lsp(
 5907                project_id,
 5908                None,
 5909                request_timeout,
 5910                cx.background_executor().clone(),
 5911                request.to_proto(project_id, buffer.read(cx)),
 5912            );
 5913            let buffer = buffer.clone();
 5914            cx.spawn(async move |weak_lsp_store, cx| {
 5915                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5916                    return Ok(None);
 5917                };
 5918                let Some(responses) = request_task.await? else {
 5919                    return Ok(None);
 5920                };
 5921                let actions = join_all(responses.payload.into_iter().map(|response| {
 5922                    GetImplementations { position }.response_from_proto(
 5923                        response.response,
 5924                        lsp_store.clone(),
 5925                        buffer.clone(),
 5926                        cx.clone(),
 5927                    )
 5928                }))
 5929                .await;
 5930
 5931                Ok(Some(
 5932                    actions
 5933                        .into_iter()
 5934                        .collect::<Result<Vec<Vec<_>>>>()?
 5935                        .into_iter()
 5936                        .flatten()
 5937                        .dedup()
 5938                        .collect(),
 5939                ))
 5940            })
 5941        } else {
 5942            let implementations_task = self.request_multiple_lsp_locally(
 5943                buffer,
 5944                Some(position),
 5945                GetImplementations { position },
 5946                cx,
 5947            );
 5948            cx.background_spawn(async move {
 5949                Ok(Some(
 5950                    implementations_task
 5951                        .await
 5952                        .into_iter()
 5953                        .flat_map(|(_, implementations)| implementations)
 5954                        .dedup()
 5955                        .collect(),
 5956                ))
 5957            })
 5958        }
 5959    }
 5960
 5961    pub fn references(
 5962        &mut self,
 5963        buffer: &Entity<Buffer>,
 5964        position: PointUtf16,
 5965        cx: &mut Context<Self>,
 5966    ) -> Task<Result<Option<Vec<Location>>>> {
 5967        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5968            let request = GetReferences { position };
 5969            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5970                return Task::ready(Ok(None));
 5971            }
 5972
 5973            let request_timeout = ProjectSettings::get_global(cx)
 5974                .global_lsp_settings
 5975                .get_request_timeout();
 5976            let request_task = upstream_client.request_lsp(
 5977                project_id,
 5978                None,
 5979                request_timeout,
 5980                cx.background_executor().clone(),
 5981                request.to_proto(project_id, buffer.read(cx)),
 5982            );
 5983            let buffer = buffer.clone();
 5984            cx.spawn(async move |weak_lsp_store, cx| {
 5985                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5986                    return Ok(None);
 5987                };
 5988                let Some(responses) = request_task.await? else {
 5989                    return Ok(None);
 5990                };
 5991
 5992                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5993                    GetReferences { position }.response_from_proto(
 5994                        lsp_response.response,
 5995                        lsp_store.clone(),
 5996                        buffer.clone(),
 5997                        cx.clone(),
 5998                    )
 5999                }))
 6000                .await
 6001                .into_iter()
 6002                .collect::<Result<Vec<Vec<_>>>>()?
 6003                .into_iter()
 6004                .flatten()
 6005                .dedup()
 6006                .collect();
 6007                Ok(Some(locations))
 6008            })
 6009        } else {
 6010            let references_task = self.request_multiple_lsp_locally(
 6011                buffer,
 6012                Some(position),
 6013                GetReferences { position },
 6014                cx,
 6015            );
 6016            cx.background_spawn(async move {
 6017                Ok(Some(
 6018                    references_task
 6019                        .await
 6020                        .into_iter()
 6021                        .flat_map(|(_, references)| references)
 6022                        .dedup()
 6023                        .collect(),
 6024                ))
 6025            })
 6026        }
 6027    }
 6028
 6029    pub fn code_actions(
 6030        &mut self,
 6031        buffer: &Entity<Buffer>,
 6032        range: Range<Anchor>,
 6033        kinds: Option<Vec<CodeActionKind>>,
 6034        cx: &mut Context<Self>,
 6035    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6036        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6037            let request = GetCodeActions {
 6038                range: range.clone(),
 6039                kinds: kinds.clone(),
 6040            };
 6041            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6042                return Task::ready(Ok(None));
 6043            }
 6044            let request_timeout = ProjectSettings::get_global(cx)
 6045                .global_lsp_settings
 6046                .get_request_timeout();
 6047            let request_task = upstream_client.request_lsp(
 6048                project_id,
 6049                None,
 6050                request_timeout,
 6051                cx.background_executor().clone(),
 6052                request.to_proto(project_id, buffer.read(cx)),
 6053            );
 6054            let buffer = buffer.clone();
 6055            cx.spawn(async move |weak_lsp_store, cx| {
 6056                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6057                    return Ok(None);
 6058                };
 6059                let Some(responses) = request_task.await? else {
 6060                    return Ok(None);
 6061                };
 6062                let actions = join_all(responses.payload.into_iter().map(|response| {
 6063                    GetCodeActions {
 6064                        range: range.clone(),
 6065                        kinds: kinds.clone(),
 6066                    }
 6067                    .response_from_proto(
 6068                        response.response,
 6069                        lsp_store.clone(),
 6070                        buffer.clone(),
 6071                        cx.clone(),
 6072                    )
 6073                }))
 6074                .await;
 6075
 6076                Ok(Some(
 6077                    actions
 6078                        .into_iter()
 6079                        .collect::<Result<Vec<Vec<_>>>>()?
 6080                        .into_iter()
 6081                        .flatten()
 6082                        .collect(),
 6083                ))
 6084            })
 6085        } else {
 6086            let all_actions_task = self.request_multiple_lsp_locally(
 6087                buffer,
 6088                Some(range.start),
 6089                GetCodeActions { range, kinds },
 6090                cx,
 6091            );
 6092            cx.background_spawn(async move {
 6093                Ok(Some(
 6094                    all_actions_task
 6095                        .await
 6096                        .into_iter()
 6097                        .flat_map(|(_, actions)| actions)
 6098                        .collect(),
 6099                ))
 6100            })
 6101        }
 6102    }
 6103
 6104    #[inline(never)]
 6105    pub fn completions(
 6106        &self,
 6107        buffer: &Entity<Buffer>,
 6108        position: PointUtf16,
 6109        context: CompletionContext,
 6110        cx: &mut Context<Self>,
 6111    ) -> Task<Result<Vec<CompletionResponse>>> {
 6112        let language_registry = self.languages.clone();
 6113
 6114        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6115            let snapshot = buffer.read(cx).snapshot();
 6116            let offset = position.to_offset(&snapshot);
 6117            let scope = snapshot.language_scope_at(offset);
 6118            let capable_lsps = self.all_capable_for_proto_request(
 6119                buffer,
 6120                |server_name, capabilities| {
 6121                    capabilities.completion_provider.is_some()
 6122                        && scope
 6123                            .as_ref()
 6124                            .map(|scope| scope.language_allowed(server_name))
 6125                            .unwrap_or(true)
 6126                },
 6127                cx,
 6128            );
 6129            if capable_lsps.is_empty() {
 6130                return Task::ready(Ok(Vec::new()));
 6131            }
 6132
 6133            let language = buffer.read(cx).language().cloned();
 6134
 6135            let buffer = buffer.clone();
 6136
 6137            cx.spawn(async move |this, cx| {
 6138                let requests = join_all(
 6139                    capable_lsps
 6140                        .into_iter()
 6141                        .map(|(id, server_name)| {
 6142                            let request = GetCompletions {
 6143                                position,
 6144                                context: context.clone(),
 6145                                server_id: Some(id),
 6146                            };
 6147                            let buffer = buffer.clone();
 6148                            let language = language.clone();
 6149                            let lsp_adapter = language.as_ref().and_then(|language| {
 6150                                let adapters = language_registry.lsp_adapters(&language.name());
 6151                                adapters
 6152                                    .iter()
 6153                                    .find(|adapter| adapter.name() == server_name)
 6154                                    .or_else(|| adapters.first())
 6155                                    .cloned()
 6156                            });
 6157                            let upstream_client = upstream_client.clone();
 6158                            let response = this
 6159                                .update(cx, |this, cx| {
 6160                                    this.send_lsp_proto_request(
 6161                                        buffer,
 6162                                        upstream_client,
 6163                                        project_id,
 6164                                        request,
 6165                                        cx,
 6166                                    )
 6167                                })
 6168                                .log_err();
 6169                            async move {
 6170                                let response = response?.await.log_err()?;
 6171
 6172                                let completions = populate_labels_for_completions(
 6173                                    response.completions,
 6174                                    language,
 6175                                    lsp_adapter,
 6176                                )
 6177                                .await;
 6178
 6179                                Some(CompletionResponse {
 6180                                    completions,
 6181                                    display_options: CompletionDisplayOptions::default(),
 6182                                    is_incomplete: response.is_incomplete,
 6183                                })
 6184                            }
 6185                        })
 6186                        .collect::<Vec<_>>(),
 6187                );
 6188                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6189            })
 6190        } else if let Some(local) = self.as_local() {
 6191            let snapshot = buffer.read(cx).snapshot();
 6192            let offset = position.to_offset(&snapshot);
 6193            let scope = snapshot.language_scope_at(offset);
 6194            let language = snapshot.language().cloned();
 6195            let completion_settings = language_settings(
 6196                language.as_ref().map(|language| language.name()),
 6197                buffer.read(cx).file(),
 6198                cx,
 6199            )
 6200            .completions
 6201            .clone();
 6202            if !completion_settings.lsp {
 6203                return Task::ready(Ok(Vec::new()));
 6204            }
 6205
 6206            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6207                local
 6208                    .language_servers_for_buffer(buffer, cx)
 6209                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6210                    .filter(|(adapter, _)| {
 6211                        scope
 6212                            .as_ref()
 6213                            .map(|scope| scope.language_allowed(&adapter.name))
 6214                            .unwrap_or(true)
 6215                    })
 6216                    .map(|(_, server)| server.server_id())
 6217                    .collect()
 6218            });
 6219
 6220            let buffer = buffer.clone();
 6221            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6222            let lsp_timeout = if lsp_timeout > 0 {
 6223                Some(Duration::from_millis(lsp_timeout))
 6224            } else {
 6225                None
 6226            };
 6227            cx.spawn(async move |this,  cx| {
 6228                let mut tasks = Vec::with_capacity(server_ids.len());
 6229                this.update(cx, |lsp_store, cx| {
 6230                    for server_id in server_ids {
 6231                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6232                        let lsp_timeout = lsp_timeout
 6233                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6234                        let mut timeout = cx.background_spawn(async move {
 6235                            match lsp_timeout {
 6236                                Some(lsp_timeout) => {
 6237                                    lsp_timeout.await;
 6238                                    true
 6239                                },
 6240                                None => false,
 6241                            }
 6242                        }).fuse();
 6243                        let mut lsp_request = lsp_store.request_lsp(
 6244                            buffer.clone(),
 6245                            LanguageServerToQuery::Other(server_id),
 6246                            GetCompletions {
 6247                                position,
 6248                                context: context.clone(),
 6249                                server_id: Some(server_id),
 6250                            },
 6251                            cx,
 6252                        ).fuse();
 6253                        let new_task = cx.background_spawn(async move {
 6254                            select_biased! {
 6255                                response = lsp_request => anyhow::Ok(Some(response?)),
 6256                                timeout_happened = timeout => {
 6257                                    if timeout_happened {
 6258                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6259                                        Ok(None)
 6260                                    } else {
 6261                                        let completions = lsp_request.await?;
 6262                                        Ok(Some(completions))
 6263                                    }
 6264                                },
 6265                            }
 6266                        });
 6267                        tasks.push((lsp_adapter, new_task));
 6268                    }
 6269                })?;
 6270
 6271                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6272                    let completion_response = task.await.ok()??;
 6273                    let completions = populate_labels_for_completions(
 6274                            completion_response.completions,
 6275                            language.clone(),
 6276                            lsp_adapter,
 6277                        )
 6278                        .await;
 6279                    Some(CompletionResponse {
 6280                        completions,
 6281                        display_options: CompletionDisplayOptions::default(),
 6282                        is_incomplete: completion_response.is_incomplete,
 6283                    })
 6284                });
 6285
 6286                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6287
 6288                Ok(responses.into_iter().flatten().collect())
 6289            })
 6290        } else {
 6291            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6292        }
 6293    }
 6294
 6295    pub fn resolve_completions(
 6296        &self,
 6297        buffer: Entity<Buffer>,
 6298        completion_indices: Vec<usize>,
 6299        completions: Rc<RefCell<Box<[Completion]>>>,
 6300        cx: &mut Context<Self>,
 6301    ) -> Task<Result<bool>> {
 6302        let client = self.upstream_client();
 6303        let buffer_id = buffer.read(cx).remote_id();
 6304        let buffer_snapshot = buffer.read(cx).snapshot();
 6305
 6306        if !self.check_if_capable_for_proto_request(
 6307            &buffer,
 6308            GetCompletions::can_resolve_completions,
 6309            cx,
 6310        ) {
 6311            return Task::ready(Ok(false));
 6312        }
 6313        cx.spawn(async move |lsp_store, cx| {
 6314            let request_timeout = cx.update(|app| {
 6315                ProjectSettings::get_global(app)
 6316                    .global_lsp_settings
 6317                    .get_request_timeout()
 6318            });
 6319
 6320            let mut did_resolve = false;
 6321            if let Some((client, project_id)) = client {
 6322                for completion_index in completion_indices {
 6323                    let server_id = {
 6324                        let completion = &completions.borrow()[completion_index];
 6325                        completion.source.server_id()
 6326                    };
 6327                    if let Some(server_id) = server_id {
 6328                        if Self::resolve_completion_remote(
 6329                            project_id,
 6330                            server_id,
 6331                            buffer_id,
 6332                            completions.clone(),
 6333                            completion_index,
 6334                            client.clone(),
 6335                        )
 6336                        .await
 6337                        .log_err()
 6338                        .is_some()
 6339                        {
 6340                            did_resolve = true;
 6341                        }
 6342                    } else {
 6343                        resolve_word_completion(
 6344                            &buffer_snapshot,
 6345                            &mut completions.borrow_mut()[completion_index],
 6346                        );
 6347                    }
 6348                }
 6349            } else {
 6350                for completion_index in completion_indices {
 6351                    let server_id = {
 6352                        let completion = &completions.borrow()[completion_index];
 6353                        completion.source.server_id()
 6354                    };
 6355                    if let Some(server_id) = server_id {
 6356                        let server_and_adapter = lsp_store
 6357                            .read_with(cx, |lsp_store, _| {
 6358                                let server = lsp_store.language_server_for_id(server_id)?;
 6359                                let adapter =
 6360                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6361                                Some((server, adapter))
 6362                            })
 6363                            .ok()
 6364                            .flatten();
 6365                        let Some((server, adapter)) = server_and_adapter else {
 6366                            continue;
 6367                        };
 6368
 6369                        let resolved = Self::resolve_completion_local(
 6370                            server,
 6371                            completions.clone(),
 6372                            completion_index,
 6373                            request_timeout,
 6374                        )
 6375                        .await
 6376                        .log_err()
 6377                        .is_some();
 6378                        if resolved {
 6379                            Self::regenerate_completion_labels(
 6380                                adapter,
 6381                                &buffer_snapshot,
 6382                                completions.clone(),
 6383                                completion_index,
 6384                            )
 6385                            .await
 6386                            .log_err();
 6387                            did_resolve = true;
 6388                        }
 6389                    } else {
 6390                        resolve_word_completion(
 6391                            &buffer_snapshot,
 6392                            &mut completions.borrow_mut()[completion_index],
 6393                        );
 6394                    }
 6395                }
 6396            }
 6397
 6398            Ok(did_resolve)
 6399        })
 6400    }
 6401
 6402    async fn resolve_completion_local(
 6403        server: Arc<lsp::LanguageServer>,
 6404        completions: Rc<RefCell<Box<[Completion]>>>,
 6405        completion_index: usize,
 6406        request_timeout: Duration,
 6407    ) -> Result<()> {
 6408        let server_id = server.server_id();
 6409        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6410            return Ok(());
 6411        }
 6412
 6413        let request = {
 6414            let completion = &completions.borrow()[completion_index];
 6415            match &completion.source {
 6416                CompletionSource::Lsp {
 6417                    lsp_completion,
 6418                    resolved,
 6419                    server_id: completion_server_id,
 6420                    ..
 6421                } => {
 6422                    if *resolved {
 6423                        return Ok(());
 6424                    }
 6425                    anyhow::ensure!(
 6426                        server_id == *completion_server_id,
 6427                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6428                    );
 6429                    server.request::<lsp::request::ResolveCompletionItem>(
 6430                        *lsp_completion.clone(),
 6431                        request_timeout,
 6432                    )
 6433                }
 6434                CompletionSource::BufferWord { .. }
 6435                | CompletionSource::Dap { .. }
 6436                | CompletionSource::Custom => {
 6437                    return Ok(());
 6438                }
 6439            }
 6440        };
 6441        let resolved_completion = request
 6442            .await
 6443            .into_response()
 6444            .context("resolve completion")?;
 6445
 6446        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6447        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6448
 6449        let mut completions = completions.borrow_mut();
 6450        let completion = &mut completions[completion_index];
 6451        if let CompletionSource::Lsp {
 6452            lsp_completion,
 6453            resolved,
 6454            server_id: completion_server_id,
 6455            ..
 6456        } = &mut completion.source
 6457        {
 6458            if *resolved {
 6459                return Ok(());
 6460            }
 6461            anyhow::ensure!(
 6462                server_id == *completion_server_id,
 6463                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6464            );
 6465            **lsp_completion = resolved_completion;
 6466            *resolved = true;
 6467        }
 6468        Ok(())
 6469    }
 6470
 6471    async fn regenerate_completion_labels(
 6472        adapter: Arc<CachedLspAdapter>,
 6473        snapshot: &BufferSnapshot,
 6474        completions: Rc<RefCell<Box<[Completion]>>>,
 6475        completion_index: usize,
 6476    ) -> Result<()> {
 6477        let completion_item = completions.borrow()[completion_index]
 6478            .source
 6479            .lsp_completion(true)
 6480            .map(Cow::into_owned);
 6481        if let Some(lsp_documentation) = completion_item
 6482            .as_ref()
 6483            .and_then(|completion_item| completion_item.documentation.clone())
 6484        {
 6485            let mut completions = completions.borrow_mut();
 6486            let completion = &mut completions[completion_index];
 6487            completion.documentation = Some(lsp_documentation.into());
 6488        } else {
 6489            let mut completions = completions.borrow_mut();
 6490            let completion = &mut completions[completion_index];
 6491            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6492        }
 6493
 6494        let mut new_label = match completion_item {
 6495            Some(completion_item) => {
 6496                // Some language servers always return `detail` lazily via resolve, regardless of
 6497                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6498                // See: https://github.com/yioneko/vtsls/issues/213
 6499                let language = snapshot.language();
 6500                match language {
 6501                    Some(language) => {
 6502                        adapter
 6503                            .labels_for_completions(
 6504                                std::slice::from_ref(&completion_item),
 6505                                language,
 6506                            )
 6507                            .await?
 6508                    }
 6509                    None => Vec::new(),
 6510                }
 6511                .pop()
 6512                .flatten()
 6513                .unwrap_or_else(|| {
 6514                    CodeLabel::fallback_for_completion(
 6515                        &completion_item,
 6516                        language.map(|language| language.as_ref()),
 6517                    )
 6518                })
 6519            }
 6520            None => CodeLabel::plain(
 6521                completions.borrow()[completion_index].new_text.clone(),
 6522                None,
 6523            ),
 6524        };
 6525        ensure_uniform_list_compatible_label(&mut new_label);
 6526
 6527        let mut completions = completions.borrow_mut();
 6528        let completion = &mut completions[completion_index];
 6529        if completion.label.filter_text() == new_label.filter_text() {
 6530            completion.label = new_label;
 6531        } else {
 6532            log::error!(
 6533                "Resolved completion changed display label from {} to {}. \
 6534                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6535                completion.label.text(),
 6536                new_label.text(),
 6537                completion.label.filter_text(),
 6538                new_label.filter_text()
 6539            );
 6540        }
 6541
 6542        Ok(())
 6543    }
 6544
 6545    async fn resolve_completion_remote(
 6546        project_id: u64,
 6547        server_id: LanguageServerId,
 6548        buffer_id: BufferId,
 6549        completions: Rc<RefCell<Box<[Completion]>>>,
 6550        completion_index: usize,
 6551        client: AnyProtoClient,
 6552    ) -> Result<()> {
 6553        let lsp_completion = {
 6554            let completion = &completions.borrow()[completion_index];
 6555            match &completion.source {
 6556                CompletionSource::Lsp {
 6557                    lsp_completion,
 6558                    resolved,
 6559                    server_id: completion_server_id,
 6560                    ..
 6561                } => {
 6562                    anyhow::ensure!(
 6563                        server_id == *completion_server_id,
 6564                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6565                    );
 6566                    if *resolved {
 6567                        return Ok(());
 6568                    }
 6569                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6570                }
 6571                CompletionSource::Custom
 6572                | CompletionSource::Dap { .. }
 6573                | CompletionSource::BufferWord { .. } => {
 6574                    return Ok(());
 6575                }
 6576            }
 6577        };
 6578        let request = proto::ResolveCompletionDocumentation {
 6579            project_id,
 6580            language_server_id: server_id.0 as u64,
 6581            lsp_completion,
 6582            buffer_id: buffer_id.into(),
 6583        };
 6584
 6585        let response = client
 6586            .request(request)
 6587            .await
 6588            .context("completion documentation resolve proto request")?;
 6589        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6590
 6591        let documentation = if response.documentation.is_empty() {
 6592            CompletionDocumentation::Undocumented
 6593        } else if response.documentation_is_markdown {
 6594            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6595        } else if response.documentation.lines().count() <= 1 {
 6596            CompletionDocumentation::SingleLine(response.documentation.into())
 6597        } else {
 6598            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6599        };
 6600
 6601        let mut completions = completions.borrow_mut();
 6602        let completion = &mut completions[completion_index];
 6603        completion.documentation = Some(documentation);
 6604        if let CompletionSource::Lsp {
 6605            insert_range,
 6606            lsp_completion,
 6607            resolved,
 6608            server_id: completion_server_id,
 6609            lsp_defaults: _,
 6610        } = &mut completion.source
 6611        {
 6612            let completion_insert_range = response
 6613                .old_insert_start
 6614                .and_then(deserialize_anchor)
 6615                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6616            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6617
 6618            if *resolved {
 6619                return Ok(());
 6620            }
 6621            anyhow::ensure!(
 6622                server_id == *completion_server_id,
 6623                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6624            );
 6625            **lsp_completion = resolved_lsp_completion;
 6626            *resolved = true;
 6627        }
 6628
 6629        let replace_range = response
 6630            .old_replace_start
 6631            .and_then(deserialize_anchor)
 6632            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6633        if let Some((old_replace_start, old_replace_end)) = replace_range
 6634            && !response.new_text.is_empty()
 6635        {
 6636            completion.new_text = response.new_text;
 6637            completion.replace_range = old_replace_start..old_replace_end;
 6638        }
 6639
 6640        Ok(())
 6641    }
 6642
 6643    pub fn apply_additional_edits_for_completion(
 6644        &self,
 6645        buffer_handle: Entity<Buffer>,
 6646        completions: Rc<RefCell<Box<[Completion]>>>,
 6647        completion_index: usize,
 6648        push_to_history: bool,
 6649        cx: &mut Context<Self>,
 6650    ) -> Task<Result<Option<Transaction>>> {
 6651        if let Some((client, project_id)) = self.upstream_client() {
 6652            let buffer = buffer_handle.read(cx);
 6653            let buffer_id = buffer.remote_id();
 6654            cx.spawn(async move |_, cx| {
 6655                let request = {
 6656                    let completion = completions.borrow()[completion_index].clone();
 6657                    proto::ApplyCompletionAdditionalEdits {
 6658                        project_id,
 6659                        buffer_id: buffer_id.into(),
 6660                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6661                            replace_range: completion.replace_range,
 6662                            new_text: completion.new_text,
 6663                            source: completion.source,
 6664                        })),
 6665                    }
 6666                };
 6667
 6668                let Some(transaction) = client.request(request).await?.transaction else {
 6669                    return Ok(None);
 6670                };
 6671
 6672                let transaction = language::proto::deserialize_transaction(transaction)?;
 6673                buffer_handle
 6674                    .update(cx, |buffer, _| {
 6675                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6676                    })
 6677                    .await?;
 6678                if push_to_history {
 6679                    buffer_handle.update(cx, |buffer, _| {
 6680                        buffer.push_transaction(transaction.clone(), Instant::now());
 6681                        buffer.finalize_last_transaction();
 6682                    });
 6683                }
 6684                Ok(Some(transaction))
 6685            })
 6686        } else {
 6687            let request_timeout = ProjectSettings::get_global(cx)
 6688                .global_lsp_settings
 6689                .get_request_timeout();
 6690
 6691            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6692                let completion = &completions.borrow()[completion_index];
 6693                let server_id = completion.source.server_id()?;
 6694                Some(
 6695                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6696                        .1
 6697                        .clone(),
 6698                )
 6699            }) else {
 6700                return Task::ready(Ok(None));
 6701            };
 6702
 6703            cx.spawn(async move |this, cx| {
 6704                Self::resolve_completion_local(
 6705                    server.clone(),
 6706                    completions.clone(),
 6707                    completion_index,
 6708                    request_timeout,
 6709                )
 6710                .await
 6711                .context("resolving completion")?;
 6712                let completion = completions.borrow()[completion_index].clone();
 6713                let additional_text_edits = completion
 6714                    .source
 6715                    .lsp_completion(true)
 6716                    .as_ref()
 6717                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6718                if let Some(edits) = additional_text_edits {
 6719                    let edits = this
 6720                        .update(cx, |this, cx| {
 6721                            this.as_local_mut().unwrap().edits_from_lsp(
 6722                                &buffer_handle,
 6723                                edits,
 6724                                server.server_id(),
 6725                                None,
 6726                                cx,
 6727                            )
 6728                        })?
 6729                        .await?;
 6730
 6731                    buffer_handle.update(cx, |buffer, cx| {
 6732                        buffer.finalize_last_transaction();
 6733                        buffer.start_transaction();
 6734
 6735                        for (range, text) in edits {
 6736                            let primary = &completion.replace_range;
 6737
 6738                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6739                            // and the primary completion is just an insertion (empty range), then this is likely
 6740                            // an auto-import scenario and should not be considered overlapping
 6741                            // https://github.com/zed-industries/zed/issues/26136
 6742                            let is_file_start_auto_import = {
 6743                                let snapshot = buffer.snapshot();
 6744                                let primary_start_point = primary.start.to_point(&snapshot);
 6745                                let range_start_point = range.start.to_point(&snapshot);
 6746
 6747                                let result = primary_start_point.row == 0
 6748                                    && primary_start_point.column == 0
 6749                                    && range_start_point.row == 0
 6750                                    && range_start_point.column == 0;
 6751
 6752                                result
 6753                            };
 6754
 6755                            let has_overlap = if is_file_start_auto_import {
 6756                                false
 6757                            } else {
 6758                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6759                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6760                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6761                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6762                                let result = start_within || end_within;
 6763                                result
 6764                            };
 6765
 6766                            //Skip additional edits which overlap with the primary completion edit
 6767                            //https://github.com/zed-industries/zed/pull/1871
 6768                            if !has_overlap {
 6769                                buffer.edit([(range, text)], None, cx);
 6770                            }
 6771                        }
 6772
 6773                        let transaction = if buffer.end_transaction(cx).is_some() {
 6774                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6775                            if !push_to_history {
 6776                                buffer.forget_transaction(transaction.id);
 6777                            }
 6778                            Some(transaction)
 6779                        } else {
 6780                            None
 6781                        };
 6782                        Ok(transaction)
 6783                    })
 6784                } else {
 6785                    Ok(None)
 6786                }
 6787            })
 6788        }
 6789    }
 6790
 6791    pub fn pull_diagnostics(
 6792        &mut self,
 6793        buffer: Entity<Buffer>,
 6794        cx: &mut Context<Self>,
 6795    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6796        let buffer_id = buffer.read(cx).remote_id();
 6797
 6798        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6799            let mut suitable_capabilities = None;
 6800            // Are we capable for proto request?
 6801            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6802                &buffer,
 6803                |capabilities| {
 6804                    if let Some(caps) = &capabilities.diagnostic_provider {
 6805                        suitable_capabilities = Some(caps.clone());
 6806                        true
 6807                    } else {
 6808                        false
 6809                    }
 6810                },
 6811                cx,
 6812            );
 6813            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6814            let Some(dynamic_caps) = suitable_capabilities else {
 6815                return Task::ready(Ok(None));
 6816            };
 6817            assert!(any_server_has_diagnostics_provider);
 6818
 6819            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6820            let request = GetDocumentDiagnostics {
 6821                previous_result_id: None,
 6822                identifier,
 6823                registration_id: None,
 6824            };
 6825            let request_timeout = ProjectSettings::get_global(cx)
 6826                .global_lsp_settings
 6827                .get_request_timeout();
 6828            let request_task = client.request_lsp(
 6829                upstream_project_id,
 6830                None,
 6831                request_timeout,
 6832                cx.background_executor().clone(),
 6833                request.to_proto(upstream_project_id, buffer.read(cx)),
 6834            );
 6835            cx.background_spawn(async move {
 6836                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6837                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6838                // Do not attempt to further process the dummy responses here.
 6839                let _response = request_task.await?;
 6840                Ok(None)
 6841            })
 6842        } else {
 6843            let servers = buffer.update(cx, |buffer, cx| {
 6844                self.running_language_servers_for_local_buffer(buffer, cx)
 6845                    .map(|(_, server)| server.clone())
 6846                    .collect::<Vec<_>>()
 6847            });
 6848
 6849            let pull_diagnostics = servers
 6850                .into_iter()
 6851                .flat_map(|server| {
 6852                    let result = maybe!({
 6853                        let local = self.as_local()?;
 6854                        let server_id = server.server_id();
 6855                        let providers_with_identifiers = local
 6856                            .language_server_dynamic_registrations
 6857                            .get(&server_id)
 6858                            .into_iter()
 6859                            .flat_map(|registrations| registrations.diagnostics.clone())
 6860                            .collect::<Vec<_>>();
 6861                        Some(
 6862                            providers_with_identifiers
 6863                                .into_iter()
 6864                                .map(|(registration_id, dynamic_caps)| {
 6865                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6866                                    let registration_id = registration_id.map(SharedString::from);
 6867                                    let result_id = self.result_id_for_buffer_pull(
 6868                                        server_id,
 6869                                        buffer_id,
 6870                                        &registration_id,
 6871                                        cx,
 6872                                    );
 6873                                    self.request_lsp(
 6874                                        buffer.clone(),
 6875                                        LanguageServerToQuery::Other(server_id),
 6876                                        GetDocumentDiagnostics {
 6877                                            previous_result_id: result_id,
 6878                                            registration_id,
 6879                                            identifier,
 6880                                        },
 6881                                        cx,
 6882                                    )
 6883                                })
 6884                                .collect::<Vec<_>>(),
 6885                        )
 6886                    });
 6887
 6888                    result.unwrap_or_default()
 6889                })
 6890                .collect::<Vec<_>>();
 6891
 6892            cx.background_spawn(async move {
 6893                let mut responses = Vec::new();
 6894                for diagnostics in join_all(pull_diagnostics).await {
 6895                    responses.extend(diagnostics?);
 6896                }
 6897                Ok(Some(responses))
 6898            })
 6899        }
 6900    }
 6901
 6902    pub fn applicable_inlay_chunks(
 6903        &mut self,
 6904        buffer: &Entity<Buffer>,
 6905        ranges: &[Range<text::Anchor>],
 6906        cx: &mut Context<Self>,
 6907    ) -> Vec<Range<BufferRow>> {
 6908        let buffer_snapshot = buffer.read(cx).snapshot();
 6909        let ranges = ranges
 6910            .iter()
 6911            .map(|range| range.to_point(&buffer_snapshot))
 6912            .collect::<Vec<_>>();
 6913
 6914        self.latest_lsp_data(buffer, cx)
 6915            .inlay_hints
 6916            .applicable_chunks(ranges.as_slice())
 6917            .map(|chunk| chunk.row_range())
 6918            .collect()
 6919    }
 6920
 6921    pub fn invalidate_inlay_hints<'a>(
 6922        &'a mut self,
 6923        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6924    ) {
 6925        for buffer_id in for_buffers {
 6926            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6927                lsp_data.inlay_hints.clear();
 6928            }
 6929        }
 6930    }
 6931
 6932    pub fn inlay_hints(
 6933        &mut self,
 6934        invalidate: InvalidationStrategy,
 6935        buffer: Entity<Buffer>,
 6936        ranges: Vec<Range<text::Anchor>>,
 6937        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6938        cx: &mut Context<Self>,
 6939    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6940        let next_hint_id = self.next_hint_id.clone();
 6941        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6942        let query_version = lsp_data.buffer_version.clone();
 6943        let mut lsp_refresh_requested = false;
 6944        let for_server = if let InvalidationStrategy::RefreshRequested {
 6945            server_id,
 6946            request_id,
 6947        } = invalidate
 6948        {
 6949            let invalidated = lsp_data
 6950                .inlay_hints
 6951                .invalidate_for_server_refresh(server_id, request_id);
 6952            lsp_refresh_requested = invalidated;
 6953            Some(server_id)
 6954        } else {
 6955            None
 6956        };
 6957        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6958        let known_chunks = known_chunks
 6959            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6960            .map(|(_, known_chunks)| known_chunks)
 6961            .unwrap_or_default();
 6962
 6963        let buffer_snapshot = buffer.read(cx).snapshot();
 6964        let ranges = ranges
 6965            .iter()
 6966            .map(|range| range.to_point(&buffer_snapshot))
 6967            .collect::<Vec<_>>();
 6968
 6969        let mut hint_fetch_tasks = Vec::new();
 6970        let mut cached_inlay_hints = None;
 6971        let mut ranges_to_query = None;
 6972        let applicable_chunks = existing_inlay_hints
 6973            .applicable_chunks(ranges.as_slice())
 6974            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 6975            .collect::<Vec<_>>();
 6976        if applicable_chunks.is_empty() {
 6977            return HashMap::default();
 6978        }
 6979
 6980        for row_chunk in applicable_chunks {
 6981            match (
 6982                existing_inlay_hints
 6983                    .cached_hints(&row_chunk)
 6984                    .filter(|_| !lsp_refresh_requested)
 6985                    .cloned(),
 6986                existing_inlay_hints
 6987                    .fetched_hints(&row_chunk)
 6988                    .as_ref()
 6989                    .filter(|_| !lsp_refresh_requested)
 6990                    .cloned(),
 6991            ) {
 6992                (None, None) => {
 6993                    let chunk_range = row_chunk.anchor_range();
 6994                    ranges_to_query
 6995                        .get_or_insert_with(Vec::new)
 6996                        .push((row_chunk, chunk_range));
 6997                }
 6998                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 6999                (Some(cached_hints), None) => {
 7000                    for (server_id, cached_hints) in cached_hints {
 7001                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7002                            cached_inlay_hints
 7003                                .get_or_insert_with(HashMap::default)
 7004                                .entry(row_chunk.row_range())
 7005                                .or_insert_with(HashMap::default)
 7006                                .entry(server_id)
 7007                                .or_insert_with(Vec::new)
 7008                                .extend(cached_hints);
 7009                        }
 7010                    }
 7011                }
 7012                (Some(cached_hints), Some(fetched_hints)) => {
 7013                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7014                    for (server_id, cached_hints) in cached_hints {
 7015                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7016                            cached_inlay_hints
 7017                                .get_or_insert_with(HashMap::default)
 7018                                .entry(row_chunk.row_range())
 7019                                .or_insert_with(HashMap::default)
 7020                                .entry(server_id)
 7021                                .or_insert_with(Vec::new)
 7022                                .extend(cached_hints);
 7023                        }
 7024                    }
 7025                }
 7026            }
 7027        }
 7028
 7029        if hint_fetch_tasks.is_empty()
 7030            && ranges_to_query
 7031                .as_ref()
 7032                .is_none_or(|ranges| ranges.is_empty())
 7033            && let Some(cached_inlay_hints) = cached_inlay_hints
 7034        {
 7035            cached_inlay_hints
 7036                .into_iter()
 7037                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7038                .collect()
 7039        } else {
 7040            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7041                // When a server refresh was requested, other servers' cached hints
 7042                // are unaffected by the refresh and must be included in the result.
 7043                // Otherwise apply_fetched_hints (with should_invalidate()=true)
 7044                // removes all visible hints but only adds back the requesting
 7045                // server's new hints, permanently losing other servers' hints.
 7046                let other_servers_cached: CacheInlayHints = if lsp_refresh_requested {
 7047                    lsp_data
 7048                        .inlay_hints
 7049                        .cached_hints(&chunk)
 7050                        .cloned()
 7051                        .unwrap_or_default()
 7052                } else {
 7053                    HashMap::default()
 7054                };
 7055
 7056                let next_hint_id = next_hint_id.clone();
 7057                let buffer = buffer.clone();
 7058                let query_version = query_version.clone();
 7059                let new_inlay_hints = cx
 7060                    .spawn(async move |lsp_store, cx| {
 7061                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7062                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7063                        })?;
 7064                        new_fetch_task
 7065                            .await
 7066                            .and_then(|new_hints_by_server| {
 7067                                lsp_store.update(cx, |lsp_store, cx| {
 7068                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7069                                    let update_cache = lsp_data.buffer_version == query_version;
 7070                                    if new_hints_by_server.is_empty() {
 7071                                        if update_cache {
 7072                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7073                                        }
 7074                                        other_servers_cached
 7075                                    } else {
 7076                                        let mut result = other_servers_cached;
 7077                                        for (server_id, new_hints) in new_hints_by_server {
 7078                                            let new_hints = new_hints
 7079                                                .into_iter()
 7080                                                .map(|new_hint| {
 7081                                                    (
 7082                                                        InlayId::Hint(next_hint_id.fetch_add(
 7083                                                            1,
 7084                                                            atomic::Ordering::AcqRel,
 7085                                                        )),
 7086                                                        new_hint,
 7087                                                    )
 7088                                                })
 7089                                                .collect::<Vec<_>>();
 7090                                            if update_cache {
 7091                                                lsp_data.inlay_hints.insert_new_hints(
 7092                                                    chunk,
 7093                                                    server_id,
 7094                                                    new_hints.clone(),
 7095                                                );
 7096                                            }
 7097                                            result.insert(server_id, new_hints);
 7098                                        }
 7099                                        result
 7100                                    }
 7101                                })
 7102                            })
 7103                            .map_err(Arc::new)
 7104                    })
 7105                    .shared();
 7106
 7107                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7108                *fetch_task = Some(new_inlay_hints.clone());
 7109                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7110            }
 7111
 7112            cached_inlay_hints
 7113                .unwrap_or_default()
 7114                .into_iter()
 7115                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7116                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7117                    (
 7118                        chunk.row_range(),
 7119                        cx.spawn(async move |_, _| {
 7120                            hints_fetch.await.map_err(|e| {
 7121                                if e.error_code() != ErrorCode::Internal {
 7122                                    anyhow!(e.error_code())
 7123                                } else {
 7124                                    anyhow!("{e:#}")
 7125                                }
 7126                            })
 7127                        }),
 7128                    )
 7129                }))
 7130                .collect()
 7131        }
 7132    }
 7133
 7134    fn fetch_inlay_hints(
 7135        &mut self,
 7136        for_server: Option<LanguageServerId>,
 7137        buffer: &Entity<Buffer>,
 7138        range: Range<Anchor>,
 7139        cx: &mut Context<Self>,
 7140    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7141        let request = InlayHints {
 7142            range: range.clone(),
 7143        };
 7144        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7145            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7146                return Task::ready(Ok(HashMap::default()));
 7147            }
 7148            let request_timeout = ProjectSettings::get_global(cx)
 7149                .global_lsp_settings
 7150                .get_request_timeout();
 7151            let request_task = upstream_client.request_lsp(
 7152                project_id,
 7153                for_server.map(|id| id.to_proto()),
 7154                request_timeout,
 7155                cx.background_executor().clone(),
 7156                request.to_proto(project_id, buffer.read(cx)),
 7157            );
 7158            let buffer = buffer.clone();
 7159            cx.spawn(async move |weak_lsp_store, cx| {
 7160                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7161                    return Ok(HashMap::default());
 7162                };
 7163                let Some(responses) = request_task.await? else {
 7164                    return Ok(HashMap::default());
 7165                };
 7166
 7167                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7168                    let lsp_store = lsp_store.clone();
 7169                    let buffer = buffer.clone();
 7170                    let cx = cx.clone();
 7171                    let request = request.clone();
 7172                    async move {
 7173                        (
 7174                            LanguageServerId::from_proto(response.server_id),
 7175                            request
 7176                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7177                                .await,
 7178                        )
 7179                    }
 7180                }))
 7181                .await;
 7182
 7183                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7184                let mut has_errors = false;
 7185                let inlay_hints = inlay_hints
 7186                    .into_iter()
 7187                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7188                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7189                        Err(e) => {
 7190                            has_errors = true;
 7191                            log::error!("{e:#}");
 7192                            None
 7193                        }
 7194                    })
 7195                    .map(|(server_id, mut new_hints)| {
 7196                        new_hints.retain(|hint| {
 7197                            hint.position.is_valid(&buffer_snapshot)
 7198                                && range.start.is_valid(&buffer_snapshot)
 7199                                && range.end.is_valid(&buffer_snapshot)
 7200                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7201                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7202                        });
 7203                        (server_id, new_hints)
 7204                    })
 7205                    .collect::<HashMap<_, _>>();
 7206                anyhow::ensure!(
 7207                    !has_errors || !inlay_hints.is_empty(),
 7208                    "Failed to fetch inlay hints"
 7209                );
 7210                Ok(inlay_hints)
 7211            })
 7212        } else {
 7213            let inlay_hints_task = match for_server {
 7214                Some(server_id) => {
 7215                    let server_task = self.request_lsp(
 7216                        buffer.clone(),
 7217                        LanguageServerToQuery::Other(server_id),
 7218                        request,
 7219                        cx,
 7220                    );
 7221                    cx.background_spawn(async move {
 7222                        let mut responses = Vec::new();
 7223                        match server_task.await {
 7224                            Ok(response) => responses.push((server_id, response)),
 7225                            // rust-analyzer likes to error with this when its still loading up
 7226                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7227                            Err(e) => log::error!(
 7228                                "Error handling response for inlay hints request: {e:#}"
 7229                            ),
 7230                        }
 7231                        responses
 7232                    })
 7233                }
 7234                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7235            };
 7236            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7237            cx.background_spawn(async move {
 7238                Ok(inlay_hints_task
 7239                    .await
 7240                    .into_iter()
 7241                    .map(|(server_id, mut new_hints)| {
 7242                        new_hints.retain(|hint| {
 7243                            hint.position.is_valid(&buffer_snapshot)
 7244                                && range.start.is_valid(&buffer_snapshot)
 7245                                && range.end.is_valid(&buffer_snapshot)
 7246                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7247                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7248                        });
 7249                        (server_id, new_hints)
 7250                    })
 7251                    .collect())
 7252            })
 7253        }
 7254    }
 7255
 7256    fn diagnostic_registration_exists(
 7257        &self,
 7258        server_id: LanguageServerId,
 7259        registration_id: &Option<SharedString>,
 7260    ) -> bool {
 7261        let Some(local) = self.as_local() else {
 7262            return false;
 7263        };
 7264        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7265        else {
 7266            return false;
 7267        };
 7268        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7269        registrations.diagnostics.contains_key(&registration_key)
 7270    }
 7271
 7272    pub fn pull_diagnostics_for_buffer(
 7273        &mut self,
 7274        buffer: Entity<Buffer>,
 7275        cx: &mut Context<Self>,
 7276    ) -> Task<anyhow::Result<()>> {
 7277        let diagnostics = self.pull_diagnostics(buffer, cx);
 7278        cx.spawn(async move |lsp_store, cx| {
 7279            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7280                return Ok(());
 7281            };
 7282            lsp_store.update(cx, |lsp_store, cx| {
 7283                if lsp_store.as_local().is_none() {
 7284                    return;
 7285                }
 7286
 7287                let mut unchanged_buffers = HashMap::default();
 7288                let server_diagnostics_updates = diagnostics
 7289                    .into_iter()
 7290                    .filter_map(|diagnostics_set| match diagnostics_set {
 7291                        LspPullDiagnostics::Response {
 7292                            server_id,
 7293                            uri,
 7294                            diagnostics,
 7295                            registration_id,
 7296                        } => Some((server_id, uri, diagnostics, registration_id)),
 7297                        LspPullDiagnostics::Default => None,
 7298                    })
 7299                    .filter(|(server_id, _, _, registration_id)| {
 7300                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7301                    })
 7302                    .fold(
 7303                        HashMap::default(),
 7304                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7305                            let (result_id, diagnostics) = match diagnostics {
 7306                                PulledDiagnostics::Unchanged { result_id } => {
 7307                                    unchanged_buffers
 7308                                        .entry(new_registration_id.clone())
 7309                                        .or_insert_with(HashSet::default)
 7310                                        .insert(uri.clone());
 7311                                    (Some(result_id), Vec::new())
 7312                                }
 7313                                PulledDiagnostics::Changed {
 7314                                    result_id,
 7315                                    diagnostics,
 7316                                } => (result_id, diagnostics),
 7317                            };
 7318                            let disk_based_sources = Cow::Owned(
 7319                                lsp_store
 7320                                    .language_server_adapter_for_id(server_id)
 7321                                    .as_ref()
 7322                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7323                                    .unwrap_or(&[])
 7324                                    .to_vec(),
 7325                            );
 7326                            acc.entry(server_id)
 7327                                .or_insert_with(HashMap::default)
 7328                                .entry(new_registration_id.clone())
 7329                                .or_insert_with(Vec::new)
 7330                                .push(DocumentDiagnosticsUpdate {
 7331                                    server_id,
 7332                                    diagnostics: lsp::PublishDiagnosticsParams {
 7333                                        uri,
 7334                                        diagnostics,
 7335                                        version: None,
 7336                                    },
 7337                                    result_id: result_id.map(SharedString::new),
 7338                                    disk_based_sources,
 7339                                    registration_id: new_registration_id,
 7340                                });
 7341                            acc
 7342                        },
 7343                    );
 7344
 7345                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7346                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7347                        lsp_store
 7348                            .merge_lsp_diagnostics(
 7349                                DiagnosticSourceKind::Pulled,
 7350                                diagnostic_updates,
 7351                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7352                                    DiagnosticSourceKind::Pulled => {
 7353                                        old_diagnostic.registration_id != registration_id
 7354                                            || unchanged_buffers
 7355                                                .get(&old_diagnostic.registration_id)
 7356                                                .is_some_and(|unchanged_buffers| {
 7357                                                    unchanged_buffers.contains(&document_uri)
 7358                                                })
 7359                                    }
 7360                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7361                                        true
 7362                                    }
 7363                                },
 7364                                cx,
 7365                            )
 7366                            .log_err();
 7367                    }
 7368                }
 7369            })
 7370        })
 7371    }
 7372
 7373    pub fn signature_help<T: ToPointUtf16>(
 7374        &mut self,
 7375        buffer: &Entity<Buffer>,
 7376        position: T,
 7377        cx: &mut Context<Self>,
 7378    ) -> Task<Option<Vec<SignatureHelp>>> {
 7379        let position = position.to_point_utf16(buffer.read(cx));
 7380
 7381        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7382            let request = GetSignatureHelp { position };
 7383            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7384                return Task::ready(None);
 7385            }
 7386            let request_timeout = ProjectSettings::get_global(cx)
 7387                .global_lsp_settings
 7388                .get_request_timeout();
 7389            let request_task = client.request_lsp(
 7390                upstream_project_id,
 7391                None,
 7392                request_timeout,
 7393                cx.background_executor().clone(),
 7394                request.to_proto(upstream_project_id, buffer.read(cx)),
 7395            );
 7396            let buffer = buffer.clone();
 7397            cx.spawn(async move |weak_lsp_store, cx| {
 7398                let lsp_store = weak_lsp_store.upgrade()?;
 7399                let signatures = join_all(
 7400                    request_task
 7401                        .await
 7402                        .log_err()
 7403                        .flatten()
 7404                        .map(|response| response.payload)
 7405                        .unwrap_or_default()
 7406                        .into_iter()
 7407                        .map(|response| {
 7408                            let response = GetSignatureHelp { position }.response_from_proto(
 7409                                response.response,
 7410                                lsp_store.clone(),
 7411                                buffer.clone(),
 7412                                cx.clone(),
 7413                            );
 7414                            async move { response.await.log_err().flatten() }
 7415                        }),
 7416                )
 7417                .await
 7418                .into_iter()
 7419                .flatten()
 7420                .collect();
 7421                Some(signatures)
 7422            })
 7423        } else {
 7424            let all_actions_task = self.request_multiple_lsp_locally(
 7425                buffer,
 7426                Some(position),
 7427                GetSignatureHelp { position },
 7428                cx,
 7429            );
 7430            cx.background_spawn(async move {
 7431                Some(
 7432                    all_actions_task
 7433                        .await
 7434                        .into_iter()
 7435                        .flat_map(|(_, actions)| actions)
 7436                        .collect::<Vec<_>>(),
 7437                )
 7438            })
 7439        }
 7440    }
 7441
 7442    pub fn hover(
 7443        &mut self,
 7444        buffer: &Entity<Buffer>,
 7445        position: PointUtf16,
 7446        cx: &mut Context<Self>,
 7447    ) -> Task<Option<Vec<Hover>>> {
 7448        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7449            let request = GetHover { position };
 7450            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7451                return Task::ready(None);
 7452            }
 7453            let request_timeout = ProjectSettings::get_global(cx)
 7454                .global_lsp_settings
 7455                .get_request_timeout();
 7456            let request_task = client.request_lsp(
 7457                upstream_project_id,
 7458                None,
 7459                request_timeout,
 7460                cx.background_executor().clone(),
 7461                request.to_proto(upstream_project_id, buffer.read(cx)),
 7462            );
 7463            let buffer = buffer.clone();
 7464            cx.spawn(async move |weak_lsp_store, cx| {
 7465                let lsp_store = weak_lsp_store.upgrade()?;
 7466                let hovers = join_all(
 7467                    request_task
 7468                        .await
 7469                        .log_err()
 7470                        .flatten()
 7471                        .map(|response| response.payload)
 7472                        .unwrap_or_default()
 7473                        .into_iter()
 7474                        .map(|response| {
 7475                            let response = GetHover { position }.response_from_proto(
 7476                                response.response,
 7477                                lsp_store.clone(),
 7478                                buffer.clone(),
 7479                                cx.clone(),
 7480                            );
 7481                            async move {
 7482                                response
 7483                                    .await
 7484                                    .log_err()
 7485                                    .flatten()
 7486                                    .and_then(remove_empty_hover_blocks)
 7487                            }
 7488                        }),
 7489                )
 7490                .await
 7491                .into_iter()
 7492                .flatten()
 7493                .collect();
 7494                Some(hovers)
 7495            })
 7496        } else {
 7497            let all_actions_task = self.request_multiple_lsp_locally(
 7498                buffer,
 7499                Some(position),
 7500                GetHover { position },
 7501                cx,
 7502            );
 7503            cx.background_spawn(async move {
 7504                Some(
 7505                    all_actions_task
 7506                        .await
 7507                        .into_iter()
 7508                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7509                        .collect::<Vec<Hover>>(),
 7510                )
 7511            })
 7512        }
 7513    }
 7514
 7515    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7516        let language_registry = self.languages.clone();
 7517
 7518        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7519            let request = upstream_client.request(proto::GetProjectSymbols {
 7520                project_id: *project_id,
 7521                query: query.to_string(),
 7522            });
 7523            cx.foreground_executor().spawn(async move {
 7524                let response = request.await?;
 7525                let mut symbols = Vec::new();
 7526                let core_symbols = response
 7527                    .symbols
 7528                    .into_iter()
 7529                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7530                    .collect::<Vec<_>>();
 7531                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7532                    .await;
 7533                Ok(symbols)
 7534            })
 7535        } else if let Some(local) = self.as_local() {
 7536            struct WorkspaceSymbolsResult {
 7537                server_id: LanguageServerId,
 7538                lsp_adapter: Arc<CachedLspAdapter>,
 7539                worktree: WeakEntity<Worktree>,
 7540                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7541            }
 7542
 7543            let mut requests = Vec::new();
 7544            let mut requested_servers = BTreeSet::new();
 7545            let request_timeout = ProjectSettings::get_global(cx)
 7546                .global_lsp_settings
 7547                .get_request_timeout();
 7548
 7549            for (seed, state) in local.language_server_ids.iter() {
 7550                let Some(worktree_handle) = self
 7551                    .worktree_store
 7552                    .read(cx)
 7553                    .worktree_for_id(seed.worktree_id, cx)
 7554                else {
 7555                    continue;
 7556                };
 7557
 7558                let worktree = worktree_handle.read(cx);
 7559                if !worktree.is_visible() {
 7560                    continue;
 7561                }
 7562
 7563                if !requested_servers.insert(state.id) {
 7564                    continue;
 7565                }
 7566
 7567                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7568                    Some(LanguageServerState::Running {
 7569                        adapter, server, ..
 7570                    }) => (adapter.clone(), server),
 7571
 7572                    _ => continue,
 7573                };
 7574
 7575                let supports_workspace_symbol_request =
 7576                    match server.capabilities().workspace_symbol_provider {
 7577                        Some(OneOf::Left(supported)) => supported,
 7578                        Some(OneOf::Right(_)) => true,
 7579                        None => false,
 7580                    };
 7581
 7582                if !supports_workspace_symbol_request {
 7583                    continue;
 7584                }
 7585
 7586                let worktree_handle = worktree_handle.clone();
 7587                let server_id = server.server_id();
 7588                requests.push(
 7589                    server
 7590                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7591                            lsp::WorkspaceSymbolParams {
 7592                                query: query.to_string(),
 7593                                ..Default::default()
 7594                            },
 7595                            request_timeout,
 7596                        )
 7597                        .map(move |response| {
 7598                            let lsp_symbols = response
 7599                                .into_response()
 7600                                .context("workspace symbols request")
 7601                                .log_err()
 7602                                .flatten()
 7603                                .map(|symbol_response| match symbol_response {
 7604                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7605                                        flat_responses
 7606                                            .into_iter()
 7607                                            .map(|lsp_symbol| {
 7608                                                (
 7609                                                    lsp_symbol.name,
 7610                                                    lsp_symbol.kind,
 7611                                                    lsp_symbol.location,
 7612                                                    lsp_symbol.container_name,
 7613                                                )
 7614                                            })
 7615                                            .collect::<Vec<_>>()
 7616                                    }
 7617                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7618                                        nested_responses
 7619                                            .into_iter()
 7620                                            .filter_map(|lsp_symbol| {
 7621                                                let location = match lsp_symbol.location {
 7622                                                    OneOf::Left(location) => location,
 7623                                                    OneOf::Right(_) => {
 7624                                                        log::error!(
 7625                                                            "Unexpected: client capabilities \
 7626                                                            forbid symbol resolutions in \
 7627                                                            workspace.symbol.resolveSupport"
 7628                                                        );
 7629                                                        return None;
 7630                                                    }
 7631                                                };
 7632                                                Some((
 7633                                                    lsp_symbol.name,
 7634                                                    lsp_symbol.kind,
 7635                                                    location,
 7636                                                    lsp_symbol.container_name,
 7637                                                ))
 7638                                            })
 7639                                            .collect::<Vec<_>>()
 7640                                    }
 7641                                })
 7642                                .unwrap_or_default();
 7643
 7644                            WorkspaceSymbolsResult {
 7645                                server_id,
 7646                                lsp_adapter,
 7647                                worktree: worktree_handle.downgrade(),
 7648                                lsp_symbols,
 7649                            }
 7650                        }),
 7651                );
 7652            }
 7653
 7654            cx.spawn(async move |this, cx| {
 7655                let responses = futures::future::join_all(requests).await;
 7656                let this = match this.upgrade() {
 7657                    Some(this) => this,
 7658                    None => return Ok(Vec::new()),
 7659                };
 7660
 7661                let mut symbols = Vec::new();
 7662                for result in responses {
 7663                    let core_symbols = this.update(cx, |this, cx| {
 7664                        result
 7665                            .lsp_symbols
 7666                            .into_iter()
 7667                            .filter_map(
 7668                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7669                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7670                                    let source_worktree = result.worktree.upgrade()?;
 7671                                    let source_worktree_id = source_worktree.read(cx).id();
 7672
 7673                                    let path = if let Some((tree, rel_path)) =
 7674                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7675                                    {
 7676                                        let worktree_id = tree.read(cx).id();
 7677                                        SymbolLocation::InProject(ProjectPath {
 7678                                            worktree_id,
 7679                                            path: rel_path,
 7680                                        })
 7681                                    } else {
 7682                                        SymbolLocation::OutsideProject {
 7683                                            signature: this.symbol_signature(&abs_path),
 7684                                            abs_path: abs_path.into(),
 7685                                        }
 7686                                    };
 7687
 7688                                    Some(CoreSymbol {
 7689                                        source_language_server_id: result.server_id,
 7690                                        language_server_name: result.lsp_adapter.name.clone(),
 7691                                        source_worktree_id,
 7692                                        path,
 7693                                        kind: symbol_kind,
 7694                                        name: collapse_newlines(&symbol_name, ""),
 7695                                        range: range_from_lsp(symbol_location.range),
 7696                                        container_name: container_name
 7697                                            .map(|c| collapse_newlines(&c, "")),
 7698                                    })
 7699                                },
 7700                            )
 7701                            .collect::<Vec<_>>()
 7702                    });
 7703
 7704                    populate_labels_for_symbols(
 7705                        core_symbols,
 7706                        &language_registry,
 7707                        Some(result.lsp_adapter),
 7708                        &mut symbols,
 7709                    )
 7710                    .await;
 7711                }
 7712
 7713                Ok(symbols)
 7714            })
 7715        } else {
 7716            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7717        }
 7718    }
 7719
 7720    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7721        let mut summary = DiagnosticSummary::default();
 7722        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7723            summary.error_count += path_summary.error_count;
 7724            summary.warning_count += path_summary.warning_count;
 7725        }
 7726        summary
 7727    }
 7728
 7729    /// Returns the diagnostic summary for a specific project path.
 7730    pub fn diagnostic_summary_for_path(
 7731        &self,
 7732        project_path: &ProjectPath,
 7733        _: &App,
 7734    ) -> DiagnosticSummary {
 7735        if let Some(summaries) = self
 7736            .diagnostic_summaries
 7737            .get(&project_path.worktree_id)
 7738            .and_then(|map| map.get(&project_path.path))
 7739        {
 7740            let (error_count, warning_count) = summaries.iter().fold(
 7741                (0, 0),
 7742                |(error_count, warning_count), (_language_server_id, summary)| {
 7743                    (
 7744                        error_count + summary.error_count,
 7745                        warning_count + summary.warning_count,
 7746                    )
 7747                },
 7748            );
 7749
 7750            DiagnosticSummary {
 7751                error_count,
 7752                warning_count,
 7753            }
 7754        } else {
 7755            DiagnosticSummary::default()
 7756        }
 7757    }
 7758
 7759    pub fn diagnostic_summaries<'a>(
 7760        &'a self,
 7761        include_ignored: bool,
 7762        cx: &'a App,
 7763    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7764        self.worktree_store
 7765            .read(cx)
 7766            .visible_worktrees(cx)
 7767            .filter_map(|worktree| {
 7768                let worktree = worktree.read(cx);
 7769                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7770            })
 7771            .flat_map(move |(worktree, summaries)| {
 7772                let worktree_id = worktree.id();
 7773                summaries
 7774                    .iter()
 7775                    .filter(move |(path, _)| {
 7776                        include_ignored
 7777                            || worktree
 7778                                .entry_for_path(path.as_ref())
 7779                                .is_some_and(|entry| !entry.is_ignored)
 7780                    })
 7781                    .flat_map(move |(path, summaries)| {
 7782                        summaries.iter().map(move |(server_id, summary)| {
 7783                            (
 7784                                ProjectPath {
 7785                                    worktree_id,
 7786                                    path: path.clone(),
 7787                                },
 7788                                *server_id,
 7789                                *summary,
 7790                            )
 7791                        })
 7792                    })
 7793            })
 7794    }
 7795
 7796    pub fn on_buffer_edited(
 7797        &mut self,
 7798        buffer: Entity<Buffer>,
 7799        cx: &mut Context<Self>,
 7800    ) -> Option<()> {
 7801        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7802            Some(
 7803                self.as_local()?
 7804                    .language_servers_for_buffer(buffer, cx)
 7805                    .map(|i| i.1.clone())
 7806                    .collect(),
 7807            )
 7808        })?;
 7809
 7810        let buffer = buffer.read(cx);
 7811        let file = File::from_dyn(buffer.file())?;
 7812        let abs_path = file.as_local()?.abs_path(cx);
 7813        let uri = lsp::Uri::from_file_path(&abs_path)
 7814            .ok()
 7815            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7816            .log_err()?;
 7817        let next_snapshot = buffer.text_snapshot();
 7818        for language_server in language_servers {
 7819            let language_server = language_server.clone();
 7820
 7821            let buffer_snapshots = self
 7822                .as_local_mut()?
 7823                .buffer_snapshots
 7824                .get_mut(&buffer.remote_id())
 7825                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7826            let previous_snapshot = buffer_snapshots.last()?;
 7827
 7828            let build_incremental_change = || {
 7829                buffer
 7830                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7831                        previous_snapshot.snapshot.version(),
 7832                    )
 7833                    .map(|edit| {
 7834                        let edit_start = edit.new.start.0;
 7835                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7836                        let new_text = next_snapshot
 7837                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7838                            .collect();
 7839                        lsp::TextDocumentContentChangeEvent {
 7840                            range: Some(lsp::Range::new(
 7841                                point_to_lsp(edit_start),
 7842                                point_to_lsp(edit_end),
 7843                            )),
 7844                            range_length: None,
 7845                            text: new_text,
 7846                        }
 7847                    })
 7848                    .collect()
 7849            };
 7850
 7851            let document_sync_kind = language_server
 7852                .capabilities()
 7853                .text_document_sync
 7854                .as_ref()
 7855                .and_then(|sync| match sync {
 7856                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7857                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7858                });
 7859
 7860            let content_changes: Vec<_> = match document_sync_kind {
 7861                Some(lsp::TextDocumentSyncKind::FULL) => {
 7862                    vec![lsp::TextDocumentContentChangeEvent {
 7863                        range: None,
 7864                        range_length: None,
 7865                        text: next_snapshot.text(),
 7866                    }]
 7867                }
 7868                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7869                _ => {
 7870                    #[cfg(any(test, feature = "test-support"))]
 7871                    {
 7872                        build_incremental_change()
 7873                    }
 7874
 7875                    #[cfg(not(any(test, feature = "test-support")))]
 7876                    {
 7877                        continue;
 7878                    }
 7879                }
 7880            };
 7881
 7882            let next_version = previous_snapshot.version + 1;
 7883            buffer_snapshots.push(LspBufferSnapshot {
 7884                version: next_version,
 7885                snapshot: next_snapshot.clone(),
 7886            });
 7887
 7888            language_server
 7889                .notify::<lsp::notification::DidChangeTextDocument>(
 7890                    lsp::DidChangeTextDocumentParams {
 7891                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7892                            uri.clone(),
 7893                            next_version,
 7894                        ),
 7895                        content_changes,
 7896                    },
 7897                )
 7898                .ok();
 7899            self.pull_workspace_diagnostics(language_server.server_id());
 7900        }
 7901
 7902        None
 7903    }
 7904
 7905    pub fn on_buffer_saved(
 7906        &mut self,
 7907        buffer: Entity<Buffer>,
 7908        cx: &mut Context<Self>,
 7909    ) -> Option<()> {
 7910        let file = File::from_dyn(buffer.read(cx).file())?;
 7911        let worktree_id = file.worktree_id(cx);
 7912        let abs_path = file.as_local()?.abs_path(cx);
 7913        let text_document = lsp::TextDocumentIdentifier {
 7914            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7915        };
 7916        let local = self.as_local()?;
 7917
 7918        for server in local.language_servers_for_worktree(worktree_id) {
 7919            if let Some(include_text) = include_text(server.as_ref()) {
 7920                let text = if include_text {
 7921                    Some(buffer.read(cx).text())
 7922                } else {
 7923                    None
 7924                };
 7925                server
 7926                    .notify::<lsp::notification::DidSaveTextDocument>(
 7927                        lsp::DidSaveTextDocumentParams {
 7928                            text_document: text_document.clone(),
 7929                            text,
 7930                        },
 7931                    )
 7932                    .ok();
 7933            }
 7934        }
 7935
 7936        let language_servers = buffer.update(cx, |buffer, cx| {
 7937            local.language_server_ids_for_buffer(buffer, cx)
 7938        });
 7939        for language_server_id in language_servers {
 7940            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7941        }
 7942
 7943        None
 7944    }
 7945
 7946    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7947        maybe!(async move {
 7948            let mut refreshed_servers = HashSet::default();
 7949            let servers = lsp_store
 7950                .update(cx, |lsp_store, cx| {
 7951                    let local = lsp_store.as_local()?;
 7952
 7953                    let servers = local
 7954                        .language_server_ids
 7955                        .iter()
 7956                        .filter_map(|(seed, state)| {
 7957                            let worktree = lsp_store
 7958                                .worktree_store
 7959                                .read(cx)
 7960                                .worktree_for_id(seed.worktree_id, cx);
 7961                            let delegate: Arc<dyn LspAdapterDelegate> =
 7962                                worktree.map(|worktree| {
 7963                                    LocalLspAdapterDelegate::new(
 7964                                        local.languages.clone(),
 7965                                        &local.environment,
 7966                                        cx.weak_entity(),
 7967                                        &worktree,
 7968                                        local.http_client.clone(),
 7969                                        local.fs.clone(),
 7970                                        cx,
 7971                                    )
 7972                                })?;
 7973                            let server_id = state.id;
 7974
 7975                            let states = local.language_servers.get(&server_id)?;
 7976
 7977                            match states {
 7978                                LanguageServerState::Starting { .. } => None,
 7979                                LanguageServerState::Running {
 7980                                    adapter, server, ..
 7981                                } => {
 7982                                    let adapter = adapter.clone();
 7983                                    let server = server.clone();
 7984                                    refreshed_servers.insert(server.name());
 7985                                    let toolchain = seed.toolchain.clone();
 7986                                    Some(cx.spawn(async move |_, cx| {
 7987                                        let settings =
 7988                                            LocalLspStore::workspace_configuration_for_adapter(
 7989                                                adapter.adapter.clone(),
 7990                                                &delegate,
 7991                                                toolchain,
 7992                                                None,
 7993                                                cx,
 7994                                            )
 7995                                            .await
 7996                                            .ok()?;
 7997                                        server
 7998                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7999                                                lsp::DidChangeConfigurationParams { settings },
 8000                                            )
 8001                                            .ok()?;
 8002                                        Some(())
 8003                                    }))
 8004                                }
 8005                            }
 8006                        })
 8007                        .collect::<Vec<_>>();
 8008
 8009                    Some(servers)
 8010                })
 8011                .ok()
 8012                .flatten()?;
 8013
 8014            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8015            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8016            // to stop and unregister its language server wrapper.
 8017            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8018            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8019            let _: Vec<Option<()>> = join_all(servers).await;
 8020
 8021            Some(())
 8022        })
 8023        .await;
 8024    }
 8025
 8026    fn maintain_workspace_config(
 8027        external_refresh_requests: watch::Receiver<()>,
 8028        cx: &mut Context<Self>,
 8029    ) -> Task<Result<()>> {
 8030        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8031        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8032
 8033        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8034            *settings_changed_tx.borrow_mut() = ();
 8035        });
 8036
 8037        let mut joint_future =
 8038            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8039        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8040        // - 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).
 8041        // - 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.
 8042        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8043        // - 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,
 8044        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8045        cx.spawn(async move |this, cx| {
 8046            while let Some(()) = joint_future.next().await {
 8047                this.update(cx, |this, cx| {
 8048                    this.refresh_server_tree(cx);
 8049                })
 8050                .ok();
 8051
 8052                Self::refresh_workspace_configurations(&this, cx).await;
 8053            }
 8054
 8055            drop(settings_observation);
 8056            anyhow::Ok(())
 8057        })
 8058    }
 8059
 8060    pub fn running_language_servers_for_local_buffer<'a>(
 8061        &'a self,
 8062        buffer: &Buffer,
 8063        cx: &mut App,
 8064    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8065        let local = self.as_local();
 8066        let language_server_ids = local
 8067            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8068            .unwrap_or_default();
 8069
 8070        language_server_ids
 8071            .into_iter()
 8072            .filter_map(
 8073                move |server_id| match local?.language_servers.get(&server_id)? {
 8074                    LanguageServerState::Running {
 8075                        adapter, server, ..
 8076                    } => Some((adapter, server)),
 8077                    _ => None,
 8078                },
 8079            )
 8080    }
 8081
 8082    pub fn language_servers_for_local_buffer(
 8083        &self,
 8084        buffer: &Buffer,
 8085        cx: &mut App,
 8086    ) -> Vec<LanguageServerId> {
 8087        let local = self.as_local();
 8088        local
 8089            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8090            .unwrap_or_default()
 8091    }
 8092
 8093    pub fn language_server_for_local_buffer<'a>(
 8094        &'a self,
 8095        buffer: &'a Buffer,
 8096        server_id: LanguageServerId,
 8097        cx: &'a mut App,
 8098    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8099        self.as_local()?
 8100            .language_servers_for_buffer(buffer, cx)
 8101            .find(|(_, s)| s.server_id() == server_id)
 8102    }
 8103
 8104    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8105        self.diagnostic_summaries.remove(&id_to_remove);
 8106        if let Some(local) = self.as_local_mut() {
 8107            let to_remove = local.remove_worktree(id_to_remove, cx);
 8108            for server in to_remove {
 8109                self.language_server_statuses.remove(&server);
 8110            }
 8111        }
 8112    }
 8113
 8114    pub fn shared(
 8115        &mut self,
 8116        project_id: u64,
 8117        downstream_client: AnyProtoClient,
 8118        _: &mut Context<Self>,
 8119    ) {
 8120        self.downstream_client = Some((downstream_client.clone(), project_id));
 8121
 8122        for (server_id, status) in &self.language_server_statuses {
 8123            if let Some(server) = self.language_server_for_id(*server_id) {
 8124                downstream_client
 8125                    .send(proto::StartLanguageServer {
 8126                        project_id,
 8127                        server: Some(proto::LanguageServer {
 8128                            id: server_id.to_proto(),
 8129                            name: status.name.to_string(),
 8130                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8131                        }),
 8132                        capabilities: serde_json::to_string(&server.capabilities())
 8133                            .expect("serializing server LSP capabilities"),
 8134                    })
 8135                    .log_err();
 8136            }
 8137        }
 8138    }
 8139
 8140    pub fn disconnected_from_host(&mut self) {
 8141        self.downstream_client.take();
 8142    }
 8143
 8144    pub fn disconnected_from_ssh_remote(&mut self) {
 8145        if let LspStoreMode::Remote(RemoteLspStore {
 8146            upstream_client, ..
 8147        }) = &mut self.mode
 8148        {
 8149            upstream_client.take();
 8150        }
 8151    }
 8152
 8153    pub(crate) fn set_language_server_statuses_from_proto(
 8154        &mut self,
 8155        project: WeakEntity<Project>,
 8156        language_servers: Vec<proto::LanguageServer>,
 8157        server_capabilities: Vec<String>,
 8158        cx: &mut Context<Self>,
 8159    ) {
 8160        let lsp_logs = cx
 8161            .try_global::<GlobalLogStore>()
 8162            .map(|lsp_store| lsp_store.0.clone());
 8163
 8164        self.language_server_statuses = language_servers
 8165            .into_iter()
 8166            .zip(server_capabilities)
 8167            .map(|(server, server_capabilities)| {
 8168                let server_id = LanguageServerId(server.id as usize);
 8169                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8170                    self.lsp_server_capabilities
 8171                        .insert(server_id, server_capabilities);
 8172                }
 8173
 8174                let name = LanguageServerName::from_proto(server.name);
 8175                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8176
 8177                if let Some(lsp_logs) = &lsp_logs {
 8178                    lsp_logs.update(cx, |lsp_logs, cx| {
 8179                        lsp_logs.add_language_server(
 8180                            // Only remote clients get their language servers set from proto
 8181                            LanguageServerKind::Remote {
 8182                                project: project.clone(),
 8183                            },
 8184                            server_id,
 8185                            Some(name.clone()),
 8186                            worktree,
 8187                            None,
 8188                            cx,
 8189                        );
 8190                    });
 8191                }
 8192
 8193                (
 8194                    server_id,
 8195                    LanguageServerStatus {
 8196                        name,
 8197                        server_version: None,
 8198                        pending_work: Default::default(),
 8199                        has_pending_diagnostic_updates: false,
 8200                        progress_tokens: Default::default(),
 8201                        worktree,
 8202                        binary: None,
 8203                        configuration: None,
 8204                        workspace_folders: BTreeSet::new(),
 8205                        process_id: None,
 8206                    },
 8207                )
 8208            })
 8209            .collect();
 8210    }
 8211
 8212    #[cfg(feature = "test-support")]
 8213    pub fn update_diagnostic_entries(
 8214        &mut self,
 8215        server_id: LanguageServerId,
 8216        abs_path: PathBuf,
 8217        result_id: Option<SharedString>,
 8218        version: Option<i32>,
 8219        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8220        cx: &mut Context<Self>,
 8221    ) -> anyhow::Result<()> {
 8222        self.merge_diagnostic_entries(
 8223            vec![DocumentDiagnosticsUpdate {
 8224                diagnostics: DocumentDiagnostics {
 8225                    diagnostics,
 8226                    document_abs_path: abs_path,
 8227                    version,
 8228                },
 8229                result_id,
 8230                server_id,
 8231                disk_based_sources: Cow::Borrowed(&[]),
 8232                registration_id: None,
 8233            }],
 8234            |_, _, _| false,
 8235            cx,
 8236        )?;
 8237        Ok(())
 8238    }
 8239
 8240    pub fn merge_diagnostic_entries<'a>(
 8241        &mut self,
 8242        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8243        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8244        cx: &mut Context<Self>,
 8245    ) -> anyhow::Result<()> {
 8246        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8247        let mut updated_diagnostics_paths = HashMap::default();
 8248        for mut update in diagnostic_updates {
 8249            let abs_path = &update.diagnostics.document_abs_path;
 8250            let server_id = update.server_id;
 8251            let Some((worktree, relative_path)) =
 8252                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8253            else {
 8254                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8255                return Ok(());
 8256            };
 8257
 8258            let worktree_id = worktree.read(cx).id();
 8259            let project_path = ProjectPath {
 8260                worktree_id,
 8261                path: relative_path,
 8262            };
 8263
 8264            let document_uri = lsp::Uri::from_file_path(abs_path)
 8265                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8266            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8267                let snapshot = buffer_handle.read(cx).snapshot();
 8268                let buffer = buffer_handle.read(cx);
 8269                let reused_diagnostics = buffer
 8270                    .buffer_diagnostics(Some(server_id))
 8271                    .iter()
 8272                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8273                    .map(|v| {
 8274                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8275                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8276                        DiagnosticEntry {
 8277                            range: start..end,
 8278                            diagnostic: v.diagnostic.clone(),
 8279                        }
 8280                    })
 8281                    .collect::<Vec<_>>();
 8282
 8283                self.as_local_mut()
 8284                    .context("cannot merge diagnostics on a remote LspStore")?
 8285                    .update_buffer_diagnostics(
 8286                        &buffer_handle,
 8287                        server_id,
 8288                        Some(update.registration_id),
 8289                        update.result_id,
 8290                        update.diagnostics.version,
 8291                        update.diagnostics.diagnostics.clone(),
 8292                        reused_diagnostics.clone(),
 8293                        cx,
 8294                    )?;
 8295
 8296                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8297            } else if let Some(local) = self.as_local() {
 8298                let reused_diagnostics = local
 8299                    .diagnostics
 8300                    .get(&worktree_id)
 8301                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8302                    .and_then(|diagnostics_by_server_id| {
 8303                        diagnostics_by_server_id
 8304                            .binary_search_by_key(&server_id, |e| e.0)
 8305                            .ok()
 8306                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8307                    })
 8308                    .into_iter()
 8309                    .flatten()
 8310                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8311
 8312                update
 8313                    .diagnostics
 8314                    .diagnostics
 8315                    .extend(reused_diagnostics.cloned());
 8316            }
 8317
 8318            let updated = worktree.update(cx, |worktree, cx| {
 8319                self.update_worktree_diagnostics(
 8320                    worktree.id(),
 8321                    server_id,
 8322                    project_path.path.clone(),
 8323                    update.diagnostics.diagnostics,
 8324                    cx,
 8325                )
 8326            })?;
 8327            match updated {
 8328                ControlFlow::Continue(new_summary) => {
 8329                    if let Some((project_id, new_summary)) = new_summary {
 8330                        match &mut diagnostics_summary {
 8331                            Some(diagnostics_summary) => {
 8332                                diagnostics_summary
 8333                                    .more_summaries
 8334                                    .push(proto::DiagnosticSummary {
 8335                                        path: project_path.path.as_ref().to_proto(),
 8336                                        language_server_id: server_id.0 as u64,
 8337                                        error_count: new_summary.error_count,
 8338                                        warning_count: new_summary.warning_count,
 8339                                    })
 8340                            }
 8341                            None => {
 8342                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8343                                    project_id,
 8344                                    worktree_id: worktree_id.to_proto(),
 8345                                    summary: Some(proto::DiagnosticSummary {
 8346                                        path: project_path.path.as_ref().to_proto(),
 8347                                        language_server_id: server_id.0 as u64,
 8348                                        error_count: new_summary.error_count,
 8349                                        warning_count: new_summary.warning_count,
 8350                                    }),
 8351                                    more_summaries: Vec::new(),
 8352                                })
 8353                            }
 8354                        }
 8355                    }
 8356                    updated_diagnostics_paths
 8357                        .entry(server_id)
 8358                        .or_insert_with(Vec::new)
 8359                        .push(project_path);
 8360                }
 8361                ControlFlow::Break(()) => {}
 8362            }
 8363        }
 8364
 8365        if let Some((diagnostics_summary, (downstream_client, _))) =
 8366            diagnostics_summary.zip(self.downstream_client.as_ref())
 8367        {
 8368            downstream_client.send(diagnostics_summary).log_err();
 8369        }
 8370        for (server_id, paths) in updated_diagnostics_paths {
 8371            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8372        }
 8373        Ok(())
 8374    }
 8375
 8376    fn update_worktree_diagnostics(
 8377        &mut self,
 8378        worktree_id: WorktreeId,
 8379        server_id: LanguageServerId,
 8380        path_in_worktree: Arc<RelPath>,
 8381        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8382        _: &mut Context<Worktree>,
 8383    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8384        let local = match &mut self.mode {
 8385            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8386            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8387        };
 8388
 8389        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8390        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8391        let summaries_by_server_id = summaries_for_tree
 8392            .entry(path_in_worktree.clone())
 8393            .or_default();
 8394
 8395        let old_summary = summaries_by_server_id
 8396            .remove(&server_id)
 8397            .unwrap_or_default();
 8398
 8399        let new_summary = DiagnosticSummary::new(&diagnostics);
 8400        if diagnostics.is_empty() {
 8401            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8402            {
 8403                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8404                    diagnostics_by_server_id.remove(ix);
 8405                }
 8406                if diagnostics_by_server_id.is_empty() {
 8407                    diagnostics_for_tree.remove(&path_in_worktree);
 8408                }
 8409            }
 8410        } else {
 8411            summaries_by_server_id.insert(server_id, new_summary);
 8412            let diagnostics_by_server_id = diagnostics_for_tree
 8413                .entry(path_in_worktree.clone())
 8414                .or_default();
 8415            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8416                Ok(ix) => {
 8417                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8418                }
 8419                Err(ix) => {
 8420                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8421                }
 8422            }
 8423        }
 8424
 8425        if !old_summary.is_empty() || !new_summary.is_empty() {
 8426            if let Some((_, project_id)) = &self.downstream_client {
 8427                Ok(ControlFlow::Continue(Some((
 8428                    *project_id,
 8429                    proto::DiagnosticSummary {
 8430                        path: path_in_worktree.to_proto(),
 8431                        language_server_id: server_id.0 as u64,
 8432                        error_count: new_summary.error_count as u32,
 8433                        warning_count: new_summary.warning_count as u32,
 8434                    },
 8435                ))))
 8436            } else {
 8437                Ok(ControlFlow::Continue(None))
 8438            }
 8439        } else {
 8440            Ok(ControlFlow::Break(()))
 8441        }
 8442    }
 8443
 8444    pub fn open_buffer_for_symbol(
 8445        &mut self,
 8446        symbol: &Symbol,
 8447        cx: &mut Context<Self>,
 8448    ) -> Task<Result<Entity<Buffer>>> {
 8449        if let Some((client, project_id)) = self.upstream_client() {
 8450            let request = client.request(proto::OpenBufferForSymbol {
 8451                project_id,
 8452                symbol: Some(Self::serialize_symbol(symbol)),
 8453            });
 8454            cx.spawn(async move |this, cx| {
 8455                let response = request.await?;
 8456                let buffer_id = BufferId::new(response.buffer_id)?;
 8457                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8458                    .await
 8459            })
 8460        } else if let Some(local) = self.as_local() {
 8461            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8462                seed.worktree_id == symbol.source_worktree_id
 8463                    && state.id == symbol.source_language_server_id
 8464                    && symbol.language_server_name == seed.name
 8465            });
 8466            if !is_valid {
 8467                return Task::ready(Err(anyhow!(
 8468                    "language server for worktree and language not found"
 8469                )));
 8470            };
 8471
 8472            let symbol_abs_path = match &symbol.path {
 8473                SymbolLocation::InProject(project_path) => self
 8474                    .worktree_store
 8475                    .read(cx)
 8476                    .absolutize(&project_path, cx)
 8477                    .context("no such worktree"),
 8478                SymbolLocation::OutsideProject {
 8479                    abs_path,
 8480                    signature: _,
 8481                } => Ok(abs_path.to_path_buf()),
 8482            };
 8483            let symbol_abs_path = match symbol_abs_path {
 8484                Ok(abs_path) => abs_path,
 8485                Err(err) => return Task::ready(Err(err)),
 8486            };
 8487            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8488                uri
 8489            } else {
 8490                return Task::ready(Err(anyhow!("invalid symbol path")));
 8491            };
 8492
 8493            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8494        } else {
 8495            Task::ready(Err(anyhow!("no upstream client or local store")))
 8496        }
 8497    }
 8498
 8499    pub(crate) fn open_local_buffer_via_lsp(
 8500        &mut self,
 8501        abs_path: lsp::Uri,
 8502        language_server_id: LanguageServerId,
 8503        cx: &mut Context<Self>,
 8504    ) -> Task<Result<Entity<Buffer>>> {
 8505        let path_style = self.worktree_store.read(cx).path_style();
 8506        cx.spawn(async move |lsp_store, cx| {
 8507            // Escape percent-encoded string.
 8508            let current_scheme = abs_path.scheme().to_owned();
 8509            // Uri is immutable, so we can't modify the scheme
 8510
 8511            let abs_path = abs_path
 8512                .to_file_path_ext(path_style)
 8513                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8514            let p = abs_path.clone();
 8515            let yarn_worktree = lsp_store
 8516                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8517                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8518                        cx.spawn(async move |this, cx| {
 8519                            let t = this
 8520                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8521                                .ok()?;
 8522                            t.await
 8523                        })
 8524                    }),
 8525                    None => Task::ready(None),
 8526                })?
 8527                .await;
 8528            let (worktree_root_target, known_relative_path) =
 8529                if let Some((zip_root, relative_path)) = yarn_worktree {
 8530                    (zip_root, Some(relative_path))
 8531                } else {
 8532                    (Arc::<Path>::from(abs_path.as_path()), None)
 8533                };
 8534            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8535                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8536                    worktree_store.find_worktree(&worktree_root_target, cx)
 8537                })
 8538            })?;
 8539            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8540                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8541                (result.0, relative_path, None)
 8542            } else {
 8543                let worktree = lsp_store
 8544                    .update(cx, |lsp_store, cx| {
 8545                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8546                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8547                        })
 8548                    })?
 8549                    .await?;
 8550                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8551                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8552                    lsp_store
 8553                        .update(cx, |lsp_store, cx| {
 8554                            if let Some(local) = lsp_store.as_local_mut() {
 8555                                local.register_language_server_for_invisible_worktree(
 8556                                    &worktree,
 8557                                    language_server_id,
 8558                                    cx,
 8559                                )
 8560                            }
 8561                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8562                                Some(status) => status.worktree,
 8563                                None => None,
 8564                            }
 8565                        })
 8566                        .ok()
 8567                        .flatten()
 8568                        .zip(Some(worktree_root.clone()))
 8569                } else {
 8570                    None
 8571                };
 8572                let relative_path = if let Some(known_path) = known_relative_path {
 8573                    known_path
 8574                } else {
 8575                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8576                        .into_arc()
 8577                };
 8578                (worktree, relative_path, source_ws)
 8579            };
 8580            let project_path = ProjectPath {
 8581                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8582                path: relative_path,
 8583            };
 8584            let buffer = lsp_store
 8585                .update(cx, |lsp_store, cx| {
 8586                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8587                        buffer_store.open_buffer(project_path, cx)
 8588                    })
 8589                })?
 8590                .await?;
 8591            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8592            if let Some((source_ws, worktree_root)) = source_ws {
 8593                buffer.update(cx, |buffer, cx| {
 8594                    let settings = WorktreeSettings::get(
 8595                        Some(
 8596                            (&ProjectPath {
 8597                                worktree_id: source_ws,
 8598                                path: Arc::from(RelPath::empty()),
 8599                            })
 8600                                .into(),
 8601                        ),
 8602                        cx,
 8603                    );
 8604                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8605                    if is_read_only {
 8606                        buffer.set_capability(Capability::ReadOnly, cx);
 8607                    }
 8608                });
 8609            }
 8610            Ok(buffer)
 8611        })
 8612    }
 8613
 8614    fn local_lsp_servers_for_buffer(
 8615        &self,
 8616        buffer: &Entity<Buffer>,
 8617        cx: &mut Context<Self>,
 8618    ) -> Vec<LanguageServerId> {
 8619        let Some(local) = self.as_local() else {
 8620            return Vec::new();
 8621        };
 8622
 8623        let snapshot = buffer.read(cx).snapshot();
 8624
 8625        buffer.update(cx, |buffer, cx| {
 8626            local
 8627                .language_servers_for_buffer(buffer, cx)
 8628                .map(|(_, server)| server.server_id())
 8629                .filter(|server_id| {
 8630                    self.as_local().is_none_or(|local| {
 8631                        local
 8632                            .buffers_opened_in_servers
 8633                            .get(&snapshot.remote_id())
 8634                            .is_some_and(|servers| servers.contains(server_id))
 8635                    })
 8636                })
 8637                .collect()
 8638        })
 8639    }
 8640
 8641    fn request_multiple_lsp_locally<P, R>(
 8642        &mut self,
 8643        buffer: &Entity<Buffer>,
 8644        position: Option<P>,
 8645        request: R,
 8646        cx: &mut Context<Self>,
 8647    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8648    where
 8649        P: ToOffset,
 8650        R: LspCommand + Clone,
 8651        <R::LspRequest as lsp::request::Request>::Result: Send,
 8652        <R::LspRequest as lsp::request::Request>::Params: Send,
 8653    {
 8654        let Some(local) = self.as_local() else {
 8655            return Task::ready(Vec::new());
 8656        };
 8657
 8658        let snapshot = buffer.read(cx).snapshot();
 8659        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8660
 8661        let server_ids = buffer.update(cx, |buffer, cx| {
 8662            local
 8663                .language_servers_for_buffer(buffer, cx)
 8664                .filter(|(adapter, _)| {
 8665                    scope
 8666                        .as_ref()
 8667                        .map(|scope| scope.language_allowed(&adapter.name))
 8668                        .unwrap_or(true)
 8669                })
 8670                .map(|(_, server)| server.server_id())
 8671                .filter(|server_id| {
 8672                    self.as_local().is_none_or(|local| {
 8673                        local
 8674                            .buffers_opened_in_servers
 8675                            .get(&snapshot.remote_id())
 8676                            .is_some_and(|servers| servers.contains(server_id))
 8677                    })
 8678                })
 8679                .collect::<Vec<_>>()
 8680        });
 8681
 8682        let mut response_results = server_ids
 8683            .into_iter()
 8684            .map(|server_id| {
 8685                let task = self.request_lsp(
 8686                    buffer.clone(),
 8687                    LanguageServerToQuery::Other(server_id),
 8688                    request.clone(),
 8689                    cx,
 8690                );
 8691                async move { (server_id, task.await) }
 8692            })
 8693            .collect::<FuturesUnordered<_>>();
 8694
 8695        cx.background_spawn(async move {
 8696            let mut responses = Vec::with_capacity(response_results.len());
 8697            while let Some((server_id, response_result)) = response_results.next().await {
 8698                match response_result {
 8699                    Ok(response) => responses.push((server_id, response)),
 8700                    // rust-analyzer likes to error with this when its still loading up
 8701                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8702                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8703                }
 8704            }
 8705            responses
 8706        })
 8707    }
 8708
 8709    async fn handle_lsp_get_completions(
 8710        this: Entity<Self>,
 8711        envelope: TypedEnvelope<proto::GetCompletions>,
 8712        mut cx: AsyncApp,
 8713    ) -> Result<proto::GetCompletionsResponse> {
 8714        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8715
 8716        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8717        let buffer_handle = this.update(&mut cx, |this, cx| {
 8718            this.buffer_store.read(cx).get_existing(buffer_id)
 8719        })?;
 8720        let request = GetCompletions::from_proto(
 8721            envelope.payload,
 8722            this.clone(),
 8723            buffer_handle.clone(),
 8724            cx.clone(),
 8725        )
 8726        .await?;
 8727
 8728        let server_to_query = match request.server_id {
 8729            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8730            None => LanguageServerToQuery::FirstCapable,
 8731        };
 8732
 8733        let response = this
 8734            .update(&mut cx, |this, cx| {
 8735                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8736            })
 8737            .await?;
 8738        this.update(&mut cx, |this, cx| {
 8739            Ok(GetCompletions::response_to_proto(
 8740                response,
 8741                this,
 8742                sender_id,
 8743                &buffer_handle.read(cx).version(),
 8744                cx,
 8745            ))
 8746        })
 8747    }
 8748
 8749    async fn handle_lsp_command<T: LspCommand>(
 8750        this: Entity<Self>,
 8751        envelope: TypedEnvelope<T::ProtoRequest>,
 8752        mut cx: AsyncApp,
 8753    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8754    where
 8755        <T::LspRequest as lsp::request::Request>::Params: Send,
 8756        <T::LspRequest as lsp::request::Request>::Result: Send,
 8757    {
 8758        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8759        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8760        let buffer_handle = this.update(&mut cx, |this, cx| {
 8761            this.buffer_store.read(cx).get_existing(buffer_id)
 8762        })?;
 8763        let request = T::from_proto(
 8764            envelope.payload,
 8765            this.clone(),
 8766            buffer_handle.clone(),
 8767            cx.clone(),
 8768        )
 8769        .await?;
 8770        let response = this
 8771            .update(&mut cx, |this, cx| {
 8772                this.request_lsp(
 8773                    buffer_handle.clone(),
 8774                    LanguageServerToQuery::FirstCapable,
 8775                    request,
 8776                    cx,
 8777                )
 8778            })
 8779            .await?;
 8780        this.update(&mut cx, |this, cx| {
 8781            Ok(T::response_to_proto(
 8782                response,
 8783                this,
 8784                sender_id,
 8785                &buffer_handle.read(cx).version(),
 8786                cx,
 8787            ))
 8788        })
 8789    }
 8790
 8791    async fn handle_lsp_query(
 8792        lsp_store: Entity<Self>,
 8793        envelope: TypedEnvelope<proto::LspQuery>,
 8794        mut cx: AsyncApp,
 8795    ) -> Result<proto::Ack> {
 8796        use proto::lsp_query::Request;
 8797        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8798        let lsp_query = envelope.payload;
 8799        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8800        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8801        match lsp_query.request.context("invalid LSP query request")? {
 8802            Request::GetReferences(get_references) => {
 8803                let position = get_references.position.clone().and_then(deserialize_anchor);
 8804                Self::query_lsp_locally::<GetReferences>(
 8805                    lsp_store,
 8806                    server_id,
 8807                    sender_id,
 8808                    lsp_request_id,
 8809                    get_references,
 8810                    position,
 8811                    &mut cx,
 8812                )
 8813                .await?;
 8814            }
 8815            Request::GetDocumentColor(get_document_color) => {
 8816                Self::query_lsp_locally::<GetDocumentColor>(
 8817                    lsp_store,
 8818                    server_id,
 8819                    sender_id,
 8820                    lsp_request_id,
 8821                    get_document_color,
 8822                    None,
 8823                    &mut cx,
 8824                )
 8825                .await?;
 8826            }
 8827            Request::GetFoldingRanges(get_folding_ranges) => {
 8828                Self::query_lsp_locally::<GetFoldingRanges>(
 8829                    lsp_store,
 8830                    server_id,
 8831                    sender_id,
 8832                    lsp_request_id,
 8833                    get_folding_ranges,
 8834                    None,
 8835                    &mut cx,
 8836                )
 8837                .await?;
 8838            }
 8839            Request::GetDocumentSymbols(get_document_symbols) => {
 8840                Self::query_lsp_locally::<GetDocumentSymbols>(
 8841                    lsp_store,
 8842                    server_id,
 8843                    sender_id,
 8844                    lsp_request_id,
 8845                    get_document_symbols,
 8846                    None,
 8847                    &mut cx,
 8848                )
 8849                .await?;
 8850            }
 8851            Request::GetHover(get_hover) => {
 8852                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8853                Self::query_lsp_locally::<GetHover>(
 8854                    lsp_store,
 8855                    server_id,
 8856                    sender_id,
 8857                    lsp_request_id,
 8858                    get_hover,
 8859                    position,
 8860                    &mut cx,
 8861                )
 8862                .await?;
 8863            }
 8864            Request::GetCodeActions(get_code_actions) => {
 8865                Self::query_lsp_locally::<GetCodeActions>(
 8866                    lsp_store,
 8867                    server_id,
 8868                    sender_id,
 8869                    lsp_request_id,
 8870                    get_code_actions,
 8871                    None,
 8872                    &mut cx,
 8873                )
 8874                .await?;
 8875            }
 8876            Request::GetSignatureHelp(get_signature_help) => {
 8877                let position = get_signature_help
 8878                    .position
 8879                    .clone()
 8880                    .and_then(deserialize_anchor);
 8881                Self::query_lsp_locally::<GetSignatureHelp>(
 8882                    lsp_store,
 8883                    server_id,
 8884                    sender_id,
 8885                    lsp_request_id,
 8886                    get_signature_help,
 8887                    position,
 8888                    &mut cx,
 8889                )
 8890                .await?;
 8891            }
 8892            Request::GetCodeLens(get_code_lens) => {
 8893                Self::query_lsp_locally::<GetCodeLens>(
 8894                    lsp_store,
 8895                    server_id,
 8896                    sender_id,
 8897                    lsp_request_id,
 8898                    get_code_lens,
 8899                    None,
 8900                    &mut cx,
 8901                )
 8902                .await?;
 8903            }
 8904            Request::GetDefinition(get_definition) => {
 8905                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8906                Self::query_lsp_locally::<GetDefinitions>(
 8907                    lsp_store,
 8908                    server_id,
 8909                    sender_id,
 8910                    lsp_request_id,
 8911                    get_definition,
 8912                    position,
 8913                    &mut cx,
 8914                )
 8915                .await?;
 8916            }
 8917            Request::GetDeclaration(get_declaration) => {
 8918                let position = get_declaration
 8919                    .position
 8920                    .clone()
 8921                    .and_then(deserialize_anchor);
 8922                Self::query_lsp_locally::<GetDeclarations>(
 8923                    lsp_store,
 8924                    server_id,
 8925                    sender_id,
 8926                    lsp_request_id,
 8927                    get_declaration,
 8928                    position,
 8929                    &mut cx,
 8930                )
 8931                .await?;
 8932            }
 8933            Request::GetTypeDefinition(get_type_definition) => {
 8934                let position = get_type_definition
 8935                    .position
 8936                    .clone()
 8937                    .and_then(deserialize_anchor);
 8938                Self::query_lsp_locally::<GetTypeDefinitions>(
 8939                    lsp_store,
 8940                    server_id,
 8941                    sender_id,
 8942                    lsp_request_id,
 8943                    get_type_definition,
 8944                    position,
 8945                    &mut cx,
 8946                )
 8947                .await?;
 8948            }
 8949            Request::GetImplementation(get_implementation) => {
 8950                let position = get_implementation
 8951                    .position
 8952                    .clone()
 8953                    .and_then(deserialize_anchor);
 8954                Self::query_lsp_locally::<GetImplementations>(
 8955                    lsp_store,
 8956                    server_id,
 8957                    sender_id,
 8958                    lsp_request_id,
 8959                    get_implementation,
 8960                    position,
 8961                    &mut cx,
 8962                )
 8963                .await?;
 8964            }
 8965            Request::InlayHints(inlay_hints) => {
 8966                let query_start = inlay_hints
 8967                    .start
 8968                    .clone()
 8969                    .and_then(deserialize_anchor)
 8970                    .context("invalid inlay hints range start")?;
 8971                let query_end = inlay_hints
 8972                    .end
 8973                    .clone()
 8974                    .and_then(deserialize_anchor)
 8975                    .context("invalid inlay hints range end")?;
 8976                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 8977                    &lsp_store,
 8978                    server_id,
 8979                    lsp_request_id,
 8980                    &inlay_hints,
 8981                    query_start..query_end,
 8982                    &mut cx,
 8983                )
 8984                .await
 8985                .context("preparing inlay hints request")?;
 8986                Self::query_lsp_locally::<InlayHints>(
 8987                    lsp_store,
 8988                    server_id,
 8989                    sender_id,
 8990                    lsp_request_id,
 8991                    inlay_hints,
 8992                    None,
 8993                    &mut cx,
 8994                )
 8995                .await
 8996                .context("querying for inlay hints")?
 8997            }
 8998            //////////////////////////////
 8999            // Below are LSP queries that need to fetch more data,
 9000            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 9001            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9002                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 9003                    &lsp_store,
 9004                    &get_document_diagnostics,
 9005                    &mut cx,
 9006                )
 9007                .await?;
 9008                lsp_store.update(&mut cx, |lsp_store, cx| {
 9009                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9010                    let key = LspKey {
 9011                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9012                        server_queried: server_id,
 9013                    };
 9014                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9015                    ) {
 9016                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9017                            lsp_requests.clear();
 9018                        };
 9019                    }
 9020
 9021                    lsp_data.lsp_requests.entry(key).or_default().insert(
 9022                        lsp_request_id,
 9023                        cx.spawn(async move |lsp_store, cx| {
 9024                            let diagnostics_pull = lsp_store
 9025                                .update(cx, |lsp_store, cx| {
 9026                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9027                                })
 9028                                .ok();
 9029                            if let Some(diagnostics_pull) = diagnostics_pull {
 9030                                match diagnostics_pull.await {
 9031                                    Ok(()) => {}
 9032                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9033                                };
 9034                            }
 9035                        }),
 9036                    );
 9037                });
 9038            }
 9039            Request::SemanticTokens(semantic_tokens) => {
 9040                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 9041                    &lsp_store,
 9042                    &semantic_tokens,
 9043                    &mut cx,
 9044                )
 9045                .await?;
 9046                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9047                lsp_store.update(&mut cx, |lsp_store, cx| {
 9048                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9049                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9050                        let key = LspKey {
 9051                            request_type: TypeId::of::<SemanticTokensFull>(),
 9052                            server_queried: server_id,
 9053                        };
 9054                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9055                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9056                                lsp_requests.clear();
 9057                            };
 9058                        }
 9059
 9060                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9061                            lsp_request_id,
 9062                            cx.spawn(async move |lsp_store, cx| {
 9063                                let tokens_fetch = lsp_store
 9064                                    .update(cx, |lsp_store, cx| {
 9065                                        lsp_store
 9066                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9067                                    })
 9068                                    .ok();
 9069                                if let Some(tokens_fetch) = tokens_fetch {
 9070                                    let new_tokens = tokens_fetch.await;
 9071                                    if let Some(new_tokens) = new_tokens {
 9072                                        lsp_store
 9073                                            .update(cx, |lsp_store, cx| {
 9074                                                let response = new_tokens
 9075                                                    .into_iter()
 9076                                                    .map(|(server_id, response)| {
 9077                                                        (
 9078                                                            server_id.to_proto(),
 9079                                                            SemanticTokensFull::response_to_proto(
 9080                                                                response,
 9081                                                                lsp_store,
 9082                                                                sender_id,
 9083                                                                &buffer_version,
 9084                                                                cx,
 9085                                                            ),
 9086                                                        )
 9087                                                    })
 9088                                                    .collect::<HashMap<_, _>>();
 9089                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9090                                                    project_id,
 9091                                                    lsp_request_id,
 9092                                                    response,
 9093                                                ) {
 9094                                                    Ok(()) => {}
 9095                                                    Err(e) => {
 9096                                                        log::error!(
 9097                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9098                                                        )
 9099                                                    }
 9100                                                }
 9101                                            })
 9102                                            .ok();
 9103                                    }
 9104                                }
 9105                            }),
 9106                        );
 9107                    }
 9108                });
 9109            }
 9110        }
 9111        Ok(proto::Ack {})
 9112    }
 9113
 9114    async fn handle_lsp_query_response(
 9115        lsp_store: Entity<Self>,
 9116        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9117        cx: AsyncApp,
 9118    ) -> Result<()> {
 9119        lsp_store.read_with(&cx, |lsp_store, _| {
 9120            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9121                upstream_client.handle_lsp_response(envelope.clone());
 9122            }
 9123        });
 9124        Ok(())
 9125    }
 9126
 9127    async fn handle_apply_code_action(
 9128        this: Entity<Self>,
 9129        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9130        mut cx: AsyncApp,
 9131    ) -> Result<proto::ApplyCodeActionResponse> {
 9132        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9133        let action =
 9134            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9135        let apply_code_action = this.update(&mut cx, |this, cx| {
 9136            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9137            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9138            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9139        })?;
 9140
 9141        let project_transaction = apply_code_action.await?;
 9142        let project_transaction = this.update(&mut cx, |this, cx| {
 9143            this.buffer_store.update(cx, |buffer_store, cx| {
 9144                buffer_store.serialize_project_transaction_for_peer(
 9145                    project_transaction,
 9146                    sender_id,
 9147                    cx,
 9148                )
 9149            })
 9150        });
 9151        Ok(proto::ApplyCodeActionResponse {
 9152            transaction: Some(project_transaction),
 9153        })
 9154    }
 9155
 9156    async fn handle_register_buffer_with_language_servers(
 9157        this: Entity<Self>,
 9158        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9159        mut cx: AsyncApp,
 9160    ) -> Result<proto::Ack> {
 9161        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9162        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9163        this.update(&mut cx, |this, cx| {
 9164            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9165                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9166                    project_id: upstream_project_id,
 9167                    buffer_id: buffer_id.to_proto(),
 9168                    only_servers: envelope.payload.only_servers,
 9169                });
 9170            }
 9171
 9172            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9173                anyhow::bail!("buffer is not open");
 9174            };
 9175
 9176            let handle = this.register_buffer_with_language_servers(
 9177                &buffer,
 9178                envelope
 9179                    .payload
 9180                    .only_servers
 9181                    .into_iter()
 9182                    .filter_map(|selector| {
 9183                        Some(match selector.selector? {
 9184                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9185                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9186                            }
 9187                            proto::language_server_selector::Selector::Name(name) => {
 9188                                LanguageServerSelector::Name(LanguageServerName(
 9189                                    SharedString::from(name),
 9190                                ))
 9191                            }
 9192                        })
 9193                    })
 9194                    .collect(),
 9195                false,
 9196                cx,
 9197            );
 9198            // Pull diagnostics for the buffer even if it was already registered.
 9199            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9200            // but it's unclear if we need it.
 9201            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9202                .detach();
 9203            this.buffer_store().update(cx, |buffer_store, _| {
 9204                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9205            });
 9206
 9207            Ok(())
 9208        })?;
 9209        Ok(proto::Ack {})
 9210    }
 9211
 9212    async fn handle_rename_project_entry(
 9213        this: Entity<Self>,
 9214        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9215        mut cx: AsyncApp,
 9216    ) -> Result<proto::ProjectEntryResponse> {
 9217        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9218        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9219        let new_path =
 9220            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9221
 9222        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9223            .update(&mut cx, |this, cx| {
 9224                let (worktree, entry) = this
 9225                    .worktree_store
 9226                    .read(cx)
 9227                    .worktree_and_entry_for_id(entry_id, cx)?;
 9228                let new_worktree = this
 9229                    .worktree_store
 9230                    .read(cx)
 9231                    .worktree_for_id(new_worktree_id, cx)?;
 9232                Some((
 9233                    this.worktree_store.clone(),
 9234                    worktree,
 9235                    new_worktree,
 9236                    entry.clone(),
 9237                ))
 9238            })
 9239            .context("worktree not found")?;
 9240        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9241            (worktree.absolutize(&old_entry.path), worktree.id())
 9242        });
 9243        let new_abs_path =
 9244            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9245
 9246        let _transaction = Self::will_rename_entry(
 9247            this.downgrade(),
 9248            old_worktree_id,
 9249            &old_abs_path,
 9250            &new_abs_path,
 9251            old_entry.is_dir(),
 9252            cx.clone(),
 9253        )
 9254        .await;
 9255        let response = WorktreeStore::handle_rename_project_entry(
 9256            worktree_store,
 9257            envelope.payload,
 9258            cx.clone(),
 9259        )
 9260        .await;
 9261        this.read_with(&cx, |this, _| {
 9262            this.did_rename_entry(
 9263                old_worktree_id,
 9264                &old_abs_path,
 9265                &new_abs_path,
 9266                old_entry.is_dir(),
 9267            );
 9268        });
 9269        response
 9270    }
 9271
 9272    async fn handle_update_diagnostic_summary(
 9273        this: Entity<Self>,
 9274        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9275        mut cx: AsyncApp,
 9276    ) -> Result<()> {
 9277        this.update(&mut cx, |lsp_store, cx| {
 9278            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9279            let mut updated_diagnostics_paths = HashMap::default();
 9280            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9281            for message_summary in envelope
 9282                .payload
 9283                .summary
 9284                .into_iter()
 9285                .chain(envelope.payload.more_summaries)
 9286            {
 9287                let project_path = ProjectPath {
 9288                    worktree_id,
 9289                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9290                };
 9291                let path = project_path.path.clone();
 9292                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9293                let summary = DiagnosticSummary {
 9294                    error_count: message_summary.error_count as usize,
 9295                    warning_count: message_summary.warning_count as usize,
 9296                };
 9297
 9298                if summary.is_empty() {
 9299                    if let Some(worktree_summaries) =
 9300                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9301                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9302                    {
 9303                        summaries.remove(&server_id);
 9304                        if summaries.is_empty() {
 9305                            worktree_summaries.remove(&path);
 9306                        }
 9307                    }
 9308                } else {
 9309                    lsp_store
 9310                        .diagnostic_summaries
 9311                        .entry(worktree_id)
 9312                        .or_default()
 9313                        .entry(path)
 9314                        .or_default()
 9315                        .insert(server_id, summary);
 9316                }
 9317
 9318                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9319                    match &mut diagnostics_summary {
 9320                        Some(diagnostics_summary) => {
 9321                            diagnostics_summary
 9322                                .more_summaries
 9323                                .push(proto::DiagnosticSummary {
 9324                                    path: project_path.path.as_ref().to_proto(),
 9325                                    language_server_id: server_id.0 as u64,
 9326                                    error_count: summary.error_count as u32,
 9327                                    warning_count: summary.warning_count as u32,
 9328                                })
 9329                        }
 9330                        None => {
 9331                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9332                                project_id: *project_id,
 9333                                worktree_id: worktree_id.to_proto(),
 9334                                summary: Some(proto::DiagnosticSummary {
 9335                                    path: project_path.path.as_ref().to_proto(),
 9336                                    language_server_id: server_id.0 as u64,
 9337                                    error_count: summary.error_count as u32,
 9338                                    warning_count: summary.warning_count as u32,
 9339                                }),
 9340                                more_summaries: Vec::new(),
 9341                            })
 9342                        }
 9343                    }
 9344                }
 9345                updated_diagnostics_paths
 9346                    .entry(server_id)
 9347                    .or_insert_with(Vec::new)
 9348                    .push(project_path);
 9349            }
 9350
 9351            if let Some((diagnostics_summary, (downstream_client, _))) =
 9352                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9353            {
 9354                downstream_client.send(diagnostics_summary).log_err();
 9355            }
 9356            for (server_id, paths) in updated_diagnostics_paths {
 9357                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9358            }
 9359            Ok(())
 9360        })
 9361    }
 9362
 9363    async fn handle_start_language_server(
 9364        lsp_store: Entity<Self>,
 9365        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9366        mut cx: AsyncApp,
 9367    ) -> Result<()> {
 9368        let server = envelope.payload.server.context("invalid server")?;
 9369        let server_capabilities =
 9370            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9371                .with_context(|| {
 9372                    format!(
 9373                        "incorrect server capabilities {}",
 9374                        envelope.payload.capabilities
 9375                    )
 9376                })?;
 9377        lsp_store.update(&mut cx, |lsp_store, cx| {
 9378            let server_id = LanguageServerId(server.id as usize);
 9379            let server_name = LanguageServerName::from_proto(server.name.clone());
 9380            lsp_store
 9381                .lsp_server_capabilities
 9382                .insert(server_id, server_capabilities);
 9383            lsp_store.language_server_statuses.insert(
 9384                server_id,
 9385                LanguageServerStatus {
 9386                    name: server_name.clone(),
 9387                    server_version: None,
 9388                    pending_work: Default::default(),
 9389                    has_pending_diagnostic_updates: false,
 9390                    progress_tokens: Default::default(),
 9391                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9392                    binary: None,
 9393                    configuration: None,
 9394                    workspace_folders: BTreeSet::new(),
 9395                    process_id: None,
 9396                },
 9397            );
 9398            cx.emit(LspStoreEvent::LanguageServerAdded(
 9399                server_id,
 9400                server_name,
 9401                server.worktree_id.map(WorktreeId::from_proto),
 9402            ));
 9403            cx.notify();
 9404        });
 9405        Ok(())
 9406    }
 9407
 9408    async fn handle_update_language_server(
 9409        lsp_store: Entity<Self>,
 9410        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9411        mut cx: AsyncApp,
 9412    ) -> Result<()> {
 9413        lsp_store.update(&mut cx, |lsp_store, cx| {
 9414            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9415
 9416            match envelope.payload.variant.context("invalid variant")? {
 9417                proto::update_language_server::Variant::WorkStart(payload) => {
 9418                    lsp_store.on_lsp_work_start(
 9419                        language_server_id,
 9420                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9421                            .context("invalid progress token value")?,
 9422                        LanguageServerProgress {
 9423                            title: payload.title,
 9424                            is_disk_based_diagnostics_progress: false,
 9425                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9426                            message: payload.message,
 9427                            percentage: payload.percentage.map(|p| p as usize),
 9428                            last_update_at: cx.background_executor().now(),
 9429                        },
 9430                        cx,
 9431                    );
 9432                }
 9433                proto::update_language_server::Variant::WorkProgress(payload) => {
 9434                    lsp_store.on_lsp_work_progress(
 9435                        language_server_id,
 9436                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9437                            .context("invalid progress token value")?,
 9438                        LanguageServerProgress {
 9439                            title: None,
 9440                            is_disk_based_diagnostics_progress: false,
 9441                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9442                            message: payload.message,
 9443                            percentage: payload.percentage.map(|p| p as usize),
 9444                            last_update_at: cx.background_executor().now(),
 9445                        },
 9446                        cx,
 9447                    );
 9448                }
 9449
 9450                proto::update_language_server::Variant::WorkEnd(payload) => {
 9451                    lsp_store.on_lsp_work_end(
 9452                        language_server_id,
 9453                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9454                            .context("invalid progress token value")?,
 9455                        cx,
 9456                    );
 9457                }
 9458
 9459                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9460                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9461                }
 9462
 9463                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9464                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9465                }
 9466
 9467                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9468                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9469                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9470                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9471                        language_server_id,
 9472                        name: envelope
 9473                            .payload
 9474                            .server_name
 9475                            .map(SharedString::new)
 9476                            .map(LanguageServerName),
 9477                        message: non_lsp,
 9478                    });
 9479                }
 9480            }
 9481
 9482            Ok(())
 9483        })
 9484    }
 9485
 9486    async fn handle_language_server_log(
 9487        this: Entity<Self>,
 9488        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9489        mut cx: AsyncApp,
 9490    ) -> Result<()> {
 9491        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9492        let log_type = envelope
 9493            .payload
 9494            .log_type
 9495            .map(LanguageServerLogType::from_proto)
 9496            .context("invalid language server log type")?;
 9497
 9498        let message = envelope.payload.message;
 9499
 9500        this.update(&mut cx, |_, cx| {
 9501            cx.emit(LspStoreEvent::LanguageServerLog(
 9502                language_server_id,
 9503                log_type,
 9504                message,
 9505            ));
 9506        });
 9507        Ok(())
 9508    }
 9509
 9510    async fn handle_lsp_ext_cancel_flycheck(
 9511        lsp_store: Entity<Self>,
 9512        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9513        cx: AsyncApp,
 9514    ) -> Result<proto::Ack> {
 9515        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9516        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9517            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9518                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9519            } else {
 9520                None
 9521            }
 9522        });
 9523        if let Some(task) = task {
 9524            task.context("handling lsp ext cancel flycheck")?;
 9525        }
 9526
 9527        Ok(proto::Ack {})
 9528    }
 9529
 9530    async fn handle_lsp_ext_run_flycheck(
 9531        lsp_store: Entity<Self>,
 9532        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9533        mut cx: AsyncApp,
 9534    ) -> Result<proto::Ack> {
 9535        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9536        lsp_store.update(&mut cx, |lsp_store, cx| {
 9537            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9538                let text_document = if envelope.payload.current_file_only {
 9539                    let buffer_id = envelope
 9540                        .payload
 9541                        .buffer_id
 9542                        .map(|id| BufferId::new(id))
 9543                        .transpose()?;
 9544                    buffer_id
 9545                        .and_then(|buffer_id| {
 9546                            lsp_store
 9547                                .buffer_store()
 9548                                .read(cx)
 9549                                .get(buffer_id)
 9550                                .and_then(|buffer| {
 9551                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9552                                })
 9553                                .map(|path| make_text_document_identifier(&path))
 9554                        })
 9555                        .transpose()?
 9556                } else {
 9557                    None
 9558                };
 9559                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9560                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9561                )?;
 9562            }
 9563            anyhow::Ok(())
 9564        })?;
 9565
 9566        Ok(proto::Ack {})
 9567    }
 9568
 9569    async fn handle_lsp_ext_clear_flycheck(
 9570        lsp_store: Entity<Self>,
 9571        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9572        cx: AsyncApp,
 9573    ) -> Result<proto::Ack> {
 9574        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9575        lsp_store.read_with(&cx, |lsp_store, _| {
 9576            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9577                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9578            } else {
 9579                None
 9580            }
 9581        });
 9582
 9583        Ok(proto::Ack {})
 9584    }
 9585
 9586    pub fn disk_based_diagnostics_started(
 9587        &mut self,
 9588        language_server_id: LanguageServerId,
 9589        cx: &mut Context<Self>,
 9590    ) {
 9591        if let Some(language_server_status) =
 9592            self.language_server_statuses.get_mut(&language_server_id)
 9593        {
 9594            language_server_status.has_pending_diagnostic_updates = true;
 9595        }
 9596
 9597        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9598        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9599            language_server_id,
 9600            name: self
 9601                .language_server_adapter_for_id(language_server_id)
 9602                .map(|adapter| adapter.name()),
 9603            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9604                Default::default(),
 9605            ),
 9606        })
 9607    }
 9608
 9609    pub fn disk_based_diagnostics_finished(
 9610        &mut self,
 9611        language_server_id: LanguageServerId,
 9612        cx: &mut Context<Self>,
 9613    ) {
 9614        if let Some(language_server_status) =
 9615            self.language_server_statuses.get_mut(&language_server_id)
 9616        {
 9617            language_server_status.has_pending_diagnostic_updates = false;
 9618        }
 9619
 9620        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9621        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9622            language_server_id,
 9623            name: self
 9624                .language_server_adapter_for_id(language_server_id)
 9625                .map(|adapter| adapter.name()),
 9626            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9627                Default::default(),
 9628            ),
 9629        })
 9630    }
 9631
 9632    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9633    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9634    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9635    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9636    // the language server might take some time to publish diagnostics.
 9637    fn simulate_disk_based_diagnostics_events_if_needed(
 9638        &mut self,
 9639        language_server_id: LanguageServerId,
 9640        cx: &mut Context<Self>,
 9641    ) {
 9642        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9643
 9644        let Some(LanguageServerState::Running {
 9645            simulate_disk_based_diagnostics_completion,
 9646            adapter,
 9647            ..
 9648        }) = self
 9649            .as_local_mut()
 9650            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9651        else {
 9652            return;
 9653        };
 9654
 9655        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9656            return;
 9657        }
 9658
 9659        let prev_task =
 9660            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9661                cx.background_executor()
 9662                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9663                    .await;
 9664
 9665                this.update(cx, |this, cx| {
 9666                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9667
 9668                    if let Some(LanguageServerState::Running {
 9669                        simulate_disk_based_diagnostics_completion,
 9670                        ..
 9671                    }) = this.as_local_mut().and_then(|local_store| {
 9672                        local_store.language_servers.get_mut(&language_server_id)
 9673                    }) {
 9674                        *simulate_disk_based_diagnostics_completion = None;
 9675                    }
 9676                })
 9677                .ok();
 9678            }));
 9679
 9680        if prev_task.is_none() {
 9681            self.disk_based_diagnostics_started(language_server_id, cx);
 9682        }
 9683    }
 9684
 9685    pub fn language_server_statuses(
 9686        &self,
 9687    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9688        self.language_server_statuses
 9689            .iter()
 9690            .map(|(key, value)| (*key, value))
 9691    }
 9692
 9693    pub(super) fn did_rename_entry(
 9694        &self,
 9695        worktree_id: WorktreeId,
 9696        old_path: &Path,
 9697        new_path: &Path,
 9698        is_dir: bool,
 9699    ) {
 9700        maybe!({
 9701            let local_store = self.as_local()?;
 9702
 9703            let old_uri = lsp::Uri::from_file_path(old_path)
 9704                .ok()
 9705                .map(|uri| uri.to_string())?;
 9706            let new_uri = lsp::Uri::from_file_path(new_path)
 9707                .ok()
 9708                .map(|uri| uri.to_string())?;
 9709
 9710            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9711                let Some(filter) = local_store
 9712                    .language_server_paths_watched_for_rename
 9713                    .get(&language_server.server_id())
 9714                else {
 9715                    continue;
 9716                };
 9717
 9718                if filter.should_send_did_rename(&old_uri, is_dir) {
 9719                    language_server
 9720                        .notify::<DidRenameFiles>(RenameFilesParams {
 9721                            files: vec![FileRename {
 9722                                old_uri: old_uri.clone(),
 9723                                new_uri: new_uri.clone(),
 9724                            }],
 9725                        })
 9726                        .ok();
 9727                }
 9728            }
 9729            Some(())
 9730        });
 9731    }
 9732
 9733    pub(super) fn will_rename_entry(
 9734        this: WeakEntity<Self>,
 9735        worktree_id: WorktreeId,
 9736        old_path: &Path,
 9737        new_path: &Path,
 9738        is_dir: bool,
 9739        cx: AsyncApp,
 9740    ) -> Task<ProjectTransaction> {
 9741        let old_uri = lsp::Uri::from_file_path(old_path)
 9742            .ok()
 9743            .map(|uri| uri.to_string());
 9744        let new_uri = lsp::Uri::from_file_path(new_path)
 9745            .ok()
 9746            .map(|uri| uri.to_string());
 9747        cx.spawn(async move |cx| {
 9748            let mut tasks = vec![];
 9749            this.update(cx, |this, cx| {
 9750                let local_store = this.as_local()?;
 9751                let old_uri = old_uri?;
 9752                let new_uri = new_uri?;
 9753                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9754                    let Some(filter) = local_store
 9755                        .language_server_paths_watched_for_rename
 9756                        .get(&language_server.server_id())
 9757                    else {
 9758                        continue;
 9759                    };
 9760
 9761                    if !filter.should_send_will_rename(&old_uri, is_dir) {
 9762                        continue;
 9763                    }
 9764                    let request_timeout = ProjectSettings::get_global(cx)
 9765                        .global_lsp_settings
 9766                        .get_request_timeout();
 9767
 9768                    let apply_edit = cx.spawn({
 9769                        let old_uri = old_uri.clone();
 9770                        let new_uri = new_uri.clone();
 9771                        let language_server = language_server.clone();
 9772                        async move |this, cx| {
 9773                            let edit = language_server
 9774                                .request::<WillRenameFiles>(
 9775                                    RenameFilesParams {
 9776                                        files: vec![FileRename { old_uri, new_uri }],
 9777                                    },
 9778                                    request_timeout,
 9779                                )
 9780                                .await
 9781                                .into_response()
 9782                                .context("will rename files")
 9783                                .log_err()
 9784                                .flatten()?;
 9785
 9786                            LocalLspStore::deserialize_workspace_edit(
 9787                                this.upgrade()?,
 9788                                edit,
 9789                                false,
 9790                                language_server.clone(),
 9791                                cx,
 9792                            )
 9793                            .await
 9794                            .ok()
 9795                        }
 9796                    });
 9797                    tasks.push(apply_edit);
 9798                }
 9799                Some(())
 9800            })
 9801            .ok()
 9802            .flatten();
 9803            let mut merged_transaction = ProjectTransaction::default();
 9804            for task in tasks {
 9805                // Await on tasks sequentially so that the order of application of edits is deterministic
 9806                // (at least with regards to the order of registration of language servers)
 9807                if let Some(transaction) = task.await {
 9808                    for (buffer, buffer_transaction) in transaction.0 {
 9809                        merged_transaction.0.insert(buffer, buffer_transaction);
 9810                    }
 9811                }
 9812            }
 9813            merged_transaction
 9814        })
 9815    }
 9816
 9817    fn lsp_notify_abs_paths_changed(
 9818        &mut self,
 9819        server_id: LanguageServerId,
 9820        changes: Vec<PathEvent>,
 9821    ) {
 9822        maybe!({
 9823            let server = self.language_server_for_id(server_id)?;
 9824            let changes = changes
 9825                .into_iter()
 9826                .filter_map(|event| {
 9827                    let typ = match event.kind? {
 9828                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9829                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9830                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9831                    };
 9832                    Some(lsp::FileEvent {
 9833                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9834                        typ,
 9835                    })
 9836                })
 9837                .collect::<Vec<_>>();
 9838            if !changes.is_empty() {
 9839                server
 9840                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9841                        lsp::DidChangeWatchedFilesParams { changes },
 9842                    )
 9843                    .ok();
 9844            }
 9845            Some(())
 9846        });
 9847    }
 9848
 9849    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9850        self.as_local()?.language_server_for_id(id)
 9851    }
 9852
 9853    fn on_lsp_progress(
 9854        &mut self,
 9855        progress_params: lsp::ProgressParams,
 9856        language_server_id: LanguageServerId,
 9857        disk_based_diagnostics_progress_token: Option<String>,
 9858        cx: &mut Context<Self>,
 9859    ) {
 9860        match progress_params.value {
 9861            lsp::ProgressParamsValue::WorkDone(progress) => {
 9862                self.handle_work_done_progress(
 9863                    progress,
 9864                    language_server_id,
 9865                    disk_based_diagnostics_progress_token,
 9866                    ProgressToken::from_lsp(progress_params.token),
 9867                    cx,
 9868                );
 9869            }
 9870            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9871                let registration_id = match progress_params.token {
 9872                    lsp::NumberOrString::Number(_) => None,
 9873                    lsp::NumberOrString::String(token) => token
 9874                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9875                        .map(|(_, id)| id.to_owned()),
 9876                };
 9877                if let Some(LanguageServerState::Running {
 9878                    workspace_diagnostics_refresh_tasks,
 9879                    ..
 9880                }) = self
 9881                    .as_local_mut()
 9882                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9883                    && let Some(workspace_diagnostics) =
 9884                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9885                {
 9886                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9887                    self.apply_workspace_diagnostic_report(
 9888                        language_server_id,
 9889                        report,
 9890                        registration_id.map(SharedString::from),
 9891                        cx,
 9892                    )
 9893                }
 9894            }
 9895        }
 9896    }
 9897
 9898    fn handle_work_done_progress(
 9899        &mut self,
 9900        progress: lsp::WorkDoneProgress,
 9901        language_server_id: LanguageServerId,
 9902        disk_based_diagnostics_progress_token: Option<String>,
 9903        token: ProgressToken,
 9904        cx: &mut Context<Self>,
 9905    ) {
 9906        let language_server_status =
 9907            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9908                status
 9909            } else {
 9910                return;
 9911            };
 9912
 9913        if !language_server_status.progress_tokens.contains(&token) {
 9914            return;
 9915        }
 9916
 9917        let is_disk_based_diagnostics_progress =
 9918            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9919                (&disk_based_diagnostics_progress_token, &token)
 9920            {
 9921                token.starts_with(disk_based_token)
 9922            } else {
 9923                false
 9924            };
 9925
 9926        match progress {
 9927            lsp::WorkDoneProgress::Begin(report) => {
 9928                if is_disk_based_diagnostics_progress {
 9929                    self.disk_based_diagnostics_started(language_server_id, cx);
 9930                }
 9931                self.on_lsp_work_start(
 9932                    language_server_id,
 9933                    token.clone(),
 9934                    LanguageServerProgress {
 9935                        title: Some(report.title),
 9936                        is_disk_based_diagnostics_progress,
 9937                        is_cancellable: report.cancellable.unwrap_or(false),
 9938                        message: report.message.clone(),
 9939                        percentage: report.percentage.map(|p| p as usize),
 9940                        last_update_at: cx.background_executor().now(),
 9941                    },
 9942                    cx,
 9943                );
 9944            }
 9945            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9946                language_server_id,
 9947                token,
 9948                LanguageServerProgress {
 9949                    title: None,
 9950                    is_disk_based_diagnostics_progress,
 9951                    is_cancellable: report.cancellable.unwrap_or(false),
 9952                    message: report.message,
 9953                    percentage: report.percentage.map(|p| p as usize),
 9954                    last_update_at: cx.background_executor().now(),
 9955                },
 9956                cx,
 9957            ),
 9958            lsp::WorkDoneProgress::End(_) => {
 9959                language_server_status.progress_tokens.remove(&token);
 9960                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9961                if is_disk_based_diagnostics_progress {
 9962                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9963                }
 9964            }
 9965        }
 9966    }
 9967
 9968    fn on_lsp_work_start(
 9969        &mut self,
 9970        language_server_id: LanguageServerId,
 9971        token: ProgressToken,
 9972        progress: LanguageServerProgress,
 9973        cx: &mut Context<Self>,
 9974    ) {
 9975        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9976            status.pending_work.insert(token.clone(), progress.clone());
 9977            cx.notify();
 9978        }
 9979        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9980            language_server_id,
 9981            name: self
 9982                .language_server_adapter_for_id(language_server_id)
 9983                .map(|adapter| adapter.name()),
 9984            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9985                token: Some(token.to_proto()),
 9986                title: progress.title,
 9987                message: progress.message,
 9988                percentage: progress.percentage.map(|p| p as u32),
 9989                is_cancellable: Some(progress.is_cancellable),
 9990            }),
 9991        })
 9992    }
 9993
 9994    fn on_lsp_work_progress(
 9995        &mut self,
 9996        language_server_id: LanguageServerId,
 9997        token: ProgressToken,
 9998        progress: LanguageServerProgress,
 9999        cx: &mut Context<Self>,
10000    ) {
10001        let mut did_update = false;
10002        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10003            match status.pending_work.entry(token.clone()) {
10004                btree_map::Entry::Vacant(entry) => {
10005                    entry.insert(progress.clone());
10006                    did_update = true;
10007                }
10008                btree_map::Entry::Occupied(mut entry) => {
10009                    let entry = entry.get_mut();
10010                    if (progress.last_update_at - entry.last_update_at)
10011                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10012                    {
10013                        entry.last_update_at = progress.last_update_at;
10014                        if progress.message.is_some() {
10015                            entry.message = progress.message.clone();
10016                        }
10017                        if progress.percentage.is_some() {
10018                            entry.percentage = progress.percentage;
10019                        }
10020                        if progress.is_cancellable != entry.is_cancellable {
10021                            entry.is_cancellable = progress.is_cancellable;
10022                        }
10023                        did_update = true;
10024                    }
10025                }
10026            }
10027        }
10028
10029        if did_update {
10030            cx.emit(LspStoreEvent::LanguageServerUpdate {
10031                language_server_id,
10032                name: self
10033                    .language_server_adapter_for_id(language_server_id)
10034                    .map(|adapter| adapter.name()),
10035                message: proto::update_language_server::Variant::WorkProgress(
10036                    proto::LspWorkProgress {
10037                        token: Some(token.to_proto()),
10038                        message: progress.message,
10039                        percentage: progress.percentage.map(|p| p as u32),
10040                        is_cancellable: Some(progress.is_cancellable),
10041                    },
10042                ),
10043            })
10044        }
10045    }
10046
10047    fn on_lsp_work_end(
10048        &mut self,
10049        language_server_id: LanguageServerId,
10050        token: ProgressToken,
10051        cx: &mut Context<Self>,
10052    ) {
10053        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10054            if let Some(work) = status.pending_work.remove(&token)
10055                && !work.is_disk_based_diagnostics_progress
10056            {
10057                cx.emit(LspStoreEvent::RefreshInlayHints {
10058                    server_id: language_server_id,
10059                    request_id: None,
10060                });
10061            }
10062            cx.notify();
10063        }
10064
10065        cx.emit(LspStoreEvent::LanguageServerUpdate {
10066            language_server_id,
10067            name: self
10068                .language_server_adapter_for_id(language_server_id)
10069                .map(|adapter| adapter.name()),
10070            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10071                token: Some(token.to_proto()),
10072            }),
10073        })
10074    }
10075
10076    pub async fn handle_resolve_completion_documentation(
10077        this: Entity<Self>,
10078        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10079        mut cx: AsyncApp,
10080    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10081        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10082
10083        let completion = this
10084            .read_with(&cx, |this, cx| {
10085                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10086                let server = this
10087                    .language_server_for_id(id)
10088                    .with_context(|| format!("No language server {id}"))?;
10089
10090                let request_timeout = ProjectSettings::get_global(cx)
10091                    .global_lsp_settings
10092                    .get_request_timeout();
10093
10094                anyhow::Ok(cx.background_spawn(async move {
10095                    let can_resolve = server
10096                        .capabilities()
10097                        .completion_provider
10098                        .as_ref()
10099                        .and_then(|options| options.resolve_provider)
10100                        .unwrap_or(false);
10101                    if can_resolve {
10102                        server
10103                            .request::<lsp::request::ResolveCompletionItem>(
10104                                lsp_completion,
10105                                request_timeout,
10106                            )
10107                            .await
10108                            .into_response()
10109                            .context("resolve completion item")
10110                    } else {
10111                        anyhow::Ok(lsp_completion)
10112                    }
10113                }))
10114            })?
10115            .await?;
10116
10117        let mut documentation_is_markdown = false;
10118        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10119        let documentation = match completion.documentation {
10120            Some(lsp::Documentation::String(text)) => text,
10121
10122            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10123                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10124                value
10125            }
10126
10127            _ => String::new(),
10128        };
10129
10130        // If we have a new buffer_id, that means we're talking to a new client
10131        // and want to check for new text_edits in the completion too.
10132        let mut old_replace_start = None;
10133        let mut old_replace_end = None;
10134        let mut old_insert_start = None;
10135        let mut old_insert_end = None;
10136        let mut new_text = String::default();
10137        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10138            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10139                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10140                anyhow::Ok(buffer.read(cx).snapshot())
10141            })?;
10142
10143            if let Some(text_edit) = completion.text_edit.as_ref() {
10144                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10145
10146                if let Some(mut edit) = edit {
10147                    LineEnding::normalize(&mut edit.new_text);
10148
10149                    new_text = edit.new_text;
10150                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10151                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10152                    if let Some(insert_range) = edit.insert_range {
10153                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10154                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10155                    }
10156                }
10157            }
10158        }
10159
10160        Ok(proto::ResolveCompletionDocumentationResponse {
10161            documentation,
10162            documentation_is_markdown,
10163            old_replace_start,
10164            old_replace_end,
10165            new_text,
10166            lsp_completion,
10167            old_insert_start,
10168            old_insert_end,
10169        })
10170    }
10171
10172    async fn handle_on_type_formatting(
10173        this: Entity<Self>,
10174        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10175        mut cx: AsyncApp,
10176    ) -> Result<proto::OnTypeFormattingResponse> {
10177        let on_type_formatting = this.update(&mut cx, |this, cx| {
10178            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10179            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10180            let position = envelope
10181                .payload
10182                .position
10183                .and_then(deserialize_anchor)
10184                .context("invalid position")?;
10185            anyhow::Ok(this.apply_on_type_formatting(
10186                buffer,
10187                position,
10188                envelope.payload.trigger.clone(),
10189                cx,
10190            ))
10191        })?;
10192
10193        let transaction = on_type_formatting
10194            .await?
10195            .as_ref()
10196            .map(language::proto::serialize_transaction);
10197        Ok(proto::OnTypeFormattingResponse { transaction })
10198    }
10199
10200    async fn handle_pull_workspace_diagnostics(
10201        lsp_store: Entity<Self>,
10202        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10203        mut cx: AsyncApp,
10204    ) -> Result<proto::Ack> {
10205        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10206        lsp_store.update(&mut cx, |lsp_store, _| {
10207            lsp_store.pull_workspace_diagnostics(server_id);
10208        });
10209        Ok(proto::Ack {})
10210    }
10211
10212    async fn handle_open_buffer_for_symbol(
10213        this: Entity<Self>,
10214        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10215        mut cx: AsyncApp,
10216    ) -> Result<proto::OpenBufferForSymbolResponse> {
10217        let peer_id = envelope.original_sender_id().unwrap_or_default();
10218        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10219        let symbol = Self::deserialize_symbol(symbol)?;
10220        this.read_with(&cx, |this, _| {
10221            if let SymbolLocation::OutsideProject {
10222                abs_path,
10223                signature,
10224            } = &symbol.path
10225            {
10226                let new_signature = this.symbol_signature(&abs_path);
10227                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10228            }
10229            Ok(())
10230        })?;
10231        let buffer = this
10232            .update(&mut cx, |this, cx| {
10233                this.open_buffer_for_symbol(
10234                    &Symbol {
10235                        language_server_name: symbol.language_server_name,
10236                        source_worktree_id: symbol.source_worktree_id,
10237                        source_language_server_id: symbol.source_language_server_id,
10238                        path: symbol.path,
10239                        name: symbol.name,
10240                        kind: symbol.kind,
10241                        range: symbol.range,
10242                        label: CodeLabel::default(),
10243                        container_name: symbol.container_name,
10244                    },
10245                    cx,
10246                )
10247            })
10248            .await?;
10249
10250        this.update(&mut cx, |this, cx| {
10251            let is_private = buffer
10252                .read(cx)
10253                .file()
10254                .map(|f| f.is_private())
10255                .unwrap_or_default();
10256            if is_private {
10257                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10258            } else {
10259                this.buffer_store
10260                    .update(cx, |buffer_store, cx| {
10261                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10262                    })
10263                    .detach_and_log_err(cx);
10264                let buffer_id = buffer.read(cx).remote_id().to_proto();
10265                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10266            }
10267        })
10268    }
10269
10270    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10271        let mut hasher = Sha256::new();
10272        hasher.update(abs_path.to_string_lossy().as_bytes());
10273        hasher.update(self.nonce.to_be_bytes());
10274        hasher.finalize().as_slice().try_into().unwrap()
10275    }
10276
10277    pub async fn handle_get_project_symbols(
10278        this: Entity<Self>,
10279        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10280        mut cx: AsyncApp,
10281    ) -> Result<proto::GetProjectSymbolsResponse> {
10282        let symbols = this
10283            .update(&mut cx, |this, cx| {
10284                this.symbols(&envelope.payload.query, cx)
10285            })
10286            .await?;
10287
10288        Ok(proto::GetProjectSymbolsResponse {
10289            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10290        })
10291    }
10292
10293    pub async fn handle_restart_language_servers(
10294        this: Entity<Self>,
10295        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10296        mut cx: AsyncApp,
10297    ) -> Result<proto::Ack> {
10298        this.update(&mut cx, |lsp_store, cx| {
10299            let buffers =
10300                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10301            lsp_store.restart_language_servers_for_buffers(
10302                buffers,
10303                envelope
10304                    .payload
10305                    .only_servers
10306                    .into_iter()
10307                    .filter_map(|selector| {
10308                        Some(match selector.selector? {
10309                            proto::language_server_selector::Selector::ServerId(server_id) => {
10310                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10311                            }
10312                            proto::language_server_selector::Selector::Name(name) => {
10313                                LanguageServerSelector::Name(LanguageServerName(
10314                                    SharedString::from(name),
10315                                ))
10316                            }
10317                        })
10318                    })
10319                    .collect(),
10320                cx,
10321            );
10322        });
10323
10324        Ok(proto::Ack {})
10325    }
10326
10327    pub async fn handle_stop_language_servers(
10328        lsp_store: Entity<Self>,
10329        envelope: TypedEnvelope<proto::StopLanguageServers>,
10330        mut cx: AsyncApp,
10331    ) -> Result<proto::Ack> {
10332        lsp_store.update(&mut cx, |lsp_store, cx| {
10333            if envelope.payload.all
10334                && envelope.payload.also_servers.is_empty()
10335                && envelope.payload.buffer_ids.is_empty()
10336            {
10337                lsp_store.stop_all_language_servers(cx);
10338            } else {
10339                let buffers =
10340                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10341                lsp_store
10342                    .stop_language_servers_for_buffers(
10343                        buffers,
10344                        envelope
10345                            .payload
10346                            .also_servers
10347                            .into_iter()
10348                            .filter_map(|selector| {
10349                                Some(match selector.selector? {
10350                                    proto::language_server_selector::Selector::ServerId(
10351                                        server_id,
10352                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10353                                        server_id,
10354                                    )),
10355                                    proto::language_server_selector::Selector::Name(name) => {
10356                                        LanguageServerSelector::Name(LanguageServerName(
10357                                            SharedString::from(name),
10358                                        ))
10359                                    }
10360                                })
10361                            })
10362                            .collect(),
10363                        cx,
10364                    )
10365                    .detach_and_log_err(cx);
10366            }
10367        });
10368
10369        Ok(proto::Ack {})
10370    }
10371
10372    pub async fn handle_cancel_language_server_work(
10373        lsp_store: Entity<Self>,
10374        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10375        mut cx: AsyncApp,
10376    ) -> Result<proto::Ack> {
10377        lsp_store.update(&mut cx, |lsp_store, cx| {
10378            if let Some(work) = envelope.payload.work {
10379                match work {
10380                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10381                        let buffers =
10382                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10383                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10384                    }
10385                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10386                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10387                        let token = work
10388                            .token
10389                            .map(|token| {
10390                                ProgressToken::from_proto(token)
10391                                    .context("invalid work progress token")
10392                            })
10393                            .transpose()?;
10394                        lsp_store.cancel_language_server_work(server_id, token, cx);
10395                    }
10396                }
10397            }
10398            anyhow::Ok(())
10399        })?;
10400
10401        Ok(proto::Ack {})
10402    }
10403
10404    fn buffer_ids_to_buffers(
10405        &mut self,
10406        buffer_ids: impl Iterator<Item = u64>,
10407        cx: &mut Context<Self>,
10408    ) -> Vec<Entity<Buffer>> {
10409        buffer_ids
10410            .into_iter()
10411            .flat_map(|buffer_id| {
10412                self.buffer_store
10413                    .read(cx)
10414                    .get(BufferId::new(buffer_id).log_err()?)
10415            })
10416            .collect::<Vec<_>>()
10417    }
10418
10419    async fn handle_apply_additional_edits_for_completion(
10420        this: Entity<Self>,
10421        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10422        mut cx: AsyncApp,
10423    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10424        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10425            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10426            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10427            let completion = Self::deserialize_completion(
10428                envelope.payload.completion.context("invalid completion")?,
10429            )?;
10430            anyhow::Ok((buffer, completion))
10431        })?;
10432
10433        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10434            this.apply_additional_edits_for_completion(
10435                buffer,
10436                Rc::new(RefCell::new(Box::new([Completion {
10437                    replace_range: completion.replace_range,
10438                    new_text: completion.new_text,
10439                    source: completion.source,
10440                    documentation: None,
10441                    label: CodeLabel::default(),
10442                    match_start: None,
10443                    snippet_deduplication_key: None,
10444                    insert_text_mode: None,
10445                    icon_path: None,
10446                    confirm: None,
10447                }]))),
10448                0,
10449                false,
10450                cx,
10451            )
10452        });
10453
10454        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10455            transaction: apply_additional_edits
10456                .await?
10457                .as_ref()
10458                .map(language::proto::serialize_transaction),
10459        })
10460    }
10461
10462    pub fn last_formatting_failure(&self) -> Option<&str> {
10463        self.last_formatting_failure.as_deref()
10464    }
10465
10466    pub fn reset_last_formatting_failure(&mut self) {
10467        self.last_formatting_failure = None;
10468    }
10469
10470    pub fn environment_for_buffer(
10471        &self,
10472        buffer: &Entity<Buffer>,
10473        cx: &mut Context<Self>,
10474    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10475        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10476            environment.update(cx, |env, cx| {
10477                env.buffer_environment(buffer, &self.worktree_store, cx)
10478            })
10479        } else {
10480            Task::ready(None).shared()
10481        }
10482    }
10483
10484    pub fn format(
10485        &mut self,
10486        buffers: HashSet<Entity<Buffer>>,
10487        target: LspFormatTarget,
10488        push_to_history: bool,
10489        trigger: FormatTrigger,
10490        cx: &mut Context<Self>,
10491    ) -> Task<anyhow::Result<ProjectTransaction>> {
10492        let logger = zlog::scoped!("format");
10493        if self.as_local().is_some() {
10494            zlog::trace!(logger => "Formatting locally");
10495            let logger = zlog::scoped!(logger => "local");
10496            let buffers = buffers
10497                .into_iter()
10498                .map(|buffer_handle| {
10499                    let buffer = buffer_handle.read(cx);
10500                    let buffer_abs_path = File::from_dyn(buffer.file())
10501                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10502
10503                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10504                })
10505                .collect::<Vec<_>>();
10506
10507            cx.spawn(async move |lsp_store, cx| {
10508                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10509
10510                for (handle, abs_path, id) in buffers {
10511                    let env = lsp_store
10512                        .update(cx, |lsp_store, cx| {
10513                            lsp_store.environment_for_buffer(&handle, cx)
10514                        })?
10515                        .await;
10516
10517                    let ranges = match &target {
10518                        LspFormatTarget::Buffers => None,
10519                        LspFormatTarget::Ranges(ranges) => {
10520                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10521                        }
10522                    };
10523
10524                    formattable_buffers.push(FormattableBuffer {
10525                        handle,
10526                        abs_path,
10527                        env,
10528                        ranges,
10529                    });
10530                }
10531                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10532
10533                let format_timer = zlog::time!(logger => "Formatting buffers");
10534                let result = LocalLspStore::format_locally(
10535                    lsp_store.clone(),
10536                    formattable_buffers,
10537                    push_to_history,
10538                    trigger,
10539                    logger,
10540                    cx,
10541                )
10542                .await;
10543                format_timer.end();
10544
10545                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10546
10547                lsp_store.update(cx, |lsp_store, _| {
10548                    lsp_store.update_last_formatting_failure(&result);
10549                })?;
10550
10551                result
10552            })
10553        } else if let Some((client, project_id)) = self.upstream_client() {
10554            zlog::trace!(logger => "Formatting remotely");
10555            let logger = zlog::scoped!(logger => "remote");
10556
10557            let buffer_ranges = match &target {
10558                LspFormatTarget::Buffers => Vec::new(),
10559                LspFormatTarget::Ranges(ranges) => ranges
10560                    .iter()
10561                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10562                        buffer_id: buffer_id.to_proto(),
10563                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10564                    })
10565                    .collect(),
10566            };
10567
10568            let buffer_store = self.buffer_store();
10569            cx.spawn(async move |lsp_store, cx| {
10570                zlog::trace!(logger => "Sending remote format request");
10571                let request_timer = zlog::time!(logger => "remote format request");
10572                let result = client
10573                    .request(proto::FormatBuffers {
10574                        project_id,
10575                        trigger: trigger as i32,
10576                        buffer_ids: buffers
10577                            .iter()
10578                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10579                            .collect(),
10580                        buffer_ranges,
10581                    })
10582                    .await
10583                    .and_then(|result| result.transaction.context("missing transaction"));
10584                request_timer.end();
10585
10586                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10587
10588                lsp_store.update(cx, |lsp_store, _| {
10589                    lsp_store.update_last_formatting_failure(&result);
10590                })?;
10591
10592                let transaction_response = result?;
10593                let _timer = zlog::time!(logger => "deserializing project transaction");
10594                buffer_store
10595                    .update(cx, |buffer_store, cx| {
10596                        buffer_store.deserialize_project_transaction(
10597                            transaction_response,
10598                            push_to_history,
10599                            cx,
10600                        )
10601                    })
10602                    .await
10603            })
10604        } else {
10605            zlog::trace!(logger => "Not formatting");
10606            Task::ready(Ok(ProjectTransaction::default()))
10607        }
10608    }
10609
10610    async fn handle_format_buffers(
10611        this: Entity<Self>,
10612        envelope: TypedEnvelope<proto::FormatBuffers>,
10613        mut cx: AsyncApp,
10614    ) -> Result<proto::FormatBuffersResponse> {
10615        let sender_id = envelope.original_sender_id().unwrap_or_default();
10616        let format = this.update(&mut cx, |this, cx| {
10617            let mut buffers = HashSet::default();
10618            for buffer_id in &envelope.payload.buffer_ids {
10619                let buffer_id = BufferId::new(*buffer_id)?;
10620                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10621            }
10622
10623            let target = if envelope.payload.buffer_ranges.is_empty() {
10624                LspFormatTarget::Buffers
10625            } else {
10626                let mut ranges_map = BTreeMap::new();
10627                for buffer_range in &envelope.payload.buffer_ranges {
10628                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10629                    let ranges: Result<Vec<_>> = buffer_range
10630                        .ranges
10631                        .iter()
10632                        .map(|range| {
10633                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10634                        })
10635                        .collect();
10636                    ranges_map.insert(buffer_id, ranges?);
10637                }
10638                LspFormatTarget::Ranges(ranges_map)
10639            };
10640
10641            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10642            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10643        })?;
10644
10645        let project_transaction = format.await?;
10646        let project_transaction = this.update(&mut cx, |this, cx| {
10647            this.buffer_store.update(cx, |buffer_store, cx| {
10648                buffer_store.serialize_project_transaction_for_peer(
10649                    project_transaction,
10650                    sender_id,
10651                    cx,
10652                )
10653            })
10654        });
10655        Ok(proto::FormatBuffersResponse {
10656            transaction: Some(project_transaction),
10657        })
10658    }
10659
10660    async fn handle_apply_code_action_kind(
10661        this: Entity<Self>,
10662        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10663        mut cx: AsyncApp,
10664    ) -> Result<proto::ApplyCodeActionKindResponse> {
10665        let sender_id = envelope.original_sender_id().unwrap_or_default();
10666        let format = this.update(&mut cx, |this, cx| {
10667            let mut buffers = HashSet::default();
10668            for buffer_id in &envelope.payload.buffer_ids {
10669                let buffer_id = BufferId::new(*buffer_id)?;
10670                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10671            }
10672            let kind = match envelope.payload.kind.as_str() {
10673                "" => CodeActionKind::EMPTY,
10674                "quickfix" => CodeActionKind::QUICKFIX,
10675                "refactor" => CodeActionKind::REFACTOR,
10676                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10677                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10678                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10679                "source" => CodeActionKind::SOURCE,
10680                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10681                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10682                _ => anyhow::bail!(
10683                    "Invalid code action kind {}",
10684                    envelope.payload.kind.as_str()
10685                ),
10686            };
10687            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10688        })?;
10689
10690        let project_transaction = format.await?;
10691        let project_transaction = this.update(&mut cx, |this, cx| {
10692            this.buffer_store.update(cx, |buffer_store, cx| {
10693                buffer_store.serialize_project_transaction_for_peer(
10694                    project_transaction,
10695                    sender_id,
10696                    cx,
10697                )
10698            })
10699        });
10700        Ok(proto::ApplyCodeActionKindResponse {
10701            transaction: Some(project_transaction),
10702        })
10703    }
10704
10705    async fn shutdown_language_server(
10706        server_state: Option<LanguageServerState>,
10707        name: LanguageServerName,
10708        cx: &mut AsyncApp,
10709    ) {
10710        let server = match server_state {
10711            Some(LanguageServerState::Starting { startup, .. }) => {
10712                let mut timer = cx
10713                    .background_executor()
10714                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10715                    .fuse();
10716
10717                select! {
10718                    server = startup.fuse() => server,
10719                    () = timer => {
10720                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10721                        None
10722                    },
10723                }
10724            }
10725
10726            Some(LanguageServerState::Running { server, .. }) => Some(server),
10727
10728            None => None,
10729        };
10730
10731        let Some(server) = server else { return };
10732        if let Some(shutdown) = server.shutdown() {
10733            shutdown.await;
10734        }
10735    }
10736
10737    // Returns a list of all of the worktrees which no longer have a language server and the root path
10738    // for the stopped server
10739    fn stop_local_language_server(
10740        &mut self,
10741        server_id: LanguageServerId,
10742        cx: &mut Context<Self>,
10743    ) -> Task<()> {
10744        let local = match &mut self.mode {
10745            LspStoreMode::Local(local) => local,
10746            _ => {
10747                return Task::ready(());
10748            }
10749        };
10750
10751        // Remove this server ID from all entries in the given worktree.
10752        local
10753            .language_server_ids
10754            .retain(|_, state| state.id != server_id);
10755        self.buffer_store.update(cx, |buffer_store, cx| {
10756            for buffer in buffer_store.buffers() {
10757                buffer.update(cx, |buffer, cx| {
10758                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10759                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10760                });
10761            }
10762        });
10763
10764        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10765            summaries.retain(|path, summaries_by_server_id| {
10766                if summaries_by_server_id.remove(&server_id).is_some() {
10767                    if let Some((client, project_id)) = self.downstream_client.clone() {
10768                        client
10769                            .send(proto::UpdateDiagnosticSummary {
10770                                project_id,
10771                                worktree_id: worktree_id.to_proto(),
10772                                summary: Some(proto::DiagnosticSummary {
10773                                    path: path.as_ref().to_proto(),
10774                                    language_server_id: server_id.0 as u64,
10775                                    error_count: 0,
10776                                    warning_count: 0,
10777                                }),
10778                                more_summaries: Vec::new(),
10779                            })
10780                            .log_err();
10781                    }
10782                    !summaries_by_server_id.is_empty()
10783                } else {
10784                    true
10785                }
10786            });
10787        }
10788
10789        let local = self.as_local_mut().unwrap();
10790        for diagnostics in local.diagnostics.values_mut() {
10791            diagnostics.retain(|_, diagnostics_by_server_id| {
10792                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10793                    diagnostics_by_server_id.remove(ix);
10794                    !diagnostics_by_server_id.is_empty()
10795                } else {
10796                    true
10797                }
10798            });
10799        }
10800        local.language_server_watched_paths.remove(&server_id);
10801
10802        let server_state = local.language_servers.remove(&server_id);
10803        self.cleanup_lsp_data(server_id);
10804        let name = self
10805            .language_server_statuses
10806            .remove(&server_id)
10807            .map(|status| status.name)
10808            .or_else(|| {
10809                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10810                    Some(adapter.name())
10811                } else {
10812                    None
10813                }
10814            });
10815
10816        if let Some(name) = name {
10817            log::info!("stopping language server {name}");
10818            self.languages
10819                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10820            cx.notify();
10821
10822            return cx.spawn(async move |lsp_store, cx| {
10823                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10824                lsp_store
10825                    .update(cx, |lsp_store, cx| {
10826                        lsp_store
10827                            .languages
10828                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10829                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10830                        cx.notify();
10831                    })
10832                    .ok();
10833            });
10834        }
10835
10836        if server_state.is_some() {
10837            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10838        }
10839        Task::ready(())
10840    }
10841
10842    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10843        self.shutdown_all_language_servers(cx).detach();
10844    }
10845
10846    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
10847        if let Some((client, project_id)) = self.upstream_client() {
10848            let request = client.request(proto::StopLanguageServers {
10849                project_id,
10850                buffer_ids: Vec::new(),
10851                also_servers: Vec::new(),
10852                all: true,
10853            });
10854            cx.background_spawn(async move {
10855                request.await.ok();
10856            })
10857        } else {
10858            let Some(local) = self.as_local_mut() else {
10859                return Task::ready(());
10860            };
10861            let language_servers_to_stop = local
10862                .language_server_ids
10863                .values()
10864                .map(|state| state.id)
10865                .collect();
10866            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10867            let tasks = language_servers_to_stop
10868                .into_iter()
10869                .map(|server| self.stop_local_language_server(server, cx))
10870                .collect::<Vec<_>>();
10871            cx.background_spawn(async move {
10872                futures::future::join_all(tasks).await;
10873            })
10874        }
10875    }
10876
10877    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
10878        let buffers = self.buffer_store.read(cx).buffers().collect();
10879        self.restart_language_servers_for_buffers(buffers, HashSet::default(), cx);
10880    }
10881
10882    pub fn restart_language_servers_for_buffers(
10883        &mut self,
10884        buffers: Vec<Entity<Buffer>>,
10885        only_restart_servers: HashSet<LanguageServerSelector>,
10886        cx: &mut Context<Self>,
10887    ) {
10888        if let Some((client, project_id)) = self.upstream_client() {
10889            let request = client.request(proto::RestartLanguageServers {
10890                project_id,
10891                buffer_ids: buffers
10892                    .into_iter()
10893                    .map(|b| b.read(cx).remote_id().to_proto())
10894                    .collect(),
10895                only_servers: only_restart_servers
10896                    .into_iter()
10897                    .map(|selector| {
10898                        let selector = match selector {
10899                            LanguageServerSelector::Id(language_server_id) => {
10900                                proto::language_server_selector::Selector::ServerId(
10901                                    language_server_id.to_proto(),
10902                                )
10903                            }
10904                            LanguageServerSelector::Name(language_server_name) => {
10905                                proto::language_server_selector::Selector::Name(
10906                                    language_server_name.to_string(),
10907                                )
10908                            }
10909                        };
10910                        proto::LanguageServerSelector {
10911                            selector: Some(selector),
10912                        }
10913                    })
10914                    .collect(),
10915                all: false,
10916            });
10917            cx.background_spawn(request).detach_and_log_err(cx);
10918        } else {
10919            let stop_task = if only_restart_servers.is_empty() {
10920                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10921            } else {
10922                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10923            };
10924            cx.spawn(async move |lsp_store, cx| {
10925                stop_task.await;
10926                lsp_store.update(cx, |lsp_store, cx| {
10927                    for buffer in buffers {
10928                        lsp_store.register_buffer_with_language_servers(
10929                            &buffer,
10930                            only_restart_servers.clone(),
10931                            true,
10932                            cx,
10933                        );
10934                    }
10935                })
10936            })
10937            .detach();
10938        }
10939    }
10940
10941    pub fn stop_language_servers_for_buffers(
10942        &mut self,
10943        buffers: Vec<Entity<Buffer>>,
10944        also_stop_servers: HashSet<LanguageServerSelector>,
10945        cx: &mut Context<Self>,
10946    ) -> Task<Result<()>> {
10947        if let Some((client, project_id)) = self.upstream_client() {
10948            let request = client.request(proto::StopLanguageServers {
10949                project_id,
10950                buffer_ids: buffers
10951                    .into_iter()
10952                    .map(|b| b.read(cx).remote_id().to_proto())
10953                    .collect(),
10954                also_servers: also_stop_servers
10955                    .into_iter()
10956                    .map(|selector| {
10957                        let selector = match selector {
10958                            LanguageServerSelector::Id(language_server_id) => {
10959                                proto::language_server_selector::Selector::ServerId(
10960                                    language_server_id.to_proto(),
10961                                )
10962                            }
10963                            LanguageServerSelector::Name(language_server_name) => {
10964                                proto::language_server_selector::Selector::Name(
10965                                    language_server_name.to_string(),
10966                                )
10967                            }
10968                        };
10969                        proto::LanguageServerSelector {
10970                            selector: Some(selector),
10971                        }
10972                    })
10973                    .collect(),
10974                all: false,
10975            });
10976            cx.background_spawn(async move {
10977                let _ = request.await?;
10978                Ok(())
10979            })
10980        } else {
10981            let task =
10982                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10983            cx.background_spawn(async move {
10984                task.await;
10985                Ok(())
10986            })
10987        }
10988    }
10989
10990    fn stop_local_language_servers_for_buffers(
10991        &mut self,
10992        buffers: &[Entity<Buffer>],
10993        also_stop_servers: HashSet<LanguageServerSelector>,
10994        cx: &mut Context<Self>,
10995    ) -> Task<()> {
10996        let Some(local) = self.as_local_mut() else {
10997            return Task::ready(());
10998        };
10999        let mut language_server_names_to_stop = BTreeSet::default();
11000        let mut language_servers_to_stop = also_stop_servers
11001            .into_iter()
11002            .flat_map(|selector| match selector {
11003                LanguageServerSelector::Id(id) => Some(id),
11004                LanguageServerSelector::Name(name) => {
11005                    language_server_names_to_stop.insert(name);
11006                    None
11007                }
11008            })
11009            .collect::<BTreeSet<_>>();
11010
11011        let mut covered_worktrees = HashSet::default();
11012        for buffer in buffers {
11013            buffer.update(cx, |buffer, cx| {
11014                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11015                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11016                    && covered_worktrees.insert(worktree_id)
11017                {
11018                    language_server_names_to_stop.retain(|name| {
11019                        let old_ids_count = language_servers_to_stop.len();
11020                        let all_language_servers_with_this_name = local
11021                            .language_server_ids
11022                            .iter()
11023                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11024                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11025                        old_ids_count == language_servers_to_stop.len()
11026                    });
11027                }
11028            });
11029        }
11030        for name in language_server_names_to_stop {
11031            language_servers_to_stop.extend(
11032                local
11033                    .language_server_ids
11034                    .iter()
11035                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11036            );
11037        }
11038
11039        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11040        let tasks = language_servers_to_stop
11041            .into_iter()
11042            .map(|server| self.stop_local_language_server(server, cx))
11043            .collect::<Vec<_>>();
11044
11045        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11046    }
11047
11048    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11049        let (worktree, relative_path) =
11050            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11051
11052        let project_path = ProjectPath {
11053            worktree_id: worktree.read(cx).id(),
11054            path: relative_path,
11055        };
11056
11057        Some(
11058            self.buffer_store()
11059                .read(cx)
11060                .get_by_path(&project_path)?
11061                .read(cx),
11062        )
11063    }
11064
11065    #[cfg(any(test, feature = "test-support"))]
11066    pub fn update_diagnostics(
11067        &mut self,
11068        server_id: LanguageServerId,
11069        diagnostics: lsp::PublishDiagnosticsParams,
11070        result_id: Option<SharedString>,
11071        source_kind: DiagnosticSourceKind,
11072        disk_based_sources: &[String],
11073        cx: &mut Context<Self>,
11074    ) -> Result<()> {
11075        self.merge_lsp_diagnostics(
11076            source_kind,
11077            vec![DocumentDiagnosticsUpdate {
11078                diagnostics,
11079                result_id,
11080                server_id,
11081                disk_based_sources: Cow::Borrowed(disk_based_sources),
11082                registration_id: None,
11083            }],
11084            |_, _, _| false,
11085            cx,
11086        )
11087    }
11088
11089    pub fn merge_lsp_diagnostics(
11090        &mut self,
11091        source_kind: DiagnosticSourceKind,
11092        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11093        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11094        cx: &mut Context<Self>,
11095    ) -> Result<()> {
11096        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11097        let updates = lsp_diagnostics
11098            .into_iter()
11099            .filter_map(|update| {
11100                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11101                Some(DocumentDiagnosticsUpdate {
11102                    diagnostics: self.lsp_to_document_diagnostics(
11103                        abs_path,
11104                        source_kind,
11105                        update.server_id,
11106                        update.diagnostics,
11107                        &update.disk_based_sources,
11108                        update.registration_id.clone(),
11109                    ),
11110                    result_id: update.result_id,
11111                    server_id: update.server_id,
11112                    disk_based_sources: update.disk_based_sources,
11113                    registration_id: update.registration_id,
11114                })
11115            })
11116            .collect();
11117        self.merge_diagnostic_entries(updates, merge, cx)?;
11118        Ok(())
11119    }
11120
11121    fn lsp_to_document_diagnostics(
11122        &mut self,
11123        document_abs_path: PathBuf,
11124        source_kind: DiagnosticSourceKind,
11125        server_id: LanguageServerId,
11126        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11127        disk_based_sources: &[String],
11128        registration_id: Option<SharedString>,
11129    ) -> DocumentDiagnostics {
11130        let mut diagnostics = Vec::default();
11131        let mut primary_diagnostic_group_ids = HashMap::default();
11132        let mut sources_by_group_id = HashMap::default();
11133        let mut supporting_diagnostics = HashMap::default();
11134
11135        let adapter = self.language_server_adapter_for_id(server_id);
11136
11137        // Ensure that primary diagnostics are always the most severe
11138        lsp_diagnostics
11139            .diagnostics
11140            .sort_by_key(|item| item.severity);
11141
11142        for diagnostic in &lsp_diagnostics.diagnostics {
11143            let source = diagnostic.source.as_ref();
11144            let range = range_from_lsp(diagnostic.range);
11145            let is_supporting = diagnostic
11146                .related_information
11147                .as_ref()
11148                .is_some_and(|infos| {
11149                    infos.iter().any(|info| {
11150                        primary_diagnostic_group_ids.contains_key(&(
11151                            source,
11152                            diagnostic.code.clone(),
11153                            range_from_lsp(info.location.range),
11154                        ))
11155                    })
11156                });
11157
11158            let is_unnecessary = diagnostic
11159                .tags
11160                .as_ref()
11161                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11162
11163            let underline = self
11164                .language_server_adapter_for_id(server_id)
11165                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11166
11167            if is_supporting {
11168                supporting_diagnostics.insert(
11169                    (source, diagnostic.code.clone(), range),
11170                    (diagnostic.severity, is_unnecessary),
11171                );
11172            } else {
11173                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11174                let is_disk_based =
11175                    source.is_some_and(|source| disk_based_sources.contains(source));
11176
11177                sources_by_group_id.insert(group_id, source);
11178                primary_diagnostic_group_ids
11179                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11180
11181                diagnostics.push(DiagnosticEntry {
11182                    range,
11183                    diagnostic: Diagnostic {
11184                        source: diagnostic.source.clone(),
11185                        source_kind,
11186                        code: diagnostic.code.clone(),
11187                        code_description: diagnostic
11188                            .code_description
11189                            .as_ref()
11190                            .and_then(|d| d.href.clone()),
11191                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11192                        markdown: adapter.as_ref().and_then(|adapter| {
11193                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11194                        }),
11195                        message: diagnostic.message.trim().to_string(),
11196                        group_id,
11197                        is_primary: true,
11198                        is_disk_based,
11199                        is_unnecessary,
11200                        underline,
11201                        data: diagnostic.data.clone(),
11202                        registration_id: registration_id.clone(),
11203                    },
11204                });
11205                if let Some(infos) = &diagnostic.related_information {
11206                    for info in infos {
11207                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11208                            let range = range_from_lsp(info.location.range);
11209                            diagnostics.push(DiagnosticEntry {
11210                                range,
11211                                diagnostic: Diagnostic {
11212                                    source: diagnostic.source.clone(),
11213                                    source_kind,
11214                                    code: diagnostic.code.clone(),
11215                                    code_description: diagnostic
11216                                        .code_description
11217                                        .as_ref()
11218                                        .and_then(|d| d.href.clone()),
11219                                    severity: DiagnosticSeverity::INFORMATION,
11220                                    markdown: adapter.as_ref().and_then(|adapter| {
11221                                        adapter.diagnostic_message_to_markdown(&info.message)
11222                                    }),
11223                                    message: info.message.trim().to_string(),
11224                                    group_id,
11225                                    is_primary: false,
11226                                    is_disk_based,
11227                                    is_unnecessary: false,
11228                                    underline,
11229                                    data: diagnostic.data.clone(),
11230                                    registration_id: registration_id.clone(),
11231                                },
11232                            });
11233                        }
11234                    }
11235                }
11236            }
11237        }
11238
11239        for entry in &mut diagnostics {
11240            let diagnostic = &mut entry.diagnostic;
11241            if !diagnostic.is_primary {
11242                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11243                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11244                    source,
11245                    diagnostic.code.clone(),
11246                    entry.range.clone(),
11247                )) {
11248                    if let Some(severity) = severity {
11249                        diagnostic.severity = severity;
11250                    }
11251                    diagnostic.is_unnecessary = is_unnecessary;
11252                }
11253            }
11254        }
11255
11256        DocumentDiagnostics {
11257            diagnostics,
11258            document_abs_path,
11259            version: lsp_diagnostics.version,
11260        }
11261    }
11262
11263    fn insert_newly_running_language_server(
11264        &mut self,
11265        adapter: Arc<CachedLspAdapter>,
11266        language_server: Arc<LanguageServer>,
11267        server_id: LanguageServerId,
11268        key: LanguageServerSeed,
11269        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11270        cx: &mut Context<Self>,
11271    ) {
11272        let Some(local) = self.as_local_mut() else {
11273            return;
11274        };
11275        // If the language server for this key doesn't match the server id, don't store the
11276        // server. Which will cause it to be dropped, killing the process
11277        if local
11278            .language_server_ids
11279            .get(&key)
11280            .map(|state| state.id != server_id)
11281            .unwrap_or(false)
11282        {
11283            return;
11284        }
11285
11286        // Update language_servers collection with Running variant of LanguageServerState
11287        // indicating that the server is up and running and ready
11288        let workspace_folders = workspace_folders.lock().clone();
11289        language_server.set_workspace_folders(workspace_folders);
11290
11291        let workspace_diagnostics_refresh_tasks = language_server
11292            .capabilities()
11293            .diagnostic_provider
11294            .and_then(|provider| {
11295                local
11296                    .language_server_dynamic_registrations
11297                    .entry(server_id)
11298                    .or_default()
11299                    .diagnostics
11300                    .entry(None)
11301                    .or_insert(provider.clone());
11302                let workspace_refresher =
11303                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11304
11305                Some((None, workspace_refresher))
11306            })
11307            .into_iter()
11308            .collect();
11309        local.language_servers.insert(
11310            server_id,
11311            LanguageServerState::Running {
11312                workspace_diagnostics_refresh_tasks,
11313                adapter: adapter.clone(),
11314                server: language_server.clone(),
11315                simulate_disk_based_diagnostics_completion: None,
11316            },
11317        );
11318        local
11319            .languages
11320            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11321        if let Some(file_ops_caps) = language_server
11322            .capabilities()
11323            .workspace
11324            .as_ref()
11325            .and_then(|ws| ws.file_operations.as_ref())
11326        {
11327            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11328            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11329            if did_rename_caps.or(will_rename_caps).is_some() {
11330                let watcher = RenamePathsWatchedForServer::default()
11331                    .with_did_rename_patterns(did_rename_caps)
11332                    .with_will_rename_patterns(will_rename_caps);
11333                local
11334                    .language_server_paths_watched_for_rename
11335                    .insert(server_id, watcher);
11336            }
11337        }
11338
11339        self.language_server_statuses.insert(
11340            server_id,
11341            LanguageServerStatus {
11342                name: language_server.name(),
11343                server_version: language_server.version(),
11344                pending_work: Default::default(),
11345                has_pending_diagnostic_updates: false,
11346                progress_tokens: Default::default(),
11347                worktree: Some(key.worktree_id),
11348                binary: Some(language_server.binary().clone()),
11349                configuration: Some(language_server.configuration().clone()),
11350                workspace_folders: language_server.workspace_folders(),
11351                process_id: language_server.process_id(),
11352            },
11353        );
11354
11355        cx.emit(LspStoreEvent::LanguageServerAdded(
11356            server_id,
11357            language_server.name(),
11358            Some(key.worktree_id),
11359        ));
11360
11361        let server_capabilities = language_server.capabilities();
11362        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11363            downstream_client
11364                .send(proto::StartLanguageServer {
11365                    project_id: *project_id,
11366                    server: Some(proto::LanguageServer {
11367                        id: server_id.to_proto(),
11368                        name: language_server.name().to_string(),
11369                        worktree_id: Some(key.worktree_id.to_proto()),
11370                    }),
11371                    capabilities: serde_json::to_string(&server_capabilities)
11372                        .expect("serializing server LSP capabilities"),
11373                })
11374                .log_err();
11375        }
11376        self.lsp_server_capabilities
11377            .insert(server_id, server_capabilities);
11378
11379        // Tell the language server about every open buffer in the worktree that matches the language.
11380        // Also check for buffers in worktrees that reused this server
11381        let mut worktrees_using_server = vec![key.worktree_id];
11382        if let Some(local) = self.as_local() {
11383            // Find all worktrees that have this server in their language server tree
11384            for (worktree_id, servers) in &local.lsp_tree.instances {
11385                if *worktree_id != key.worktree_id {
11386                    for server_map in servers.roots.values() {
11387                        if server_map
11388                            .values()
11389                            .any(|(node, _)| node.id() == Some(server_id))
11390                        {
11391                            worktrees_using_server.push(*worktree_id);
11392                        }
11393                    }
11394                }
11395            }
11396        }
11397
11398        let mut buffer_paths_registered = Vec::new();
11399        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11400            let mut lsp_adapters = HashMap::default();
11401            for buffer_handle in buffer_store.buffers() {
11402                let buffer = buffer_handle.read(cx);
11403                let file = match File::from_dyn(buffer.file()) {
11404                    Some(file) => file,
11405                    None => continue,
11406                };
11407                let language = match buffer.language() {
11408                    Some(language) => language,
11409                    None => continue,
11410                };
11411
11412                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11413                    || !lsp_adapters
11414                        .entry(language.name())
11415                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11416                        .iter()
11417                        .any(|a| a.name == key.name)
11418                {
11419                    continue;
11420                }
11421                // didOpen
11422                let file = match file.as_local() {
11423                    Some(file) => file,
11424                    None => continue,
11425                };
11426
11427                let local = self.as_local_mut().unwrap();
11428
11429                let buffer_id = buffer.remote_id();
11430                if local.registered_buffers.contains_key(&buffer_id) {
11431                    let abs_path = file.abs_path(cx);
11432                    let uri = match lsp::Uri::from_file_path(&abs_path) {
11433                        Ok(uri) => uri,
11434                        Err(()) => {
11435                            log::error!("failed to convert path to URI: {:?}", abs_path);
11436                            continue;
11437                        }
11438                    };
11439
11440                    let versions = local
11441                        .buffer_snapshots
11442                        .entry(buffer_id)
11443                        .or_default()
11444                        .entry(server_id)
11445                        .and_modify(|_| {
11446                            assert!(
11447                            false,
11448                            "There should not be an existing snapshot for a newly inserted buffer"
11449                        )
11450                        })
11451                        .or_insert_with(|| {
11452                            vec![LspBufferSnapshot {
11453                                version: 0,
11454                                snapshot: buffer.text_snapshot(),
11455                            }]
11456                        });
11457
11458                    let snapshot = versions.last().unwrap();
11459                    let version = snapshot.version;
11460                    let initial_snapshot = &snapshot.snapshot;
11461                    language_server.register_buffer(
11462                        uri,
11463                        adapter.language_id(&language.name()),
11464                        version,
11465                        initial_snapshot.text(),
11466                    );
11467                    buffer_paths_registered.push((buffer_id, abs_path));
11468                    local
11469                        .buffers_opened_in_servers
11470                        .entry(buffer_id)
11471                        .or_default()
11472                        .insert(server_id);
11473                }
11474                buffer_handle.update(cx, |buffer, cx| {
11475                    buffer.set_completion_triggers(
11476                        server_id,
11477                        language_server
11478                            .capabilities()
11479                            .completion_provider
11480                            .as_ref()
11481                            .and_then(|provider| {
11482                                provider
11483                                    .trigger_characters
11484                                    .as_ref()
11485                                    .map(|characters| characters.iter().cloned().collect())
11486                            })
11487                            .unwrap_or_default(),
11488                        cx,
11489                    )
11490                });
11491            }
11492        });
11493
11494        for (buffer_id, abs_path) in buffer_paths_registered {
11495            cx.emit(LspStoreEvent::LanguageServerUpdate {
11496                language_server_id: server_id,
11497                name: Some(adapter.name()),
11498                message: proto::update_language_server::Variant::RegisteredForBuffer(
11499                    proto::RegisteredForBuffer {
11500                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11501                        buffer_id: buffer_id.to_proto(),
11502                    },
11503                ),
11504            });
11505        }
11506
11507        cx.notify();
11508    }
11509
11510    pub fn language_servers_running_disk_based_diagnostics(
11511        &self,
11512    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11513        self.language_server_statuses
11514            .iter()
11515            .filter_map(|(id, status)| {
11516                if status.has_pending_diagnostic_updates {
11517                    Some(*id)
11518                } else {
11519                    None
11520                }
11521            })
11522    }
11523
11524    pub(crate) fn cancel_language_server_work_for_buffers(
11525        &mut self,
11526        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11527        cx: &mut Context<Self>,
11528    ) {
11529        if let Some((client, project_id)) = self.upstream_client() {
11530            let request = client.request(proto::CancelLanguageServerWork {
11531                project_id,
11532                work: Some(proto::cancel_language_server_work::Work::Buffers(
11533                    proto::cancel_language_server_work::Buffers {
11534                        buffer_ids: buffers
11535                            .into_iter()
11536                            .map(|b| b.read(cx).remote_id().to_proto())
11537                            .collect(),
11538                    },
11539                )),
11540            });
11541            cx.background_spawn(request).detach_and_log_err(cx);
11542        } else if let Some(local) = self.as_local() {
11543            let servers = buffers
11544                .into_iter()
11545                .flat_map(|buffer| {
11546                    buffer.update(cx, |buffer, cx| {
11547                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11548                    })
11549                })
11550                .collect::<HashSet<_>>();
11551            for server_id in servers {
11552                self.cancel_language_server_work(server_id, None, cx);
11553            }
11554        }
11555    }
11556
11557    pub(crate) fn cancel_language_server_work(
11558        &mut self,
11559        server_id: LanguageServerId,
11560        token_to_cancel: Option<ProgressToken>,
11561        cx: &mut Context<Self>,
11562    ) {
11563        if let Some(local) = self.as_local() {
11564            let status = self.language_server_statuses.get(&server_id);
11565            let server = local.language_servers.get(&server_id);
11566            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11567            {
11568                for (token, progress) in &status.pending_work {
11569                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11570                        && token != token_to_cancel
11571                    {
11572                        continue;
11573                    }
11574                    if progress.is_cancellable {
11575                        server
11576                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11577                                WorkDoneProgressCancelParams {
11578                                    token: token.to_lsp(),
11579                                },
11580                            )
11581                            .ok();
11582                    }
11583                }
11584            }
11585        } else if let Some((client, project_id)) = self.upstream_client() {
11586            let request = client.request(proto::CancelLanguageServerWork {
11587                project_id,
11588                work: Some(
11589                    proto::cancel_language_server_work::Work::LanguageServerWork(
11590                        proto::cancel_language_server_work::LanguageServerWork {
11591                            language_server_id: server_id.to_proto(),
11592                            token: token_to_cancel.map(|token| token.to_proto()),
11593                        },
11594                    ),
11595                ),
11596            });
11597            cx.background_spawn(request).detach_and_log_err(cx);
11598        }
11599    }
11600
11601    fn register_supplementary_language_server(
11602        &mut self,
11603        id: LanguageServerId,
11604        name: LanguageServerName,
11605        server: Arc<LanguageServer>,
11606        cx: &mut Context<Self>,
11607    ) {
11608        if let Some(local) = self.as_local_mut() {
11609            local
11610                .supplementary_language_servers
11611                .insert(id, (name.clone(), server));
11612            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11613        }
11614    }
11615
11616    fn unregister_supplementary_language_server(
11617        &mut self,
11618        id: LanguageServerId,
11619        cx: &mut Context<Self>,
11620    ) {
11621        if let Some(local) = self.as_local_mut() {
11622            local.supplementary_language_servers.remove(&id);
11623            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11624        }
11625    }
11626
11627    pub(crate) fn supplementary_language_servers(
11628        &self,
11629    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11630        self.as_local().into_iter().flat_map(|local| {
11631            local
11632                .supplementary_language_servers
11633                .iter()
11634                .map(|(id, (name, _))| (*id, name.clone()))
11635        })
11636    }
11637
11638    pub fn language_server_adapter_for_id(
11639        &self,
11640        id: LanguageServerId,
11641    ) -> Option<Arc<CachedLspAdapter>> {
11642        self.as_local()
11643            .and_then(|local| local.language_servers.get(&id))
11644            .and_then(|language_server_state| match language_server_state {
11645                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11646                _ => None,
11647            })
11648    }
11649
11650    pub(super) fn update_local_worktree_language_servers(
11651        &mut self,
11652        worktree_handle: &Entity<Worktree>,
11653        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11654        cx: &mut Context<Self>,
11655    ) {
11656        if changes.is_empty() {
11657            return;
11658        }
11659
11660        let Some(local) = self.as_local() else { return };
11661
11662        local.prettier_store.update(cx, |prettier_store, cx| {
11663            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11664        });
11665
11666        let worktree_id = worktree_handle.read(cx).id();
11667        let mut language_server_ids = local
11668            .language_server_ids
11669            .iter()
11670            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11671            .collect::<Vec<_>>();
11672        language_server_ids.sort();
11673        language_server_ids.dedup();
11674
11675        // let abs_path = worktree_handle.read(cx).abs_path();
11676        for server_id in &language_server_ids {
11677            if let Some(LanguageServerState::Running { server, .. }) =
11678                local.language_servers.get(server_id)
11679                && let Some(watched_paths) = local
11680                    .language_server_watched_paths
11681                    .get(server_id)
11682                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11683            {
11684                let params = lsp::DidChangeWatchedFilesParams {
11685                    changes: changes
11686                        .iter()
11687                        .filter_map(|(path, _, change)| {
11688                            if !watched_paths.is_match(path.as_std_path()) {
11689                                return None;
11690                            }
11691                            let typ = match change {
11692                                PathChange::Loaded => return None,
11693                                PathChange::Added => lsp::FileChangeType::CREATED,
11694                                PathChange::Removed => lsp::FileChangeType::DELETED,
11695                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11696                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11697                            };
11698                            let uri = lsp::Uri::from_file_path(
11699                                worktree_handle.read(cx).absolutize(&path),
11700                            )
11701                            .ok()?;
11702                            Some(lsp::FileEvent { uri, typ })
11703                        })
11704                        .collect(),
11705                };
11706                if !params.changes.is_empty() {
11707                    server
11708                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11709                        .ok();
11710                }
11711            }
11712        }
11713        for (path, _, _) in changes {
11714            if let Some(file_name) = path.file_name()
11715                && local.watched_manifest_filenames.contains(file_name)
11716            {
11717                self.request_workspace_config_refresh();
11718                break;
11719            }
11720        }
11721    }
11722
11723    pub fn wait_for_remote_buffer(
11724        &mut self,
11725        id: BufferId,
11726        cx: &mut Context<Self>,
11727    ) -> Task<Result<Entity<Buffer>>> {
11728        self.buffer_store.update(cx, |buffer_store, cx| {
11729            buffer_store.wait_for_remote_buffer(id, cx)
11730        })
11731    }
11732
11733    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11734        let mut result = proto::Symbol {
11735            language_server_name: symbol.language_server_name.0.to_string(),
11736            source_worktree_id: symbol.source_worktree_id.to_proto(),
11737            language_server_id: symbol.source_language_server_id.to_proto(),
11738            name: symbol.name.clone(),
11739            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11740            start: Some(proto::PointUtf16 {
11741                row: symbol.range.start.0.row,
11742                column: symbol.range.start.0.column,
11743            }),
11744            end: Some(proto::PointUtf16 {
11745                row: symbol.range.end.0.row,
11746                column: symbol.range.end.0.column,
11747            }),
11748            worktree_id: Default::default(),
11749            path: Default::default(),
11750            signature: Default::default(),
11751            container_name: symbol.container_name.clone(),
11752        };
11753        match &symbol.path {
11754            SymbolLocation::InProject(path) => {
11755                result.worktree_id = path.worktree_id.to_proto();
11756                result.path = path.path.to_proto();
11757            }
11758            SymbolLocation::OutsideProject {
11759                abs_path,
11760                signature,
11761            } => {
11762                result.path = abs_path.to_string_lossy().into_owned();
11763                result.signature = signature.to_vec();
11764            }
11765        }
11766        result
11767    }
11768
11769    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11770        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11771        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11772        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11773
11774        let path = if serialized_symbol.signature.is_empty() {
11775            SymbolLocation::InProject(ProjectPath {
11776                worktree_id,
11777                path: RelPath::from_proto(&serialized_symbol.path)
11778                    .context("invalid symbol path")?,
11779            })
11780        } else {
11781            SymbolLocation::OutsideProject {
11782                abs_path: Path::new(&serialized_symbol.path).into(),
11783                signature: serialized_symbol
11784                    .signature
11785                    .try_into()
11786                    .map_err(|_| anyhow!("invalid signature"))?,
11787            }
11788        };
11789
11790        let start = serialized_symbol.start.context("invalid start")?;
11791        let end = serialized_symbol.end.context("invalid end")?;
11792        Ok(CoreSymbol {
11793            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11794            source_worktree_id,
11795            source_language_server_id: LanguageServerId::from_proto(
11796                serialized_symbol.language_server_id,
11797            ),
11798            path,
11799            name: serialized_symbol.name,
11800            range: Unclipped(PointUtf16::new(start.row, start.column))
11801                ..Unclipped(PointUtf16::new(end.row, end.column)),
11802            kind,
11803            container_name: serialized_symbol.container_name,
11804        })
11805    }
11806
11807    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11808        let mut serialized_completion = proto::Completion {
11809            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11810            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11811            new_text: completion.new_text.clone(),
11812            ..proto::Completion::default()
11813        };
11814        match &completion.source {
11815            CompletionSource::Lsp {
11816                insert_range,
11817                server_id,
11818                lsp_completion,
11819                lsp_defaults,
11820                resolved,
11821            } => {
11822                let (old_insert_start, old_insert_end) = insert_range
11823                    .as_ref()
11824                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11825                    .unzip();
11826
11827                serialized_completion.old_insert_start = old_insert_start;
11828                serialized_completion.old_insert_end = old_insert_end;
11829                serialized_completion.source = proto::completion::Source::Lsp as i32;
11830                serialized_completion.server_id = server_id.0 as u64;
11831                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11832                serialized_completion.lsp_defaults = lsp_defaults
11833                    .as_deref()
11834                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11835                serialized_completion.resolved = *resolved;
11836            }
11837            CompletionSource::BufferWord {
11838                word_range,
11839                resolved,
11840            } => {
11841                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11842                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11843                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11844                serialized_completion.resolved = *resolved;
11845            }
11846            CompletionSource::Custom => {
11847                serialized_completion.source = proto::completion::Source::Custom as i32;
11848                serialized_completion.resolved = true;
11849            }
11850            CompletionSource::Dap { sort_text } => {
11851                serialized_completion.source = proto::completion::Source::Dap as i32;
11852                serialized_completion.sort_text = Some(sort_text.clone());
11853            }
11854        }
11855
11856        serialized_completion
11857    }
11858
11859    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11860        let old_replace_start = completion
11861            .old_replace_start
11862            .and_then(deserialize_anchor)
11863            .context("invalid old start")?;
11864        let old_replace_end = completion
11865            .old_replace_end
11866            .and_then(deserialize_anchor)
11867            .context("invalid old end")?;
11868        let insert_range = {
11869            match completion.old_insert_start.zip(completion.old_insert_end) {
11870                Some((start, end)) => {
11871                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11872                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11873                    Some(start..end)
11874                }
11875                None => None,
11876            }
11877        };
11878        Ok(CoreCompletion {
11879            replace_range: old_replace_start..old_replace_end,
11880            new_text: completion.new_text,
11881            source: match proto::completion::Source::from_i32(completion.source) {
11882                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11883                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11884                    insert_range,
11885                    server_id: LanguageServerId::from_proto(completion.server_id),
11886                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11887                    lsp_defaults: completion
11888                        .lsp_defaults
11889                        .as_deref()
11890                        .map(serde_json::from_slice)
11891                        .transpose()?,
11892                    resolved: completion.resolved,
11893                },
11894                Some(proto::completion::Source::BufferWord) => {
11895                    let word_range = completion
11896                        .buffer_word_start
11897                        .and_then(deserialize_anchor)
11898                        .context("invalid buffer word start")?
11899                        ..completion
11900                            .buffer_word_end
11901                            .and_then(deserialize_anchor)
11902                            .context("invalid buffer word end")?;
11903                    CompletionSource::BufferWord {
11904                        word_range,
11905                        resolved: completion.resolved,
11906                    }
11907                }
11908                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11909                    sort_text: completion
11910                        .sort_text
11911                        .context("expected sort text to exist")?,
11912                },
11913                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11914            },
11915        })
11916    }
11917
11918    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11919        let (kind, lsp_action) = match &action.lsp_action {
11920            LspAction::Action(code_action) => (
11921                proto::code_action::Kind::Action as i32,
11922                serde_json::to_vec(code_action).unwrap(),
11923            ),
11924            LspAction::Command(command) => (
11925                proto::code_action::Kind::Command as i32,
11926                serde_json::to_vec(command).unwrap(),
11927            ),
11928            LspAction::CodeLens(code_lens) => (
11929                proto::code_action::Kind::CodeLens as i32,
11930                serde_json::to_vec(code_lens).unwrap(),
11931            ),
11932        };
11933
11934        proto::CodeAction {
11935            server_id: action.server_id.0 as u64,
11936            start: Some(serialize_anchor(&action.range.start)),
11937            end: Some(serialize_anchor(&action.range.end)),
11938            lsp_action,
11939            kind,
11940            resolved: action.resolved,
11941        }
11942    }
11943
11944    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11945        let start = action
11946            .start
11947            .and_then(deserialize_anchor)
11948            .context("invalid start")?;
11949        let end = action
11950            .end
11951            .and_then(deserialize_anchor)
11952            .context("invalid end")?;
11953        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11954            Some(proto::code_action::Kind::Action) => {
11955                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11956            }
11957            Some(proto::code_action::Kind::Command) => {
11958                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11959            }
11960            Some(proto::code_action::Kind::CodeLens) => {
11961                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11962            }
11963            None => anyhow::bail!("Unknown action kind {}", action.kind),
11964        };
11965        Ok(CodeAction {
11966            server_id: LanguageServerId(action.server_id as usize),
11967            range: start..end,
11968            resolved: action.resolved,
11969            lsp_action,
11970        })
11971    }
11972
11973    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11974        match &formatting_result {
11975            Ok(_) => self.last_formatting_failure = None,
11976            Err(error) => {
11977                let error_string = format!("{error:#}");
11978                log::error!("Formatting failed: {error_string}");
11979                self.last_formatting_failure
11980                    .replace(error_string.lines().join(" "));
11981            }
11982        }
11983    }
11984
11985    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11986        self.lsp_server_capabilities.remove(&for_server);
11987        self.semantic_token_config.remove_server_data(for_server);
11988        for lsp_data in self.lsp_data.values_mut() {
11989            lsp_data.remove_server_data(for_server);
11990        }
11991        if let Some(local) = self.as_local_mut() {
11992            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11993            local
11994                .workspace_pull_diagnostics_result_ids
11995                .remove(&for_server);
11996            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11997                buffer_servers.remove(&for_server);
11998            }
11999        }
12000    }
12001
12002    pub fn result_id_for_buffer_pull(
12003        &self,
12004        server_id: LanguageServerId,
12005        buffer_id: BufferId,
12006        registration_id: &Option<SharedString>,
12007        cx: &App,
12008    ) -> Option<SharedString> {
12009        let abs_path = self
12010            .buffer_store
12011            .read(cx)
12012            .get(buffer_id)
12013            .and_then(|b| File::from_dyn(b.read(cx).file()))
12014            .map(|f| f.abs_path(cx))?;
12015        self.as_local()?
12016            .buffer_pull_diagnostics_result_ids
12017            .get(&server_id)?
12018            .get(registration_id)?
12019            .get(&abs_path)?
12020            .clone()
12021    }
12022
12023    /// Gets all result_ids for a workspace diagnostics pull request.
12024    /// 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.
12025    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12026    pub fn result_ids_for_workspace_refresh(
12027        &self,
12028        server_id: LanguageServerId,
12029        registration_id: &Option<SharedString>,
12030    ) -> HashMap<PathBuf, SharedString> {
12031        let Some(local) = self.as_local() else {
12032            return HashMap::default();
12033        };
12034        local
12035            .workspace_pull_diagnostics_result_ids
12036            .get(&server_id)
12037            .into_iter()
12038            .filter_map(|diagnostics| diagnostics.get(registration_id))
12039            .flatten()
12040            .filter_map(|(abs_path, result_id)| {
12041                let result_id = local
12042                    .buffer_pull_diagnostics_result_ids
12043                    .get(&server_id)
12044                    .and_then(|buffer_ids_result_ids| {
12045                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12046                    })
12047                    .cloned()
12048                    .flatten()
12049                    .or_else(|| result_id.clone())?;
12050                Some((abs_path.clone(), result_id))
12051            })
12052            .collect()
12053    }
12054
12055    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12056        if let Some(LanguageServerState::Running {
12057            workspace_diagnostics_refresh_tasks,
12058            ..
12059        }) = self
12060            .as_local_mut()
12061            .and_then(|local| local.language_servers.get_mut(&server_id))
12062        {
12063            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12064                diagnostics.refresh_tx.try_send(()).ok();
12065            }
12066        }
12067    }
12068
12069    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12070    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12071    /// which requires refreshing both workspace and document diagnostics.
12072    pub fn pull_document_diagnostics_for_server(
12073        &mut self,
12074        server_id: LanguageServerId,
12075        source_buffer_id: Option<BufferId>,
12076        cx: &mut Context<Self>,
12077    ) -> Shared<Task<()>> {
12078        let Some(local) = self.as_local_mut() else {
12079            return Task::ready(()).shared();
12080        };
12081        let mut buffers_to_refresh = HashSet::default();
12082        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12083            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12084                buffers_to_refresh.insert(*buffer_id);
12085            }
12086        }
12087
12088        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12089    }
12090
12091    pub fn pull_document_diagnostics_for_buffer_edit(
12092        &mut self,
12093        buffer_id: BufferId,
12094        cx: &mut Context<Self>,
12095    ) {
12096        let Some(local) = self.as_local_mut() else {
12097            return;
12098        };
12099        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12100        else {
12101            return;
12102        };
12103        for server_id in languages_servers {
12104            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12105        }
12106    }
12107
12108    fn apply_workspace_diagnostic_report(
12109        &mut self,
12110        server_id: LanguageServerId,
12111        report: lsp::WorkspaceDiagnosticReportResult,
12112        registration_id: Option<SharedString>,
12113        cx: &mut Context<Self>,
12114    ) {
12115        let mut workspace_diagnostics =
12116            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12117                report,
12118                server_id,
12119                registration_id,
12120            );
12121        workspace_diagnostics.retain(|d| match &d.diagnostics {
12122            LspPullDiagnostics::Response {
12123                server_id,
12124                registration_id,
12125                ..
12126            } => self.diagnostic_registration_exists(*server_id, registration_id),
12127            LspPullDiagnostics::Default => false,
12128        });
12129        let mut unchanged_buffers = HashMap::default();
12130        let workspace_diagnostics_updates = workspace_diagnostics
12131            .into_iter()
12132            .filter_map(
12133                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12134                    LspPullDiagnostics::Response {
12135                        server_id,
12136                        uri,
12137                        diagnostics,
12138                        registration_id,
12139                    } => Some((
12140                        server_id,
12141                        uri,
12142                        diagnostics,
12143                        workspace_diagnostics.version,
12144                        registration_id,
12145                    )),
12146                    LspPullDiagnostics::Default => None,
12147                },
12148            )
12149            .fold(
12150                HashMap::default(),
12151                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12152                    let (result_id, diagnostics) = match diagnostics {
12153                        PulledDiagnostics::Unchanged { result_id } => {
12154                            unchanged_buffers
12155                                .entry(new_registration_id.clone())
12156                                .or_insert_with(HashSet::default)
12157                                .insert(uri.clone());
12158                            (Some(result_id), Vec::new())
12159                        }
12160                        PulledDiagnostics::Changed {
12161                            result_id,
12162                            diagnostics,
12163                        } => (result_id, diagnostics),
12164                    };
12165                    let disk_based_sources = Cow::Owned(
12166                        self.language_server_adapter_for_id(server_id)
12167                            .as_ref()
12168                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12169                            .unwrap_or(&[])
12170                            .to_vec(),
12171                    );
12172
12173                    let Some(abs_path) = uri.to_file_path().ok() else {
12174                        return acc;
12175                    };
12176                    let Some((worktree, relative_path)) =
12177                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12178                    else {
12179                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12180                        return acc;
12181                    };
12182                    let worktree_id = worktree.read(cx).id();
12183                    let project_path = ProjectPath {
12184                        worktree_id,
12185                        path: relative_path,
12186                    };
12187                    if let Some(local_lsp_store) = self.as_local_mut() {
12188                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12189                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12190                    }
12191                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12192                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12193                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12194                        acc.entry(server_id)
12195                            .or_insert_with(HashMap::default)
12196                            .entry(new_registration_id.clone())
12197                            .or_insert_with(Vec::new)
12198                            .push(DocumentDiagnosticsUpdate {
12199                                server_id,
12200                                diagnostics: lsp::PublishDiagnosticsParams {
12201                                    uri,
12202                                    diagnostics,
12203                                    version,
12204                                },
12205                                result_id: result_id.map(SharedString::new),
12206                                disk_based_sources,
12207                                registration_id: new_registration_id,
12208                            });
12209                    }
12210                    acc
12211                },
12212            );
12213
12214        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12215            for (registration_id, diagnostic_updates) in diagnostic_updates {
12216                self.merge_lsp_diagnostics(
12217                    DiagnosticSourceKind::Pulled,
12218                    diagnostic_updates,
12219                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12220                        DiagnosticSourceKind::Pulled => {
12221                            old_diagnostic.registration_id != registration_id
12222                                || unchanged_buffers
12223                                    .get(&old_diagnostic.registration_id)
12224                                    .is_some_and(|unchanged_buffers| {
12225                                        unchanged_buffers.contains(&document_uri)
12226                                    })
12227                        }
12228                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12229                    },
12230                    cx,
12231                )
12232                .log_err();
12233            }
12234        }
12235    }
12236
12237    fn register_server_capabilities(
12238        &mut self,
12239        server_id: LanguageServerId,
12240        params: lsp::RegistrationParams,
12241        cx: &mut Context<Self>,
12242    ) -> anyhow::Result<()> {
12243        let server = self
12244            .language_server_for_id(server_id)
12245            .with_context(|| format!("no server {server_id} found"))?;
12246        for reg in params.registrations {
12247            match reg.method.as_str() {
12248                "workspace/didChangeWatchedFiles" => {
12249                    if let Some(options) = reg.register_options {
12250                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12251                            let caps = serde_json::from_value(options)?;
12252                            local_lsp_store
12253                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12254                            true
12255                        } else {
12256                            false
12257                        };
12258                        if notify {
12259                            notify_server_capabilities_updated(&server, cx);
12260                        }
12261                    }
12262                }
12263                "workspace/didChangeConfiguration" => {
12264                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12265                }
12266                "workspace/didChangeWorkspaceFolders" => {
12267                    // In this case register options is an empty object, we can ignore it
12268                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12269                        supported: Some(true),
12270                        change_notifications: Some(OneOf::Right(reg.id)),
12271                    };
12272                    server.update_capabilities(|capabilities| {
12273                        capabilities
12274                            .workspace
12275                            .get_or_insert_default()
12276                            .workspace_folders = Some(caps);
12277                    });
12278                    notify_server_capabilities_updated(&server, cx);
12279                }
12280                "workspace/symbol" => {
12281                    let options = parse_register_capabilities(reg)?;
12282                    server.update_capabilities(|capabilities| {
12283                        capabilities.workspace_symbol_provider = Some(options);
12284                    });
12285                    notify_server_capabilities_updated(&server, cx);
12286                }
12287                "workspace/fileOperations" => {
12288                    if let Some(options) = reg.register_options {
12289                        let caps = serde_json::from_value(options)?;
12290                        server.update_capabilities(|capabilities| {
12291                            capabilities
12292                                .workspace
12293                                .get_or_insert_default()
12294                                .file_operations = Some(caps);
12295                        });
12296                        notify_server_capabilities_updated(&server, cx);
12297                    }
12298                }
12299                "workspace/executeCommand" => {
12300                    if let Some(options) = reg.register_options {
12301                        let options = serde_json::from_value(options)?;
12302                        server.update_capabilities(|capabilities| {
12303                            capabilities.execute_command_provider = Some(options);
12304                        });
12305                        notify_server_capabilities_updated(&server, cx);
12306                    }
12307                }
12308                "textDocument/rangeFormatting" => {
12309                    let options = parse_register_capabilities(reg)?;
12310                    server.update_capabilities(|capabilities| {
12311                        capabilities.document_range_formatting_provider = Some(options);
12312                    });
12313                    notify_server_capabilities_updated(&server, cx);
12314                }
12315                "textDocument/onTypeFormatting" => {
12316                    if let Some(options) = reg
12317                        .register_options
12318                        .map(serde_json::from_value)
12319                        .transpose()?
12320                    {
12321                        server.update_capabilities(|capabilities| {
12322                            capabilities.document_on_type_formatting_provider = Some(options);
12323                        });
12324                        notify_server_capabilities_updated(&server, cx);
12325                    }
12326                }
12327                "textDocument/formatting" => {
12328                    let options = parse_register_capabilities(reg)?;
12329                    server.update_capabilities(|capabilities| {
12330                        capabilities.document_formatting_provider = Some(options);
12331                    });
12332                    notify_server_capabilities_updated(&server, cx);
12333                }
12334                "textDocument/rename" => {
12335                    let options = parse_register_capabilities(reg)?;
12336                    server.update_capabilities(|capabilities| {
12337                        capabilities.rename_provider = Some(options);
12338                    });
12339                    notify_server_capabilities_updated(&server, cx);
12340                }
12341                "textDocument/inlayHint" => {
12342                    let options = parse_register_capabilities(reg)?;
12343                    server.update_capabilities(|capabilities| {
12344                        capabilities.inlay_hint_provider = Some(options);
12345                    });
12346                    notify_server_capabilities_updated(&server, cx);
12347                }
12348                "textDocument/documentSymbol" => {
12349                    let options = parse_register_capabilities(reg)?;
12350                    server.update_capabilities(|capabilities| {
12351                        capabilities.document_symbol_provider = Some(options);
12352                    });
12353                    notify_server_capabilities_updated(&server, cx);
12354                }
12355                "textDocument/codeAction" => {
12356                    let options = parse_register_capabilities(reg)?;
12357                    let provider = match options {
12358                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12359                        OneOf::Right(caps) => caps,
12360                    };
12361                    server.update_capabilities(|capabilities| {
12362                        capabilities.code_action_provider = Some(provider);
12363                    });
12364                    notify_server_capabilities_updated(&server, cx);
12365                }
12366                "textDocument/definition" => {
12367                    let options = parse_register_capabilities(reg)?;
12368                    server.update_capabilities(|capabilities| {
12369                        capabilities.definition_provider = Some(options);
12370                    });
12371                    notify_server_capabilities_updated(&server, cx);
12372                }
12373                "textDocument/completion" => {
12374                    if let Some(caps) = reg
12375                        .register_options
12376                        .map(serde_json::from_value::<CompletionOptions>)
12377                        .transpose()?
12378                    {
12379                        server.update_capabilities(|capabilities| {
12380                            capabilities.completion_provider = Some(caps.clone());
12381                        });
12382
12383                        if let Some(local) = self.as_local() {
12384                            let mut buffers_with_language_server = Vec::new();
12385                            for handle in self.buffer_store.read(cx).buffers() {
12386                                let buffer_id = handle.read(cx).remote_id();
12387                                if local
12388                                    .buffers_opened_in_servers
12389                                    .get(&buffer_id)
12390                                    .filter(|s| s.contains(&server_id))
12391                                    .is_some()
12392                                {
12393                                    buffers_with_language_server.push(handle);
12394                                }
12395                            }
12396                            let triggers = caps
12397                                .trigger_characters
12398                                .unwrap_or_default()
12399                                .into_iter()
12400                                .collect::<BTreeSet<_>>();
12401                            for handle in buffers_with_language_server {
12402                                let triggers = triggers.clone();
12403                                let _ = handle.update(cx, move |buffer, cx| {
12404                                    buffer.set_completion_triggers(server_id, triggers, cx);
12405                                });
12406                            }
12407                        }
12408                        notify_server_capabilities_updated(&server, cx);
12409                    }
12410                }
12411                "textDocument/hover" => {
12412                    let options = parse_register_capabilities(reg)?;
12413                    let provider = match options {
12414                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12415                        OneOf::Right(caps) => caps,
12416                    };
12417                    server.update_capabilities(|capabilities| {
12418                        capabilities.hover_provider = Some(provider);
12419                    });
12420                    notify_server_capabilities_updated(&server, cx);
12421                }
12422                "textDocument/signatureHelp" => {
12423                    if let Some(caps) = reg
12424                        .register_options
12425                        .map(serde_json::from_value)
12426                        .transpose()?
12427                    {
12428                        server.update_capabilities(|capabilities| {
12429                            capabilities.signature_help_provider = Some(caps);
12430                        });
12431                        notify_server_capabilities_updated(&server, cx);
12432                    }
12433                }
12434                "textDocument/didChange" => {
12435                    if let Some(sync_kind) = reg
12436                        .register_options
12437                        .and_then(|opts| opts.get("syncKind").cloned())
12438                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12439                        .transpose()?
12440                    {
12441                        server.update_capabilities(|capabilities| {
12442                            let mut sync_options =
12443                                Self::take_text_document_sync_options(capabilities);
12444                            sync_options.change = Some(sync_kind);
12445                            capabilities.text_document_sync =
12446                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12447                        });
12448                        notify_server_capabilities_updated(&server, cx);
12449                    }
12450                }
12451                "textDocument/didSave" => {
12452                    if let Some(include_text) = reg
12453                        .register_options
12454                        .map(|opts| {
12455                            let transpose = opts
12456                                .get("includeText")
12457                                .cloned()
12458                                .map(serde_json::from_value::<Option<bool>>)
12459                                .transpose();
12460                            match transpose {
12461                                Ok(value) => Ok(value.flatten()),
12462                                Err(e) => Err(e),
12463                            }
12464                        })
12465                        .transpose()?
12466                    {
12467                        server.update_capabilities(|capabilities| {
12468                            let mut sync_options =
12469                                Self::take_text_document_sync_options(capabilities);
12470                            sync_options.save =
12471                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12472                                    include_text,
12473                                }));
12474                            capabilities.text_document_sync =
12475                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12476                        });
12477                        notify_server_capabilities_updated(&server, cx);
12478                    }
12479                }
12480                "textDocument/codeLens" => {
12481                    if let Some(caps) = reg
12482                        .register_options
12483                        .map(serde_json::from_value)
12484                        .transpose()?
12485                    {
12486                        server.update_capabilities(|capabilities| {
12487                            capabilities.code_lens_provider = Some(caps);
12488                        });
12489                        notify_server_capabilities_updated(&server, cx);
12490                    }
12491                }
12492                "textDocument/diagnostic" => {
12493                    if let Some(caps) = reg
12494                        .register_options
12495                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12496                        .transpose()?
12497                    {
12498                        let local = self
12499                            .as_local_mut()
12500                            .context("Expected LSP Store to be local")?;
12501                        let state = local
12502                            .language_servers
12503                            .get_mut(&server_id)
12504                            .context("Could not obtain Language Servers state")?;
12505                        local
12506                            .language_server_dynamic_registrations
12507                            .entry(server_id)
12508                            .or_default()
12509                            .diagnostics
12510                            .insert(Some(reg.id.clone()), caps.clone());
12511
12512                        let supports_workspace_diagnostics =
12513                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12514                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12515                                    diagnostic_options.workspace_diagnostics
12516                                }
12517                                DiagnosticServerCapabilities::RegistrationOptions(
12518                                    diagnostic_registration_options,
12519                                ) => {
12520                                    diagnostic_registration_options
12521                                        .diagnostic_options
12522                                        .workspace_diagnostics
12523                                }
12524                            };
12525
12526                        if supports_workspace_diagnostics(&caps) {
12527                            if let LanguageServerState::Running {
12528                                workspace_diagnostics_refresh_tasks,
12529                                ..
12530                            } = state
12531                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12532                                    Some(reg.id.clone()),
12533                                    caps.clone(),
12534                                    server.clone(),
12535                                    cx,
12536                                )
12537                            {
12538                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12539                            }
12540                        }
12541
12542                        server.update_capabilities(|capabilities| {
12543                            capabilities.diagnostic_provider = Some(caps);
12544                        });
12545
12546                        notify_server_capabilities_updated(&server, cx);
12547
12548                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12549                    }
12550                }
12551                "textDocument/documentColor" => {
12552                    let options = parse_register_capabilities(reg)?;
12553                    let provider = match options {
12554                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12555                        OneOf::Right(caps) => caps,
12556                    };
12557                    server.update_capabilities(|capabilities| {
12558                        capabilities.color_provider = Some(provider);
12559                    });
12560                    notify_server_capabilities_updated(&server, cx);
12561                }
12562                "textDocument/foldingRange" => {
12563                    let options = parse_register_capabilities(reg)?;
12564                    let provider = match options {
12565                        OneOf::Left(value) => lsp::FoldingRangeProviderCapability::Simple(value),
12566                        OneOf::Right(caps) => caps,
12567                    };
12568                    server.update_capabilities(|capabilities| {
12569                        capabilities.folding_range_provider = Some(provider);
12570                    });
12571                    notify_server_capabilities_updated(&server, cx);
12572                }
12573                _ => log::warn!("unhandled capability registration: {reg:?}"),
12574            }
12575        }
12576
12577        Ok(())
12578    }
12579
12580    fn unregister_server_capabilities(
12581        &mut self,
12582        server_id: LanguageServerId,
12583        params: lsp::UnregistrationParams,
12584        cx: &mut Context<Self>,
12585    ) -> anyhow::Result<()> {
12586        let server = self
12587            .language_server_for_id(server_id)
12588            .with_context(|| format!("no server {server_id} found"))?;
12589        for unreg in params.unregisterations.iter() {
12590            match unreg.method.as_str() {
12591                "workspace/didChangeWatchedFiles" => {
12592                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12593                        local_lsp_store
12594                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12595                        true
12596                    } else {
12597                        false
12598                    };
12599                    if notify {
12600                        notify_server_capabilities_updated(&server, cx);
12601                    }
12602                }
12603                "workspace/didChangeConfiguration" => {
12604                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12605                }
12606                "workspace/didChangeWorkspaceFolders" => {
12607                    server.update_capabilities(|capabilities| {
12608                        capabilities
12609                            .workspace
12610                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12611                                workspace_folders: None,
12612                                file_operations: None,
12613                            })
12614                            .workspace_folders = None;
12615                    });
12616                    notify_server_capabilities_updated(&server, cx);
12617                }
12618                "workspace/symbol" => {
12619                    server.update_capabilities(|capabilities| {
12620                        capabilities.workspace_symbol_provider = None
12621                    });
12622                    notify_server_capabilities_updated(&server, cx);
12623                }
12624                "workspace/fileOperations" => {
12625                    server.update_capabilities(|capabilities| {
12626                        capabilities
12627                            .workspace
12628                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12629                                workspace_folders: None,
12630                                file_operations: None,
12631                            })
12632                            .file_operations = None;
12633                    });
12634                    notify_server_capabilities_updated(&server, cx);
12635                }
12636                "workspace/executeCommand" => {
12637                    server.update_capabilities(|capabilities| {
12638                        capabilities.execute_command_provider = None;
12639                    });
12640                    notify_server_capabilities_updated(&server, cx);
12641                }
12642                "textDocument/rangeFormatting" => {
12643                    server.update_capabilities(|capabilities| {
12644                        capabilities.document_range_formatting_provider = None
12645                    });
12646                    notify_server_capabilities_updated(&server, cx);
12647                }
12648                "textDocument/onTypeFormatting" => {
12649                    server.update_capabilities(|capabilities| {
12650                        capabilities.document_on_type_formatting_provider = None;
12651                    });
12652                    notify_server_capabilities_updated(&server, cx);
12653                }
12654                "textDocument/formatting" => {
12655                    server.update_capabilities(|capabilities| {
12656                        capabilities.document_formatting_provider = None;
12657                    });
12658                    notify_server_capabilities_updated(&server, cx);
12659                }
12660                "textDocument/rename" => {
12661                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12662                    notify_server_capabilities_updated(&server, cx);
12663                }
12664                "textDocument/codeAction" => {
12665                    server.update_capabilities(|capabilities| {
12666                        capabilities.code_action_provider = None;
12667                    });
12668                    notify_server_capabilities_updated(&server, cx);
12669                }
12670                "textDocument/definition" => {
12671                    server.update_capabilities(|capabilities| {
12672                        capabilities.definition_provider = None;
12673                    });
12674                    notify_server_capabilities_updated(&server, cx);
12675                }
12676                "textDocument/completion" => {
12677                    server.update_capabilities(|capabilities| {
12678                        capabilities.completion_provider = None;
12679                    });
12680                    notify_server_capabilities_updated(&server, cx);
12681                }
12682                "textDocument/hover" => {
12683                    server.update_capabilities(|capabilities| {
12684                        capabilities.hover_provider = None;
12685                    });
12686                    notify_server_capabilities_updated(&server, cx);
12687                }
12688                "textDocument/signatureHelp" => {
12689                    server.update_capabilities(|capabilities| {
12690                        capabilities.signature_help_provider = None;
12691                    });
12692                    notify_server_capabilities_updated(&server, cx);
12693                }
12694                "textDocument/didChange" => {
12695                    server.update_capabilities(|capabilities| {
12696                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12697                        sync_options.change = None;
12698                        capabilities.text_document_sync =
12699                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12700                    });
12701                    notify_server_capabilities_updated(&server, cx);
12702                }
12703                "textDocument/didSave" => {
12704                    server.update_capabilities(|capabilities| {
12705                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12706                        sync_options.save = None;
12707                        capabilities.text_document_sync =
12708                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12709                    });
12710                    notify_server_capabilities_updated(&server, cx);
12711                }
12712                "textDocument/codeLens" => {
12713                    server.update_capabilities(|capabilities| {
12714                        capabilities.code_lens_provider = None;
12715                    });
12716                    notify_server_capabilities_updated(&server, cx);
12717                }
12718                "textDocument/diagnostic" => {
12719                    let local = self
12720                        .as_local_mut()
12721                        .context("Expected LSP Store to be local")?;
12722
12723                    let state = local
12724                        .language_servers
12725                        .get_mut(&server_id)
12726                        .context("Could not obtain Language Servers state")?;
12727                    let registrations = local
12728                        .language_server_dynamic_registrations
12729                        .get_mut(&server_id)
12730                        .with_context(|| {
12731                            format!("Expected dynamic registration to exist for server {server_id}")
12732                        })?;
12733                    registrations.diagnostics
12734                        .remove(&Some(unreg.id.clone()))
12735                        .with_context(|| format!(
12736                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12737                            unreg.id)
12738                        )?;
12739                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12740
12741                    if let LanguageServerState::Running {
12742                        workspace_diagnostics_refresh_tasks,
12743                        ..
12744                    } = state
12745                    {
12746                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12747                    }
12748
12749                    self.clear_unregistered_diagnostics(
12750                        server_id,
12751                        SharedString::from(unreg.id.clone()),
12752                        cx,
12753                    )?;
12754
12755                    if removed_last_diagnostic_provider {
12756                        server.update_capabilities(|capabilities| {
12757                            debug_assert!(capabilities.diagnostic_provider.is_some());
12758                            capabilities.diagnostic_provider = None;
12759                        });
12760                    }
12761
12762                    notify_server_capabilities_updated(&server, cx);
12763                }
12764                "textDocument/documentColor" => {
12765                    server.update_capabilities(|capabilities| {
12766                        capabilities.color_provider = None;
12767                    });
12768                    notify_server_capabilities_updated(&server, cx);
12769                }
12770                "textDocument/foldingRange" => {
12771                    server.update_capabilities(|capabilities| {
12772                        capabilities.folding_range_provider = None;
12773                    });
12774                    notify_server_capabilities_updated(&server, cx);
12775                }
12776                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12777            }
12778        }
12779
12780        Ok(())
12781    }
12782
12783    fn clear_unregistered_diagnostics(
12784        &mut self,
12785        server_id: LanguageServerId,
12786        cleared_registration_id: SharedString,
12787        cx: &mut Context<Self>,
12788    ) -> anyhow::Result<()> {
12789        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12790
12791        self.buffer_store.update(cx, |buffer_store, cx| {
12792            for buffer_handle in buffer_store.buffers() {
12793                let buffer = buffer_handle.read(cx);
12794                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12795                let Some(abs_path) = abs_path else {
12796                    continue;
12797                };
12798                affected_abs_paths.insert(abs_path);
12799            }
12800        });
12801
12802        let local = self.as_local().context("Expected LSP Store to be local")?;
12803        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12804            let Some(worktree) = self
12805                .worktree_store
12806                .read(cx)
12807                .worktree_for_id(*worktree_id, cx)
12808            else {
12809                continue;
12810            };
12811
12812            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
12813                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
12814                    let has_matching_registration =
12815                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
12816                            entry.diagnostic.registration_id.as_ref()
12817                                == Some(&cleared_registration_id)
12818                        });
12819                    if has_matching_registration {
12820                        let abs_path = worktree.read(cx).absolutize(rel_path);
12821                        affected_abs_paths.insert(abs_path);
12822                    }
12823                }
12824            }
12825        }
12826
12827        if affected_abs_paths.is_empty() {
12828            return Ok(());
12829        }
12830
12831        // Send a fake diagnostic update which clears the state for the registration ID
12832        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
12833            affected_abs_paths
12834                .into_iter()
12835                .map(|abs_path| DocumentDiagnosticsUpdate {
12836                    diagnostics: DocumentDiagnostics {
12837                        diagnostics: Vec::new(),
12838                        document_abs_path: abs_path,
12839                        version: None,
12840                    },
12841                    result_id: None,
12842                    registration_id: Some(cleared_registration_id.clone()),
12843                    server_id,
12844                    disk_based_sources: Cow::Borrowed(&[]),
12845                })
12846                .collect();
12847
12848        let merge_registration_id = cleared_registration_id.clone();
12849        self.merge_diagnostic_entries(
12850            clears,
12851            move |_, diagnostic, _| {
12852                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
12853                    diagnostic.registration_id != Some(merge_registration_id.clone())
12854                } else {
12855                    true
12856                }
12857            },
12858            cx,
12859        )?;
12860
12861        Ok(())
12862    }
12863
12864    async fn deduplicate_range_based_lsp_requests<T>(
12865        lsp_store: &Entity<Self>,
12866        server_id: Option<LanguageServerId>,
12867        lsp_request_id: LspRequestId,
12868        proto_request: &T::ProtoRequest,
12869        range: Range<Anchor>,
12870        cx: &mut AsyncApp,
12871    ) -> Result<()>
12872    where
12873        T: LspCommand,
12874        T::ProtoRequest: proto::LspRequestMessage,
12875    {
12876        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12877        let version = deserialize_version(proto_request.buffer_version());
12878        let buffer = lsp_store.update(cx, |this, cx| {
12879            this.buffer_store.read(cx).get_existing(buffer_id)
12880        })?;
12881        buffer
12882            .update(cx, |buffer, _| buffer.wait_for_version(version))
12883            .await?;
12884        lsp_store.update(cx, |lsp_store, cx| {
12885            let buffer_snapshot = buffer.read(cx).snapshot();
12886            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12887            let chunks_queried_for = lsp_data
12888                .inlay_hints
12889                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
12890                .collect::<Vec<_>>();
12891            match chunks_queried_for.as_slice() {
12892                &[chunk] => {
12893                    let key = LspKey {
12894                        request_type: TypeId::of::<T>(),
12895                        server_queried: server_id,
12896                    };
12897                    let previous_request = lsp_data
12898                        .chunk_lsp_requests
12899                        .entry(key)
12900                        .or_default()
12901                        .insert(chunk, lsp_request_id);
12902                    if let Some((previous_request, running_requests)) =
12903                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12904                    {
12905                        running_requests.remove(&previous_request);
12906                    }
12907                }
12908                _ambiguous_chunks => {
12909                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12910                    // there, a buffer version-based check will be performed and outdated requests discarded.
12911                }
12912            }
12913            anyhow::Ok(())
12914        })?;
12915
12916        Ok(())
12917    }
12918
12919    async fn query_lsp_locally<T>(
12920        lsp_store: Entity<Self>,
12921        for_server_id: Option<LanguageServerId>,
12922        sender_id: proto::PeerId,
12923        lsp_request_id: LspRequestId,
12924        proto_request: T::ProtoRequest,
12925        position: Option<Anchor>,
12926        cx: &mut AsyncApp,
12927    ) -> Result<()>
12928    where
12929        T: LspCommand + Clone,
12930        T::ProtoRequest: proto::LspRequestMessage,
12931        <T::ProtoRequest as proto::RequestMessage>::Response:
12932            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12933    {
12934        let (buffer_version, buffer) =
12935            Self::wait_for_buffer_version::<T>(&lsp_store, &proto_request, cx).await?;
12936        let request =
12937            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12938        let key = LspKey {
12939            request_type: TypeId::of::<T>(),
12940            server_queried: for_server_id,
12941        };
12942        lsp_store.update(cx, |lsp_store, cx| {
12943            let request_task = match for_server_id {
12944                Some(server_id) => {
12945                    let server_task = lsp_store.request_lsp(
12946                        buffer.clone(),
12947                        LanguageServerToQuery::Other(server_id),
12948                        request.clone(),
12949                        cx,
12950                    );
12951                    cx.background_spawn(async move {
12952                        let mut responses = Vec::new();
12953                        match server_task.await {
12954                            Ok(response) => responses.push((server_id, response)),
12955                            // rust-analyzer likes to error with this when its still loading up
12956                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
12957                            Err(e) => log::error!(
12958                                "Error handling response for request {request:?}: {e:#}"
12959                            ),
12960                        }
12961                        responses
12962                    })
12963                }
12964                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12965            };
12966            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12967            if T::ProtoRequest::stop_previous_requests() {
12968                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12969                    lsp_requests.clear();
12970                }
12971            }
12972            lsp_data.lsp_requests.entry(key).or_default().insert(
12973                lsp_request_id,
12974                cx.spawn(async move |lsp_store, cx| {
12975                    let response = request_task.await;
12976                    lsp_store
12977                        .update(cx, |lsp_store, cx| {
12978                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12979                            {
12980                                let response = response
12981                                    .into_iter()
12982                                    .map(|(server_id, response)| {
12983                                        (
12984                                            server_id.to_proto(),
12985                                            T::response_to_proto(
12986                                                response,
12987                                                lsp_store,
12988                                                sender_id,
12989                                                &buffer_version,
12990                                                cx,
12991                                            )
12992                                            .into(),
12993                                        )
12994                                    })
12995                                    .collect::<HashMap<_, _>>();
12996                                match client.send_lsp_response::<T::ProtoRequest>(
12997                                    project_id,
12998                                    lsp_request_id,
12999                                    response,
13000                                ) {
13001                                    Ok(()) => {}
13002                                    Err(e) => {
13003                                        log::error!("Failed to send LSP response: {e:#}",)
13004                                    }
13005                                }
13006                            }
13007                        })
13008                        .ok();
13009                }),
13010            );
13011        });
13012        Ok(())
13013    }
13014
13015    async fn wait_for_buffer_version<T>(
13016        lsp_store: &Entity<Self>,
13017        proto_request: &T::ProtoRequest,
13018        cx: &mut AsyncApp,
13019    ) -> Result<(Global, Entity<Buffer>)>
13020    where
13021        T: LspCommand,
13022        T::ProtoRequest: proto::LspRequestMessage,
13023    {
13024        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13025        let version = deserialize_version(proto_request.buffer_version());
13026        let buffer = lsp_store.update(cx, |this, cx| {
13027            this.buffer_store.read(cx).get_existing(buffer_id)
13028        })?;
13029        buffer
13030            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13031            .await?;
13032        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13033        Ok((buffer_version, buffer))
13034    }
13035
13036    fn take_text_document_sync_options(
13037        capabilities: &mut lsp::ServerCapabilities,
13038    ) -> lsp::TextDocumentSyncOptions {
13039        match capabilities.text_document_sync.take() {
13040            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13041            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13042                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13043                sync_options.change = Some(sync_kind);
13044                sync_options
13045            }
13046            None => lsp::TextDocumentSyncOptions::default(),
13047        }
13048    }
13049
13050    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13051        self.downstream_client.clone()
13052    }
13053
13054    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13055        self.worktree_store.clone()
13056    }
13057
13058    /// Gets what's stored in the LSP data for the given buffer.
13059    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13060        self.lsp_data.get_mut(&buffer_id)
13061    }
13062
13063    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13064    /// new [`BufferLspData`] will be created to replace the previous state.
13065    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13066        let (buffer_id, buffer_version) =
13067            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13068        let lsp_data = self
13069            .lsp_data
13070            .entry(buffer_id)
13071            .or_insert_with(|| BufferLspData::new(buffer, cx));
13072        if buffer_version.changed_since(&lsp_data.buffer_version) {
13073            // To send delta requests for semantic tokens, the previous tokens
13074            // need to be kept between buffer changes.
13075            let semantic_tokens = lsp_data.semantic_tokens.take();
13076            *lsp_data = BufferLspData::new(buffer, cx);
13077            lsp_data.semantic_tokens = semantic_tokens;
13078        }
13079        lsp_data
13080    }
13081}
13082
13083// Registration with registerOptions as null, should fallback to true.
13084// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13085fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13086    reg: lsp::Registration,
13087) -> Result<OneOf<bool, T>> {
13088    Ok(match reg.register_options {
13089        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13090        None => OneOf::Left(true),
13091    })
13092}
13093
13094fn subscribe_to_binary_statuses(
13095    languages: &Arc<LanguageRegistry>,
13096    cx: &mut Context<'_, LspStore>,
13097) -> Task<()> {
13098    let mut server_statuses = languages.language_server_binary_statuses();
13099    cx.spawn(async move |lsp_store, cx| {
13100        while let Some((server_name, binary_status)) = server_statuses.next().await {
13101            if lsp_store
13102                .update(cx, |_, cx| {
13103                    let mut message = None;
13104                    let binary_status = match binary_status {
13105                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13106                        BinaryStatus::CheckingForUpdate => {
13107                            proto::ServerBinaryStatus::CheckingForUpdate
13108                        }
13109                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13110                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13111                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13112                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13113                        BinaryStatus::Failed { error } => {
13114                            message = Some(error);
13115                            proto::ServerBinaryStatus::Failed
13116                        }
13117                    };
13118                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13119                        // Binary updates are about the binary that might not have any language server id at that point.
13120                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13121                        language_server_id: LanguageServerId(0),
13122                        name: Some(server_name),
13123                        message: proto::update_language_server::Variant::StatusUpdate(
13124                            proto::StatusUpdate {
13125                                message,
13126                                status: Some(proto::status_update::Status::Binary(
13127                                    binary_status as i32,
13128                                )),
13129                            },
13130                        ),
13131                    });
13132                })
13133                .is_err()
13134            {
13135                break;
13136            }
13137        }
13138    })
13139}
13140
13141fn lsp_workspace_diagnostics_refresh(
13142    registration_id: Option<String>,
13143    options: DiagnosticServerCapabilities,
13144    server: Arc<LanguageServer>,
13145    cx: &mut Context<'_, LspStore>,
13146) -> Option<WorkspaceRefreshTask> {
13147    let identifier = workspace_diagnostic_identifier(&options)?;
13148    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13149
13150    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13151    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13152    refresh_tx.try_send(()).ok();
13153
13154    let request_timeout = ProjectSettings::get_global(cx)
13155        .global_lsp_settings
13156        .get_request_timeout();
13157
13158    // 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.
13159    // This allows users to increase the duration if need be
13160    let timeout = if request_timeout != Duration::ZERO {
13161        request_timeout.max(DEFAULT_LSP_REQUEST_TIMEOUT)
13162    } else {
13163        request_timeout
13164    };
13165
13166    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13167        let mut attempts = 0;
13168        let max_attempts = 50;
13169        let mut requests = 0;
13170
13171        loop {
13172            let Some(()) = refresh_rx.recv().await else {
13173                return;
13174            };
13175
13176            'request: loop {
13177                requests += 1;
13178                if attempts > max_attempts {
13179                    log::error!(
13180                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13181                    );
13182                    return;
13183                }
13184                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13185                cx.background_executor()
13186                    .timer(Duration::from_millis(backoff_millis))
13187                    .await;
13188                attempts += 1;
13189
13190                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13191                    lsp_store
13192                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13193                        .into_iter()
13194                        .filter_map(|(abs_path, result_id)| {
13195                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13196                            Some(lsp::PreviousResultId {
13197                                uri,
13198                                value: result_id.to_string(),
13199                            })
13200                        })
13201                        .collect()
13202                }) else {
13203                    return;
13204                };
13205
13206                let token = if let Some(registration_id) = &registration_id {
13207                    format!(
13208                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13209                        server.server_id(),
13210                    )
13211                } else {
13212                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13213                };
13214
13215                progress_rx.try_recv().ok();
13216                let timer = server.request_timer(timeout).fuse();
13217                let progress = pin!(progress_rx.recv().fuse());
13218                let response_result = server
13219                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13220                        lsp::WorkspaceDiagnosticParams {
13221                            previous_result_ids,
13222                            identifier: identifier.clone(),
13223                            work_done_progress_params: Default::default(),
13224                            partial_result_params: lsp::PartialResultParams {
13225                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13226                            },
13227                        },
13228                        select(timer, progress).then(|either| match either {
13229                            Either::Left((message, ..)) => ready(message).left_future(),
13230                            Either::Right(..) => pending::<String>().right_future(),
13231                        }),
13232                    )
13233                    .await;
13234
13235                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13236                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13237                match response_result {
13238                    ConnectionResult::Timeout => {
13239                        log::error!("Timeout during workspace diagnostics pull");
13240                        continue 'request;
13241                    }
13242                    ConnectionResult::ConnectionReset => {
13243                        log::error!("Server closed a workspace diagnostics pull request");
13244                        continue 'request;
13245                    }
13246                    ConnectionResult::Result(Err(e)) => {
13247                        log::error!("Error during workspace diagnostics pull: {e:#}");
13248                        break 'request;
13249                    }
13250                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13251                        attempts = 0;
13252                        if lsp_store
13253                            .update(cx, |lsp_store, cx| {
13254                                lsp_store.apply_workspace_diagnostic_report(
13255                                    server.server_id(),
13256                                    pulled_diagnostics,
13257                                    registration_id_shared.clone(),
13258                                    cx,
13259                                )
13260                            })
13261                            .is_err()
13262                        {
13263                            return;
13264                        }
13265                        break 'request;
13266                    }
13267                }
13268            }
13269        }
13270    });
13271
13272    Some(WorkspaceRefreshTask {
13273        refresh_tx,
13274        progress_tx,
13275        task: workspace_query_language_server,
13276    })
13277}
13278
13279fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<SharedString> {
13280    match &options {
13281        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => diagnostic_options
13282            .identifier
13283            .as_deref()
13284            .map(SharedString::new),
13285        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13286            let diagnostic_options = &registration_options.diagnostic_options;
13287            diagnostic_options
13288                .identifier
13289                .as_deref()
13290                .map(SharedString::new)
13291        }
13292    }
13293}
13294
13295fn workspace_diagnostic_identifier(
13296    options: &DiagnosticServerCapabilities,
13297) -> Option<Option<String>> {
13298    match &options {
13299        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13300            if !diagnostic_options.workspace_diagnostics {
13301                return None;
13302            }
13303            Some(diagnostic_options.identifier.clone())
13304        }
13305        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13306            let diagnostic_options = &registration_options.diagnostic_options;
13307            if !diagnostic_options.workspace_diagnostics {
13308                return None;
13309            }
13310            Some(diagnostic_options.identifier.clone())
13311        }
13312    }
13313}
13314
13315fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13316    let CompletionSource::BufferWord {
13317        word_range,
13318        resolved,
13319    } = &mut completion.source
13320    else {
13321        return;
13322    };
13323    if *resolved {
13324        return;
13325    }
13326
13327    if completion.new_text
13328        != snapshot
13329            .text_for_range(word_range.clone())
13330            .collect::<String>()
13331    {
13332        return;
13333    }
13334
13335    let mut offset = 0;
13336    for chunk in snapshot.chunks(word_range.clone(), true) {
13337        let end_offset = offset + chunk.text.len();
13338        if let Some(highlight_id) = chunk.syntax_highlight_id {
13339            completion
13340                .label
13341                .runs
13342                .push((offset..end_offset, highlight_id));
13343        }
13344        offset = end_offset;
13345    }
13346    *resolved = true;
13347}
13348
13349impl EventEmitter<LspStoreEvent> for LspStore {}
13350
13351fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13352    hover
13353        .contents
13354        .retain(|hover_block| !hover_block.text.trim().is_empty());
13355    if hover.contents.is_empty() {
13356        None
13357    } else {
13358        Some(hover)
13359    }
13360}
13361
13362async fn populate_labels_for_completions(
13363    new_completions: Vec<CoreCompletion>,
13364    language: Option<Arc<Language>>,
13365    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13366) -> Vec<Completion> {
13367    let lsp_completions = new_completions
13368        .iter()
13369        .filter_map(|new_completion| {
13370            new_completion
13371                .source
13372                .lsp_completion(true)
13373                .map(|lsp_completion| lsp_completion.into_owned())
13374        })
13375        .collect::<Vec<_>>();
13376
13377    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13378        lsp_adapter
13379            .labels_for_completions(&lsp_completions, language)
13380            .await
13381            .log_err()
13382            .unwrap_or_default()
13383    } else {
13384        Vec::new()
13385    }
13386    .into_iter()
13387    .fuse();
13388
13389    let mut completions = Vec::new();
13390    for completion in new_completions {
13391        match completion.source.lsp_completion(true) {
13392            Some(lsp_completion) => {
13393                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13394
13395                let mut label = labels.next().flatten().unwrap_or_else(|| {
13396                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13397                });
13398                ensure_uniform_list_compatible_label(&mut label);
13399                completions.push(Completion {
13400                    label,
13401                    documentation,
13402                    replace_range: completion.replace_range,
13403                    new_text: completion.new_text,
13404                    insert_text_mode: lsp_completion.insert_text_mode,
13405                    source: completion.source,
13406                    icon_path: None,
13407                    confirm: None,
13408                    match_start: None,
13409                    snippet_deduplication_key: None,
13410                });
13411            }
13412            None => {
13413                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13414                ensure_uniform_list_compatible_label(&mut label);
13415                completions.push(Completion {
13416                    label,
13417                    documentation: None,
13418                    replace_range: completion.replace_range,
13419                    new_text: completion.new_text,
13420                    source: completion.source,
13421                    insert_text_mode: None,
13422                    icon_path: None,
13423                    confirm: None,
13424                    match_start: None,
13425                    snippet_deduplication_key: None,
13426                });
13427            }
13428        }
13429    }
13430    completions
13431}
13432
13433#[derive(Debug)]
13434pub enum LanguageServerToQuery {
13435    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13436    FirstCapable,
13437    /// Query a specific language server.
13438    Other(LanguageServerId),
13439}
13440
13441#[derive(Default)]
13442struct RenamePathsWatchedForServer {
13443    did_rename: Vec<RenameActionPredicate>,
13444    will_rename: Vec<RenameActionPredicate>,
13445}
13446
13447impl RenamePathsWatchedForServer {
13448    fn with_did_rename_patterns(
13449        mut self,
13450        did_rename: Option<&FileOperationRegistrationOptions>,
13451    ) -> Self {
13452        if let Some(did_rename) = did_rename {
13453            self.did_rename = did_rename
13454                .filters
13455                .iter()
13456                .filter_map(|filter| filter.try_into().log_err())
13457                .collect();
13458        }
13459        self
13460    }
13461    fn with_will_rename_patterns(
13462        mut self,
13463        will_rename: Option<&FileOperationRegistrationOptions>,
13464    ) -> Self {
13465        if let Some(will_rename) = will_rename {
13466            self.will_rename = will_rename
13467                .filters
13468                .iter()
13469                .filter_map(|filter| filter.try_into().log_err())
13470                .collect();
13471        }
13472        self
13473    }
13474
13475    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13476        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13477    }
13478    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13479        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13480    }
13481}
13482
13483impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13484    type Error = globset::Error;
13485    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13486        Ok(Self {
13487            kind: ops.pattern.matches.clone(),
13488            glob: GlobBuilder::new(&ops.pattern.glob)
13489                .case_insensitive(
13490                    ops.pattern
13491                        .options
13492                        .as_ref()
13493                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13494                )
13495                .build()?
13496                .compile_matcher(),
13497        })
13498    }
13499}
13500struct RenameActionPredicate {
13501    glob: GlobMatcher,
13502    kind: Option<FileOperationPatternKind>,
13503}
13504
13505impl RenameActionPredicate {
13506    // Returns true if language server should be notified
13507    fn eval(&self, path: &str, is_dir: bool) -> bool {
13508        self.kind.as_ref().is_none_or(|kind| {
13509            let expected_kind = if is_dir {
13510                FileOperationPatternKind::Folder
13511            } else {
13512                FileOperationPatternKind::File
13513            };
13514            kind == &expected_kind
13515        }) && self.glob.is_match(path)
13516    }
13517}
13518
13519#[derive(Default)]
13520struct LanguageServerWatchedPaths {
13521    worktree_paths: HashMap<WorktreeId, GlobSet>,
13522    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13523}
13524
13525#[derive(Default)]
13526struct LanguageServerWatchedPathsBuilder {
13527    worktree_paths: HashMap<WorktreeId, GlobSet>,
13528    abs_paths: HashMap<Arc<Path>, GlobSet>,
13529}
13530
13531impl LanguageServerWatchedPathsBuilder {
13532    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13533        self.worktree_paths.insert(worktree_id, glob_set);
13534    }
13535    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13536        self.abs_paths.insert(path, glob_set);
13537    }
13538    fn build(
13539        self,
13540        fs: Arc<dyn Fs>,
13541        language_server_id: LanguageServerId,
13542        cx: &mut Context<LspStore>,
13543    ) -> LanguageServerWatchedPaths {
13544        let lsp_store = cx.weak_entity();
13545
13546        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13547        let abs_paths = self
13548            .abs_paths
13549            .into_iter()
13550            .map(|(abs_path, globset)| {
13551                let task = cx.spawn({
13552                    let abs_path = abs_path.clone();
13553                    let fs = fs.clone();
13554
13555                    let lsp_store = lsp_store.clone();
13556                    async move |_, cx| {
13557                        maybe!(async move {
13558                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13559                            while let Some(update) = push_updates.0.next().await {
13560                                let action = lsp_store
13561                                    .update(cx, |this, _| {
13562                                        let Some(local) = this.as_local() else {
13563                                            return ControlFlow::Break(());
13564                                        };
13565                                        let Some(watcher) = local
13566                                            .language_server_watched_paths
13567                                            .get(&language_server_id)
13568                                        else {
13569                                            return ControlFlow::Break(());
13570                                        };
13571                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13572                                            "Watched abs path is not registered with a watcher",
13573                                        );
13574                                        let matching_entries = update
13575                                            .into_iter()
13576                                            .filter(|event| globs.is_match(&event.path))
13577                                            .collect::<Vec<_>>();
13578                                        this.lsp_notify_abs_paths_changed(
13579                                            language_server_id,
13580                                            matching_entries,
13581                                        );
13582                                        ControlFlow::Continue(())
13583                                    })
13584                                    .ok()?;
13585
13586                                if action.is_break() {
13587                                    break;
13588                                }
13589                            }
13590                            Some(())
13591                        })
13592                        .await;
13593                    }
13594                });
13595                (abs_path, (globset, task))
13596            })
13597            .collect();
13598        LanguageServerWatchedPaths {
13599            worktree_paths: self.worktree_paths,
13600            abs_paths,
13601        }
13602    }
13603}
13604
13605struct LspBufferSnapshot {
13606    version: i32,
13607    snapshot: TextBufferSnapshot,
13608}
13609
13610/// A prompt requested by LSP server.
13611#[derive(Clone, Debug)]
13612pub struct LanguageServerPromptRequest {
13613    pub id: usize,
13614    pub level: PromptLevel,
13615    pub message: String,
13616    pub actions: Vec<MessageActionItem>,
13617    pub lsp_name: String,
13618    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13619}
13620
13621impl LanguageServerPromptRequest {
13622    pub fn new(
13623        level: PromptLevel,
13624        message: String,
13625        actions: Vec<MessageActionItem>,
13626        lsp_name: String,
13627        response_channel: smol::channel::Sender<MessageActionItem>,
13628    ) -> Self {
13629        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13630        LanguageServerPromptRequest {
13631            id,
13632            level,
13633            message,
13634            actions,
13635            lsp_name,
13636            response_channel,
13637        }
13638    }
13639    pub async fn respond(self, index: usize) -> Option<()> {
13640        if let Some(response) = self.actions.into_iter().nth(index) {
13641            self.response_channel.send(response).await.ok()
13642        } else {
13643            None
13644        }
13645    }
13646
13647    #[cfg(any(test, feature = "test-support"))]
13648    pub fn test(
13649        level: PromptLevel,
13650        message: String,
13651        actions: Vec<MessageActionItem>,
13652        lsp_name: String,
13653    ) -> Self {
13654        let (tx, _rx) = smol::channel::unbounded();
13655        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13656    }
13657}
13658impl PartialEq for LanguageServerPromptRequest {
13659    fn eq(&self, other: &Self) -> bool {
13660        self.message == other.message && self.actions == other.actions
13661    }
13662}
13663
13664#[derive(Clone, Debug, PartialEq)]
13665pub enum LanguageServerLogType {
13666    Log(MessageType),
13667    Trace { verbose_info: Option<String> },
13668    Rpc { received: bool },
13669}
13670
13671impl LanguageServerLogType {
13672    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13673        match self {
13674            Self::Log(log_type) => {
13675                use proto::log_message::LogLevel;
13676                let level = match *log_type {
13677                    MessageType::ERROR => LogLevel::Error,
13678                    MessageType::WARNING => LogLevel::Warning,
13679                    MessageType::INFO => LogLevel::Info,
13680                    MessageType::LOG => LogLevel::Log,
13681                    other => {
13682                        log::warn!("Unknown lsp log message type: {other:?}");
13683                        LogLevel::Log
13684                    }
13685                };
13686                proto::language_server_log::LogType::Log(proto::LogMessage {
13687                    level: level as i32,
13688                })
13689            }
13690            Self::Trace { verbose_info } => {
13691                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13692                    verbose_info: verbose_info.to_owned(),
13693                })
13694            }
13695            Self::Rpc { received } => {
13696                let kind = if *received {
13697                    proto::rpc_message::Kind::Received
13698                } else {
13699                    proto::rpc_message::Kind::Sent
13700                };
13701                let kind = kind as i32;
13702                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13703            }
13704        }
13705    }
13706
13707    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13708        use proto::log_message::LogLevel;
13709        use proto::rpc_message;
13710        match log_type {
13711            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13712                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13713                    LogLevel::Error => MessageType::ERROR,
13714                    LogLevel::Warning => MessageType::WARNING,
13715                    LogLevel::Info => MessageType::INFO,
13716                    LogLevel::Log => MessageType::LOG,
13717                },
13718            ),
13719            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13720                verbose_info: trace_message.verbose_info,
13721            },
13722            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13723                received: match rpc_message::Kind::from_i32(message.kind)
13724                    .unwrap_or(rpc_message::Kind::Received)
13725                {
13726                    rpc_message::Kind::Received => true,
13727                    rpc_message::Kind::Sent => false,
13728                },
13729            },
13730        }
13731    }
13732}
13733
13734pub struct WorkspaceRefreshTask {
13735    refresh_tx: mpsc::Sender<()>,
13736    progress_tx: mpsc::Sender<()>,
13737    #[allow(dead_code)]
13738    task: Task<()>,
13739}
13740
13741pub enum LanguageServerState {
13742    Starting {
13743        startup: Task<Option<Arc<LanguageServer>>>,
13744        /// List of language servers that will be added to the workspace once it's initialization completes.
13745        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13746    },
13747
13748    Running {
13749        adapter: Arc<CachedLspAdapter>,
13750        server: Arc<LanguageServer>,
13751        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13752        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13753    },
13754}
13755
13756impl LanguageServerState {
13757    fn add_workspace_folder(&self, uri: Uri) {
13758        match self {
13759            LanguageServerState::Starting {
13760                pending_workspace_folders,
13761                ..
13762            } => {
13763                pending_workspace_folders.lock().insert(uri);
13764            }
13765            LanguageServerState::Running { server, .. } => {
13766                server.add_workspace_folder(uri);
13767            }
13768        }
13769    }
13770    fn _remove_workspace_folder(&self, uri: Uri) {
13771        match self {
13772            LanguageServerState::Starting {
13773                pending_workspace_folders,
13774                ..
13775            } => {
13776                pending_workspace_folders.lock().remove(&uri);
13777            }
13778            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13779        }
13780    }
13781}
13782
13783impl std::fmt::Debug for LanguageServerState {
13784    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13785        match self {
13786            LanguageServerState::Starting { .. } => {
13787                f.debug_struct("LanguageServerState::Starting").finish()
13788            }
13789            LanguageServerState::Running { .. } => {
13790                f.debug_struct("LanguageServerState::Running").finish()
13791            }
13792        }
13793    }
13794}
13795
13796#[derive(Clone, Debug, Serialize)]
13797pub struct LanguageServerProgress {
13798    pub is_disk_based_diagnostics_progress: bool,
13799    pub is_cancellable: bool,
13800    pub title: Option<String>,
13801    pub message: Option<String>,
13802    pub percentage: Option<usize>,
13803    #[serde(skip_serializing)]
13804    pub last_update_at: Instant,
13805}
13806
13807#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13808pub struct DiagnosticSummary {
13809    pub error_count: usize,
13810    pub warning_count: usize,
13811}
13812
13813impl DiagnosticSummary {
13814    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13815        let mut this = Self {
13816            error_count: 0,
13817            warning_count: 0,
13818        };
13819
13820        for entry in diagnostics {
13821            if entry.diagnostic.is_primary {
13822                match entry.diagnostic.severity {
13823                    DiagnosticSeverity::ERROR => this.error_count += 1,
13824                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13825                    _ => {}
13826                }
13827            }
13828        }
13829
13830        this
13831    }
13832
13833    pub fn is_empty(&self) -> bool {
13834        self.error_count == 0 && self.warning_count == 0
13835    }
13836
13837    pub fn to_proto(
13838        self,
13839        language_server_id: LanguageServerId,
13840        path: &RelPath,
13841    ) -> proto::DiagnosticSummary {
13842        proto::DiagnosticSummary {
13843            path: path.to_proto(),
13844            language_server_id: language_server_id.0 as u64,
13845            error_count: self.error_count as u32,
13846            warning_count: self.warning_count as u32,
13847        }
13848    }
13849}
13850
13851#[derive(Clone, Debug)]
13852pub enum CompletionDocumentation {
13853    /// There is no documentation for this completion.
13854    Undocumented,
13855    /// A single line of documentation.
13856    SingleLine(SharedString),
13857    /// Multiple lines of plain text documentation.
13858    MultiLinePlainText(SharedString),
13859    /// Markdown documentation.
13860    MultiLineMarkdown(SharedString),
13861    /// Both single line and multiple lines of plain text documentation.
13862    SingleLineAndMultiLinePlainText {
13863        single_line: SharedString,
13864        plain_text: Option<SharedString>,
13865    },
13866}
13867
13868impl CompletionDocumentation {
13869    #[cfg(any(test, feature = "test-support"))]
13870    pub fn text(&self) -> SharedString {
13871        match self {
13872            CompletionDocumentation::Undocumented => "".into(),
13873            CompletionDocumentation::SingleLine(s) => s.clone(),
13874            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13875            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13876            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13877                single_line.clone()
13878            }
13879        }
13880    }
13881}
13882
13883impl From<lsp::Documentation> for CompletionDocumentation {
13884    fn from(docs: lsp::Documentation) -> Self {
13885        match docs {
13886            lsp::Documentation::String(text) => {
13887                if text.lines().count() <= 1 {
13888                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
13889                } else {
13890                    CompletionDocumentation::MultiLinePlainText(text.into())
13891                }
13892            }
13893
13894            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13895                lsp::MarkupKind::PlainText => {
13896                    if value.lines().count() <= 1 {
13897                        CompletionDocumentation::SingleLine(value.into())
13898                    } else {
13899                        CompletionDocumentation::MultiLinePlainText(value.into())
13900                    }
13901                }
13902
13903                lsp::MarkupKind::Markdown => {
13904                    CompletionDocumentation::MultiLineMarkdown(value.into())
13905                }
13906            },
13907        }
13908    }
13909}
13910
13911pub enum ResolvedHint {
13912    Resolved(InlayHint),
13913    Resolving(Shared<Task<()>>),
13914}
13915
13916pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
13917    glob.components()
13918        .take_while(|component| match component {
13919            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13920            _ => true,
13921        })
13922        .collect()
13923}
13924
13925pub struct SshLspAdapter {
13926    name: LanguageServerName,
13927    binary: LanguageServerBinary,
13928    initialization_options: Option<String>,
13929    code_action_kinds: Option<Vec<CodeActionKind>>,
13930}
13931
13932impl SshLspAdapter {
13933    pub fn new(
13934        name: LanguageServerName,
13935        binary: LanguageServerBinary,
13936        initialization_options: Option<String>,
13937        code_action_kinds: Option<String>,
13938    ) -> Self {
13939        Self {
13940            name,
13941            binary,
13942            initialization_options,
13943            code_action_kinds: code_action_kinds
13944                .as_ref()
13945                .and_then(|c| serde_json::from_str(c).ok()),
13946        }
13947    }
13948}
13949
13950impl LspInstaller for SshLspAdapter {
13951    type BinaryVersion = ();
13952    async fn check_if_user_installed(
13953        &self,
13954        _: &dyn LspAdapterDelegate,
13955        _: Option<Toolchain>,
13956        _: &AsyncApp,
13957    ) -> Option<LanguageServerBinary> {
13958        Some(self.binary.clone())
13959    }
13960
13961    async fn cached_server_binary(
13962        &self,
13963        _: PathBuf,
13964        _: &dyn LspAdapterDelegate,
13965    ) -> Option<LanguageServerBinary> {
13966        None
13967    }
13968
13969    async fn fetch_latest_server_version(
13970        &self,
13971        _: &dyn LspAdapterDelegate,
13972        _: bool,
13973        _: &mut AsyncApp,
13974    ) -> Result<()> {
13975        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13976    }
13977
13978    async fn fetch_server_binary(
13979        &self,
13980        _: (),
13981        _: PathBuf,
13982        _: &dyn LspAdapterDelegate,
13983    ) -> Result<LanguageServerBinary> {
13984        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13985    }
13986}
13987
13988#[async_trait(?Send)]
13989impl LspAdapter for SshLspAdapter {
13990    fn name(&self) -> LanguageServerName {
13991        self.name.clone()
13992    }
13993
13994    async fn initialization_options(
13995        self: Arc<Self>,
13996        _: &Arc<dyn LspAdapterDelegate>,
13997        _: &mut AsyncApp,
13998    ) -> Result<Option<serde_json::Value>> {
13999        let Some(options) = &self.initialization_options else {
14000            return Ok(None);
14001        };
14002        let result = serde_json::from_str(options)?;
14003        Ok(result)
14004    }
14005
14006    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14007        self.code_action_kinds.clone()
14008    }
14009}
14010
14011pub fn language_server_settings<'a>(
14012    delegate: &'a dyn LspAdapterDelegate,
14013    language: &LanguageServerName,
14014    cx: &'a App,
14015) -> Option<&'a LspSettings> {
14016    language_server_settings_for(
14017        SettingsLocation {
14018            worktree_id: delegate.worktree_id(),
14019            path: RelPath::empty(),
14020        },
14021        language,
14022        cx,
14023    )
14024}
14025
14026pub fn language_server_settings_for<'a>(
14027    location: SettingsLocation<'a>,
14028    language: &LanguageServerName,
14029    cx: &'a App,
14030) -> Option<&'a LspSettings> {
14031    ProjectSettings::get(Some(location), cx).lsp.get(language)
14032}
14033
14034pub struct LocalLspAdapterDelegate {
14035    lsp_store: WeakEntity<LspStore>,
14036    worktree: worktree::Snapshot,
14037    fs: Arc<dyn Fs>,
14038    http_client: Arc<dyn HttpClient>,
14039    language_registry: Arc<LanguageRegistry>,
14040    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14041}
14042
14043impl LocalLspAdapterDelegate {
14044    pub fn new(
14045        language_registry: Arc<LanguageRegistry>,
14046        environment: &Entity<ProjectEnvironment>,
14047        lsp_store: WeakEntity<LspStore>,
14048        worktree: &Entity<Worktree>,
14049        http_client: Arc<dyn HttpClient>,
14050        fs: Arc<dyn Fs>,
14051        cx: &mut App,
14052    ) -> Arc<Self> {
14053        let load_shell_env_task =
14054            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14055
14056        Arc::new(Self {
14057            lsp_store,
14058            worktree: worktree.read(cx).snapshot(),
14059            fs,
14060            http_client,
14061            language_registry,
14062            load_shell_env_task,
14063        })
14064    }
14065
14066    pub fn from_local_lsp(
14067        local: &LocalLspStore,
14068        worktree: &Entity<Worktree>,
14069        cx: &mut App,
14070    ) -> Arc<Self> {
14071        Self::new(
14072            local.languages.clone(),
14073            &local.environment,
14074            local.weak.clone(),
14075            worktree,
14076            local.http_client.clone(),
14077            local.fs.clone(),
14078            cx,
14079        )
14080    }
14081}
14082
14083#[async_trait]
14084impl LspAdapterDelegate for LocalLspAdapterDelegate {
14085    fn show_notification(&self, message: &str, cx: &mut App) {
14086        self.lsp_store
14087            .update(cx, |_, cx| {
14088                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14089            })
14090            .ok();
14091    }
14092
14093    fn http_client(&self) -> Arc<dyn HttpClient> {
14094        self.http_client.clone()
14095    }
14096
14097    fn worktree_id(&self) -> WorktreeId {
14098        self.worktree.id()
14099    }
14100
14101    fn worktree_root_path(&self) -> &Path {
14102        self.worktree.abs_path().as_ref()
14103    }
14104
14105    fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
14106        self.worktree.resolve_relative_path(path)
14107    }
14108
14109    async fn shell_env(&self) -> HashMap<String, String> {
14110        let task = self.load_shell_env_task.clone();
14111        task.await.unwrap_or_default()
14112    }
14113
14114    async fn npm_package_installed_version(
14115        &self,
14116        package_name: &str,
14117    ) -> Result<Option<(PathBuf, Version)>> {
14118        let local_package_directory = self.worktree_root_path();
14119        let node_modules_directory = local_package_directory.join("node_modules");
14120
14121        if let Some(version) =
14122            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14123        {
14124            return Ok(Some((node_modules_directory, version)));
14125        }
14126        let Some(npm) = self.which("npm".as_ref()).await else {
14127            log::warn!(
14128                "Failed to find npm executable for {:?}",
14129                local_package_directory
14130            );
14131            return Ok(None);
14132        };
14133
14134        let env = self.shell_env().await;
14135        let output = util::command::new_command(&npm)
14136            .args(["root", "-g"])
14137            .envs(env)
14138            .current_dir(local_package_directory)
14139            .output()
14140            .await?;
14141        let global_node_modules =
14142            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14143
14144        if let Some(version) =
14145            read_package_installed_version(global_node_modules.clone(), package_name).await?
14146        {
14147            return Ok(Some((global_node_modules, version)));
14148        }
14149        return Ok(None);
14150    }
14151
14152    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14153        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14154        if self.fs.is_file(&worktree_abs_path).await {
14155            worktree_abs_path.pop();
14156        }
14157
14158        let env = self.shell_env().await;
14159
14160        let shell_path = env.get("PATH").cloned();
14161
14162        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14163    }
14164
14165    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14166        let mut working_dir = self.worktree_root_path().to_path_buf();
14167        if self.fs.is_file(&working_dir).await {
14168            working_dir.pop();
14169        }
14170        let output = util::command::new_command(&command.path)
14171            .args(command.arguments)
14172            .envs(command.env.clone().unwrap_or_default())
14173            .current_dir(working_dir)
14174            .output()
14175            .await?;
14176
14177        anyhow::ensure!(
14178            output.status.success(),
14179            "{}, stdout: {:?}, stderr: {:?}",
14180            output.status,
14181            String::from_utf8_lossy(&output.stdout),
14182            String::from_utf8_lossy(&output.stderr)
14183        );
14184        Ok(())
14185    }
14186
14187    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14188        self.language_registry
14189            .update_lsp_binary_status(server_name, status);
14190    }
14191
14192    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14193        self.language_registry
14194            .all_lsp_adapters()
14195            .into_iter()
14196            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14197            .collect()
14198    }
14199
14200    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14201        let dir = self.language_registry.language_server_download_dir(name)?;
14202
14203        if !dir.exists() {
14204            smol::fs::create_dir_all(&dir)
14205                .await
14206                .context("failed to create container directory")
14207                .log_err()?;
14208        }
14209
14210        Some(dir)
14211    }
14212
14213    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14214        let entry = self
14215            .worktree
14216            .entry_for_path(path)
14217            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14218        let abs_path = self.worktree.absolutize(&entry.path);
14219        self.fs.load(&abs_path).await
14220    }
14221}
14222
14223async fn populate_labels_for_symbols(
14224    symbols: Vec<CoreSymbol>,
14225    language_registry: &Arc<LanguageRegistry>,
14226    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14227    output: &mut Vec<Symbol>,
14228) {
14229    #[allow(clippy::mutable_key_type)]
14230    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14231
14232    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14233    for symbol in symbols {
14234        let Some(file_name) = symbol.path.file_name() else {
14235            continue;
14236        };
14237        let language = language_registry
14238            .load_language_for_file_path(Path::new(file_name))
14239            .await
14240            .ok()
14241            .or_else(|| {
14242                unknown_paths.insert(file_name.into());
14243                None
14244            });
14245        symbols_by_language
14246            .entry(language)
14247            .or_default()
14248            .push(symbol);
14249    }
14250
14251    for unknown_path in unknown_paths {
14252        log::info!("no language found for symbol in file {unknown_path:?}");
14253    }
14254
14255    let mut label_params = Vec::new();
14256    for (language, mut symbols) in symbols_by_language {
14257        label_params.clear();
14258        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14259            name: mem::take(&mut symbol.name),
14260            kind: symbol.kind,
14261            container_name: symbol.container_name.take(),
14262        }));
14263
14264        let mut labels = Vec::new();
14265        if let Some(language) = language {
14266            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14267                language_registry
14268                    .lsp_adapters(&language.name())
14269                    .first()
14270                    .cloned()
14271            });
14272            if let Some(lsp_adapter) = lsp_adapter {
14273                labels = lsp_adapter
14274                    .labels_for_symbols(&label_params, &language)
14275                    .await
14276                    .log_err()
14277                    .unwrap_or_default();
14278            }
14279        }
14280
14281        for (
14282            (
14283                symbol,
14284                language::Symbol {
14285                    name,
14286                    container_name,
14287                    ..
14288                },
14289            ),
14290            label,
14291        ) in symbols
14292            .into_iter()
14293            .zip(label_params.drain(..))
14294            .zip(labels.into_iter().chain(iter::repeat(None)))
14295        {
14296            output.push(Symbol {
14297                language_server_name: symbol.language_server_name,
14298                source_worktree_id: symbol.source_worktree_id,
14299                source_language_server_id: symbol.source_language_server_id,
14300                path: symbol.path,
14301                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14302                name,
14303                kind: symbol.kind,
14304                range: symbol.range,
14305                container_name,
14306            });
14307        }
14308    }
14309}
14310
14311pub(crate) fn collapse_newlines(text: &str, separator: &str) -> String {
14312    text.lines()
14313        .map(|line| line.trim())
14314        .filter(|line| !line.is_empty())
14315        .join(separator)
14316}
14317
14318fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14319    match server.capabilities().text_document_sync.as_ref()? {
14320        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14321            // Server wants didSave but didn't specify includeText.
14322            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14323            // Server doesn't want didSave at all.
14324            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14325            // Server provided SaveOptions.
14326            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14327                Some(save_options.include_text.unwrap_or(false))
14328            }
14329        },
14330        // We do not have any save info. Kind affects didChange only.
14331        lsp::TextDocumentSyncCapability::Kind(_) => None,
14332    }
14333}
14334
14335/// Completion items are displayed in a `UniformList`.
14336/// Usually, those items are single-line strings, but in LSP responses,
14337/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14338/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14339/// 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,
14340/// breaking the completions menu presentation.
14341///
14342/// 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.
14343pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14344    let mut new_text = String::with_capacity(label.text.len());
14345    let mut offset_map = vec![0; label.text.len() + 1];
14346    let mut last_char_was_space = false;
14347    let mut new_idx = 0;
14348    let chars = label.text.char_indices().fuse();
14349    let mut newlines_removed = false;
14350
14351    for (idx, c) in chars {
14352        offset_map[idx] = new_idx;
14353
14354        match c {
14355            '\n' if last_char_was_space => {
14356                newlines_removed = true;
14357            }
14358            '\t' | ' ' if last_char_was_space => {}
14359            '\n' if !last_char_was_space => {
14360                new_text.push(' ');
14361                new_idx += 1;
14362                last_char_was_space = true;
14363                newlines_removed = true;
14364            }
14365            ' ' | '\t' => {
14366                new_text.push(' ');
14367                new_idx += 1;
14368                last_char_was_space = true;
14369            }
14370            _ => {
14371                new_text.push(c);
14372                new_idx += c.len_utf8();
14373                last_char_was_space = false;
14374            }
14375        }
14376    }
14377    offset_map[label.text.len()] = new_idx;
14378
14379    // Only modify the label if newlines were removed.
14380    if !newlines_removed {
14381        return;
14382    }
14383
14384    let last_index = new_idx;
14385    let mut run_ranges_errors = Vec::new();
14386    label.runs.retain_mut(|(range, _)| {
14387        match offset_map.get(range.start) {
14388            Some(&start) => range.start = start,
14389            None => {
14390                run_ranges_errors.push(range.clone());
14391                return false;
14392            }
14393        }
14394
14395        match offset_map.get(range.end) {
14396            Some(&end) => range.end = end,
14397            None => {
14398                run_ranges_errors.push(range.clone());
14399                range.end = last_index;
14400            }
14401        }
14402        true
14403    });
14404    if !run_ranges_errors.is_empty() {
14405        log::error!(
14406            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14407            label.text
14408        );
14409    }
14410
14411    let mut wrong_filter_range = None;
14412    if label.filter_range == (0..label.text.len()) {
14413        label.filter_range = 0..new_text.len();
14414    } else {
14415        let mut original_filter_range = Some(label.filter_range.clone());
14416        match offset_map.get(label.filter_range.start) {
14417            Some(&start) => label.filter_range.start = start,
14418            None => {
14419                wrong_filter_range = original_filter_range.take();
14420                label.filter_range.start = last_index;
14421            }
14422        }
14423
14424        match offset_map.get(label.filter_range.end) {
14425            Some(&end) => label.filter_range.end = end,
14426            None => {
14427                wrong_filter_range = original_filter_range.take();
14428                label.filter_range.end = last_index;
14429            }
14430        }
14431    }
14432    if let Some(wrong_filter_range) = wrong_filter_range {
14433        log::error!(
14434            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14435            label.text
14436        );
14437    }
14438
14439    label.text = new_text;
14440}