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