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        all_commit_ranges: Vec<Range<language::Anchor>>,
 6647        cx: &mut Context<Self>,
 6648    ) -> Task<Result<Option<Transaction>>> {
 6649        if let Some((client, project_id)) = self.upstream_client() {
 6650            let buffer = buffer_handle.read(cx);
 6651            let buffer_id = buffer.remote_id();
 6652            cx.spawn(async move |_, cx| {
 6653                let request = {
 6654                    let completion = completions.borrow()[completion_index].clone();
 6655                    proto::ApplyCompletionAdditionalEdits {
 6656                        project_id,
 6657                        buffer_id: buffer_id.into(),
 6658                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6659                            replace_range: completion.replace_range,
 6660                            new_text: completion.new_text,
 6661                            source: completion.source,
 6662                        })),
 6663                        all_commit_ranges: all_commit_ranges
 6664                            .iter()
 6665                            .cloned()
 6666                            .map(language::proto::serialize_anchor_range)
 6667                            .collect(),
 6668                    }
 6669                };
 6670
 6671                let Some(transaction) = client.request(request).await?.transaction else {
 6672                    return Ok(None);
 6673                };
 6674
 6675                let transaction = language::proto::deserialize_transaction(transaction)?;
 6676                buffer_handle
 6677                    .update(cx, |buffer, _| {
 6678                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6679                    })
 6680                    .await?;
 6681                if push_to_history {
 6682                    buffer_handle.update(cx, |buffer, _| {
 6683                        buffer.push_transaction(transaction.clone(), Instant::now());
 6684                        buffer.finalize_last_transaction();
 6685                    });
 6686                }
 6687                Ok(Some(transaction))
 6688            })
 6689        } else {
 6690            let request_timeout = ProjectSettings::get_global(cx)
 6691                .global_lsp_settings
 6692                .get_request_timeout();
 6693
 6694            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6695                let completion = &completions.borrow()[completion_index];
 6696                let server_id = completion.source.server_id()?;
 6697                Some(
 6698                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6699                        .1
 6700                        .clone(),
 6701                )
 6702            }) else {
 6703                return Task::ready(Ok(None));
 6704            };
 6705
 6706            cx.spawn(async move |this, cx| {
 6707                Self::resolve_completion_local(
 6708                    server.clone(),
 6709                    completions.clone(),
 6710                    completion_index,
 6711                    request_timeout,
 6712                )
 6713                .await
 6714                .context("resolving completion")?;
 6715                let completion = completions.borrow()[completion_index].clone();
 6716                let additional_text_edits = completion
 6717                    .source
 6718                    .lsp_completion(true)
 6719                    .as_ref()
 6720                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6721                if let Some(edits) = additional_text_edits {
 6722                    let edits = this
 6723                        .update(cx, |this, cx| {
 6724                            this.as_local_mut().unwrap().edits_from_lsp(
 6725                                &buffer_handle,
 6726                                edits,
 6727                                server.server_id(),
 6728                                None,
 6729                                cx,
 6730                            )
 6731                        })?
 6732                        .await?;
 6733
 6734                    buffer_handle.update(cx, |buffer, cx| {
 6735                        buffer.finalize_last_transaction();
 6736                        buffer.start_transaction();
 6737
 6738                        for (range, text) in edits {
 6739                            let primary = &completion.replace_range;
 6740
 6741                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6742                            // and the primary completion is just an insertion (empty range), then this is likely
 6743                            // an auto-import scenario and should not be considered overlapping
 6744                            // https://github.com/zed-industries/zed/issues/26136
 6745                            let is_file_start_auto_import = {
 6746                                let snapshot = buffer.snapshot();
 6747                                let primary_start_point = primary.start.to_point(&snapshot);
 6748                                let range_start_point = range.start.to_point(&snapshot);
 6749
 6750                                let result = primary_start_point.row == 0
 6751                                    && primary_start_point.column == 0
 6752                                    && range_start_point.row == 0
 6753                                    && range_start_point.column == 0;
 6754
 6755                                result
 6756                            };
 6757
 6758                            let has_overlap = if is_file_start_auto_import {
 6759                                false
 6760                            } else {
 6761                                all_commit_ranges.iter().any(|commit_range| {
 6762                                    let start_within =
 6763                                        commit_range.start.cmp(&range.start, buffer).is_le()
 6764                                            && commit_range.end.cmp(&range.start, buffer).is_ge();
 6765                                    let end_within =
 6766                                        range.start.cmp(&commit_range.end, buffer).is_le()
 6767                                            && range.end.cmp(&commit_range.end, buffer).is_ge();
 6768                                    start_within || end_within
 6769                                })
 6770                            };
 6771
 6772                            //Skip additional edits which overlap with the primary completion edit
 6773                            //https://github.com/zed-industries/zed/pull/1871
 6774                            if !has_overlap {
 6775                                buffer.edit([(range, text)], None, cx);
 6776                            }
 6777                        }
 6778
 6779                        let transaction = if buffer.end_transaction(cx).is_some() {
 6780                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6781                            if !push_to_history {
 6782                                buffer.forget_transaction(transaction.id);
 6783                            }
 6784                            Some(transaction)
 6785                        } else {
 6786                            None
 6787                        };
 6788                        Ok(transaction)
 6789                    })
 6790                } else {
 6791                    Ok(None)
 6792                }
 6793            })
 6794        }
 6795    }
 6796
 6797    pub fn pull_diagnostics(
 6798        &mut self,
 6799        buffer: Entity<Buffer>,
 6800        cx: &mut Context<Self>,
 6801    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6802        let buffer_id = buffer.read(cx).remote_id();
 6803
 6804        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6805            let mut suitable_capabilities = None;
 6806            // Are we capable for proto request?
 6807            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6808                &buffer,
 6809                |capabilities| {
 6810                    if let Some(caps) = &capabilities.diagnostic_provider {
 6811                        suitable_capabilities = Some(caps.clone());
 6812                        true
 6813                    } else {
 6814                        false
 6815                    }
 6816                },
 6817                cx,
 6818            );
 6819            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6820            let Some(dynamic_caps) = suitable_capabilities else {
 6821                return Task::ready(Ok(None));
 6822            };
 6823            assert!(any_server_has_diagnostics_provider);
 6824
 6825            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6826            let request = GetDocumentDiagnostics {
 6827                previous_result_id: None,
 6828                identifier,
 6829                registration_id: None,
 6830            };
 6831            let request_timeout = ProjectSettings::get_global(cx)
 6832                .global_lsp_settings
 6833                .get_request_timeout();
 6834            let request_task = client.request_lsp(
 6835                upstream_project_id,
 6836                None,
 6837                request_timeout,
 6838                cx.background_executor().clone(),
 6839                request.to_proto(upstream_project_id, buffer.read(cx)),
 6840            );
 6841            cx.background_spawn(async move {
 6842                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6843                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6844                // Do not attempt to further process the dummy responses here.
 6845                let _response = request_task.await?;
 6846                Ok(None)
 6847            })
 6848        } else {
 6849            let servers = buffer.update(cx, |buffer, cx| {
 6850                self.running_language_servers_for_local_buffer(buffer, cx)
 6851                    .map(|(_, server)| server.clone())
 6852                    .collect::<Vec<_>>()
 6853            });
 6854
 6855            let pull_diagnostics = servers
 6856                .into_iter()
 6857                .flat_map(|server| {
 6858                    let result = maybe!({
 6859                        let local = self.as_local()?;
 6860                        let server_id = server.server_id();
 6861                        let providers_with_identifiers = local
 6862                            .language_server_dynamic_registrations
 6863                            .get(&server_id)
 6864                            .into_iter()
 6865                            .flat_map(|registrations| registrations.diagnostics.clone())
 6866                            .collect::<Vec<_>>();
 6867                        Some(
 6868                            providers_with_identifiers
 6869                                .into_iter()
 6870                                .map(|(registration_id, dynamic_caps)| {
 6871                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6872                                    let registration_id = registration_id.map(SharedString::from);
 6873                                    let result_id = self.result_id_for_buffer_pull(
 6874                                        server_id,
 6875                                        buffer_id,
 6876                                        &registration_id,
 6877                                        cx,
 6878                                    );
 6879                                    self.request_lsp(
 6880                                        buffer.clone(),
 6881                                        LanguageServerToQuery::Other(server_id),
 6882                                        GetDocumentDiagnostics {
 6883                                            previous_result_id: result_id,
 6884                                            registration_id,
 6885                                            identifier,
 6886                                        },
 6887                                        cx,
 6888                                    )
 6889                                })
 6890                                .collect::<Vec<_>>(),
 6891                        )
 6892                    });
 6893
 6894                    result.unwrap_or_default()
 6895                })
 6896                .collect::<Vec<_>>();
 6897
 6898            cx.background_spawn(async move {
 6899                let mut responses = Vec::new();
 6900                for diagnostics in join_all(pull_diagnostics).await {
 6901                    responses.extend(diagnostics?);
 6902                }
 6903                Ok(Some(responses))
 6904            })
 6905        }
 6906    }
 6907
 6908    pub fn applicable_inlay_chunks(
 6909        &mut self,
 6910        buffer: &Entity<Buffer>,
 6911        ranges: &[Range<text::Anchor>],
 6912        cx: &mut Context<Self>,
 6913    ) -> Vec<Range<BufferRow>> {
 6914        let buffer_snapshot = buffer.read(cx).snapshot();
 6915        let ranges = ranges
 6916            .iter()
 6917            .map(|range| range.to_point(&buffer_snapshot))
 6918            .collect::<Vec<_>>();
 6919
 6920        self.latest_lsp_data(buffer, cx)
 6921            .inlay_hints
 6922            .applicable_chunks(ranges.as_slice())
 6923            .map(|chunk| chunk.row_range())
 6924            .collect()
 6925    }
 6926
 6927    pub fn invalidate_inlay_hints<'a>(
 6928        &'a mut self,
 6929        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6930    ) {
 6931        for buffer_id in for_buffers {
 6932            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6933                lsp_data.inlay_hints.clear();
 6934            }
 6935        }
 6936    }
 6937
 6938    pub fn inlay_hints(
 6939        &mut self,
 6940        invalidate: InvalidationStrategy,
 6941        buffer: Entity<Buffer>,
 6942        ranges: Vec<Range<text::Anchor>>,
 6943        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6944        cx: &mut Context<Self>,
 6945    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6946        let next_hint_id = self.next_hint_id.clone();
 6947        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6948        let query_version = lsp_data.buffer_version.clone();
 6949        let mut lsp_refresh_requested = false;
 6950        let for_server = if let InvalidationStrategy::RefreshRequested {
 6951            server_id,
 6952            request_id,
 6953        } = invalidate
 6954        {
 6955            let invalidated = lsp_data
 6956                .inlay_hints
 6957                .invalidate_for_server_refresh(server_id, request_id);
 6958            lsp_refresh_requested = invalidated;
 6959            Some(server_id)
 6960        } else {
 6961            None
 6962        };
 6963        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6964        let known_chunks = known_chunks
 6965            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6966            .map(|(_, known_chunks)| known_chunks)
 6967            .unwrap_or_default();
 6968
 6969        let buffer_snapshot = buffer.read(cx).snapshot();
 6970        let ranges = ranges
 6971            .iter()
 6972            .map(|range| range.to_point(&buffer_snapshot))
 6973            .collect::<Vec<_>>();
 6974
 6975        let mut hint_fetch_tasks = Vec::new();
 6976        let mut cached_inlay_hints = None;
 6977        let mut ranges_to_query = None;
 6978        let applicable_chunks = existing_inlay_hints
 6979            .applicable_chunks(ranges.as_slice())
 6980            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 6981            .collect::<Vec<_>>();
 6982        if applicable_chunks.is_empty() {
 6983            return HashMap::default();
 6984        }
 6985
 6986        for row_chunk in applicable_chunks {
 6987            match (
 6988                existing_inlay_hints
 6989                    .cached_hints(&row_chunk)
 6990                    .filter(|_| !lsp_refresh_requested)
 6991                    .cloned(),
 6992                existing_inlay_hints
 6993                    .fetched_hints(&row_chunk)
 6994                    .as_ref()
 6995                    .filter(|_| !lsp_refresh_requested)
 6996                    .cloned(),
 6997            ) {
 6998                (None, None) => {
 6999                    let chunk_range = row_chunk.anchor_range();
 7000                    ranges_to_query
 7001                        .get_or_insert_with(Vec::new)
 7002                        .push((row_chunk, chunk_range));
 7003                }
 7004                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7005                (Some(cached_hints), None) => {
 7006                    for (server_id, cached_hints) in cached_hints {
 7007                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7008                            cached_inlay_hints
 7009                                .get_or_insert_with(HashMap::default)
 7010                                .entry(row_chunk.row_range())
 7011                                .or_insert_with(HashMap::default)
 7012                                .entry(server_id)
 7013                                .or_insert_with(Vec::new)
 7014                                .extend(cached_hints);
 7015                        }
 7016                    }
 7017                }
 7018                (Some(cached_hints), Some(fetched_hints)) => {
 7019                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7020                    for (server_id, cached_hints) in cached_hints {
 7021                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7022                            cached_inlay_hints
 7023                                .get_or_insert_with(HashMap::default)
 7024                                .entry(row_chunk.row_range())
 7025                                .or_insert_with(HashMap::default)
 7026                                .entry(server_id)
 7027                                .or_insert_with(Vec::new)
 7028                                .extend(cached_hints);
 7029                        }
 7030                    }
 7031                }
 7032            }
 7033        }
 7034
 7035        if hint_fetch_tasks.is_empty()
 7036            && ranges_to_query
 7037                .as_ref()
 7038                .is_none_or(|ranges| ranges.is_empty())
 7039            && let Some(cached_inlay_hints) = cached_inlay_hints
 7040        {
 7041            cached_inlay_hints
 7042                .into_iter()
 7043                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7044                .collect()
 7045        } else {
 7046            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7047                // When a server refresh was requested, other servers' cached hints
 7048                // are unaffected by the refresh and must be included in the result.
 7049                // Otherwise apply_fetched_hints (with should_invalidate()=true)
 7050                // removes all visible hints but only adds back the requesting
 7051                // server's new hints, permanently losing other servers' hints.
 7052                let other_servers_cached: CacheInlayHints = if lsp_refresh_requested {
 7053                    lsp_data
 7054                        .inlay_hints
 7055                        .cached_hints(&chunk)
 7056                        .cloned()
 7057                        .unwrap_or_default()
 7058                } else {
 7059                    HashMap::default()
 7060                };
 7061
 7062                let next_hint_id = next_hint_id.clone();
 7063                let buffer = buffer.clone();
 7064                let query_version = query_version.clone();
 7065                let new_inlay_hints = cx
 7066                    .spawn(async move |lsp_store, cx| {
 7067                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7068                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7069                        })?;
 7070                        new_fetch_task
 7071                            .await
 7072                            .and_then(|new_hints_by_server| {
 7073                                lsp_store.update(cx, |lsp_store, cx| {
 7074                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7075                                    let update_cache = lsp_data.buffer_version == query_version;
 7076                                    if new_hints_by_server.is_empty() {
 7077                                        if update_cache {
 7078                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7079                                        }
 7080                                        other_servers_cached
 7081                                    } else {
 7082                                        let mut result = other_servers_cached;
 7083                                        for (server_id, new_hints) in new_hints_by_server {
 7084                                            let new_hints = new_hints
 7085                                                .into_iter()
 7086                                                .map(|new_hint| {
 7087                                                    (
 7088                                                        InlayId::Hint(next_hint_id.fetch_add(
 7089                                                            1,
 7090                                                            atomic::Ordering::AcqRel,
 7091                                                        )),
 7092                                                        new_hint,
 7093                                                    )
 7094                                                })
 7095                                                .collect::<Vec<_>>();
 7096                                            if update_cache {
 7097                                                lsp_data.inlay_hints.insert_new_hints(
 7098                                                    chunk,
 7099                                                    server_id,
 7100                                                    new_hints.clone(),
 7101                                                );
 7102                                            }
 7103                                            result.insert(server_id, new_hints);
 7104                                        }
 7105                                        result
 7106                                    }
 7107                                })
 7108                            })
 7109                            .map_err(Arc::new)
 7110                    })
 7111                    .shared();
 7112
 7113                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7114                *fetch_task = Some(new_inlay_hints.clone());
 7115                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7116            }
 7117
 7118            cached_inlay_hints
 7119                .unwrap_or_default()
 7120                .into_iter()
 7121                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7122                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7123                    (
 7124                        chunk.row_range(),
 7125                        cx.spawn(async move |_, _| {
 7126                            hints_fetch.await.map_err(|e| {
 7127                                if e.error_code() != ErrorCode::Internal {
 7128                                    anyhow!(e.error_code())
 7129                                } else {
 7130                                    anyhow!("{e:#}")
 7131                                }
 7132                            })
 7133                        }),
 7134                    )
 7135                }))
 7136                .collect()
 7137        }
 7138    }
 7139
 7140    fn fetch_inlay_hints(
 7141        &mut self,
 7142        for_server: Option<LanguageServerId>,
 7143        buffer: &Entity<Buffer>,
 7144        range: Range<Anchor>,
 7145        cx: &mut Context<Self>,
 7146    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7147        let request = InlayHints {
 7148            range: range.clone(),
 7149        };
 7150        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7151            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7152                return Task::ready(Ok(HashMap::default()));
 7153            }
 7154            let request_timeout = ProjectSettings::get_global(cx)
 7155                .global_lsp_settings
 7156                .get_request_timeout();
 7157            let request_task = upstream_client.request_lsp(
 7158                project_id,
 7159                for_server.map(|id| id.to_proto()),
 7160                request_timeout,
 7161                cx.background_executor().clone(),
 7162                request.to_proto(project_id, buffer.read(cx)),
 7163            );
 7164            let buffer = buffer.clone();
 7165            cx.spawn(async move |weak_lsp_store, cx| {
 7166                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7167                    return Ok(HashMap::default());
 7168                };
 7169                let Some(responses) = request_task.await? else {
 7170                    return Ok(HashMap::default());
 7171                };
 7172
 7173                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7174                    let lsp_store = lsp_store.clone();
 7175                    let buffer = buffer.clone();
 7176                    let cx = cx.clone();
 7177                    let request = request.clone();
 7178                    async move {
 7179                        (
 7180                            LanguageServerId::from_proto(response.server_id),
 7181                            request
 7182                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7183                                .await,
 7184                        )
 7185                    }
 7186                }))
 7187                .await;
 7188
 7189                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7190                let mut has_errors = false;
 7191                let inlay_hints = inlay_hints
 7192                    .into_iter()
 7193                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7194                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7195                        Err(e) => {
 7196                            has_errors = true;
 7197                            log::error!("{e:#}");
 7198                            None
 7199                        }
 7200                    })
 7201                    .map(|(server_id, mut new_hints)| {
 7202                        new_hints.retain(|hint| {
 7203                            hint.position.is_valid(&buffer_snapshot)
 7204                                && range.start.is_valid(&buffer_snapshot)
 7205                                && range.end.is_valid(&buffer_snapshot)
 7206                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7207                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7208                        });
 7209                        (server_id, new_hints)
 7210                    })
 7211                    .collect::<HashMap<_, _>>();
 7212                anyhow::ensure!(
 7213                    !has_errors || !inlay_hints.is_empty(),
 7214                    "Failed to fetch inlay hints"
 7215                );
 7216                Ok(inlay_hints)
 7217            })
 7218        } else {
 7219            let inlay_hints_task = match for_server {
 7220                Some(server_id) => {
 7221                    let server_task = self.request_lsp(
 7222                        buffer.clone(),
 7223                        LanguageServerToQuery::Other(server_id),
 7224                        request,
 7225                        cx,
 7226                    );
 7227                    cx.background_spawn(async move {
 7228                        let mut responses = Vec::new();
 7229                        match server_task.await {
 7230                            Ok(response) => responses.push((server_id, response)),
 7231                            // rust-analyzer likes to error with this when its still loading up
 7232                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7233                            Err(e) => log::error!(
 7234                                "Error handling response for inlay hints request: {e:#}"
 7235                            ),
 7236                        }
 7237                        responses
 7238                    })
 7239                }
 7240                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7241            };
 7242            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7243            cx.background_spawn(async move {
 7244                Ok(inlay_hints_task
 7245                    .await
 7246                    .into_iter()
 7247                    .map(|(server_id, mut new_hints)| {
 7248                        new_hints.retain(|hint| {
 7249                            hint.position.is_valid(&buffer_snapshot)
 7250                                && range.start.is_valid(&buffer_snapshot)
 7251                                && range.end.is_valid(&buffer_snapshot)
 7252                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7253                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7254                        });
 7255                        (server_id, new_hints)
 7256                    })
 7257                    .collect())
 7258            })
 7259        }
 7260    }
 7261
 7262    fn diagnostic_registration_exists(
 7263        &self,
 7264        server_id: LanguageServerId,
 7265        registration_id: &Option<SharedString>,
 7266    ) -> bool {
 7267        let Some(local) = self.as_local() else {
 7268            return false;
 7269        };
 7270        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7271        else {
 7272            return false;
 7273        };
 7274        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7275        registrations.diagnostics.contains_key(&registration_key)
 7276    }
 7277
 7278    pub fn pull_diagnostics_for_buffer(
 7279        &mut self,
 7280        buffer: Entity<Buffer>,
 7281        cx: &mut Context<Self>,
 7282    ) -> Task<anyhow::Result<()>> {
 7283        let diagnostics = self.pull_diagnostics(buffer, cx);
 7284        cx.spawn(async move |lsp_store, cx| {
 7285            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7286                return Ok(());
 7287            };
 7288            lsp_store.update(cx, |lsp_store, cx| {
 7289                if lsp_store.as_local().is_none() {
 7290                    return;
 7291                }
 7292
 7293                let mut unchanged_buffers = HashMap::default();
 7294                let server_diagnostics_updates = diagnostics
 7295                    .into_iter()
 7296                    .filter_map(|diagnostics_set| match diagnostics_set {
 7297                        LspPullDiagnostics::Response {
 7298                            server_id,
 7299                            uri,
 7300                            diagnostics,
 7301                            registration_id,
 7302                        } => Some((server_id, uri, diagnostics, registration_id)),
 7303                        LspPullDiagnostics::Default => None,
 7304                    })
 7305                    .filter(|(server_id, _, _, registration_id)| {
 7306                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7307                    })
 7308                    .fold(
 7309                        HashMap::default(),
 7310                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7311                            let (result_id, diagnostics) = match diagnostics {
 7312                                PulledDiagnostics::Unchanged { result_id } => {
 7313                                    unchanged_buffers
 7314                                        .entry(new_registration_id.clone())
 7315                                        .or_insert_with(HashSet::default)
 7316                                        .insert(uri.clone());
 7317                                    (Some(result_id), Vec::new())
 7318                                }
 7319                                PulledDiagnostics::Changed {
 7320                                    result_id,
 7321                                    diagnostics,
 7322                                } => (result_id, diagnostics),
 7323                            };
 7324                            let disk_based_sources = Cow::Owned(
 7325                                lsp_store
 7326                                    .language_server_adapter_for_id(server_id)
 7327                                    .as_ref()
 7328                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7329                                    .unwrap_or(&[])
 7330                                    .to_vec(),
 7331                            );
 7332                            acc.entry(server_id)
 7333                                .or_insert_with(HashMap::default)
 7334                                .entry(new_registration_id.clone())
 7335                                .or_insert_with(Vec::new)
 7336                                .push(DocumentDiagnosticsUpdate {
 7337                                    server_id,
 7338                                    diagnostics: lsp::PublishDiagnosticsParams {
 7339                                        uri,
 7340                                        diagnostics,
 7341                                        version: None,
 7342                                    },
 7343                                    result_id: result_id.map(SharedString::new),
 7344                                    disk_based_sources,
 7345                                    registration_id: new_registration_id,
 7346                                });
 7347                            acc
 7348                        },
 7349                    );
 7350
 7351                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7352                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7353                        lsp_store
 7354                            .merge_lsp_diagnostics(
 7355                                DiagnosticSourceKind::Pulled,
 7356                                diagnostic_updates,
 7357                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7358                                    DiagnosticSourceKind::Pulled => {
 7359                                        old_diagnostic.registration_id != registration_id
 7360                                            || unchanged_buffers
 7361                                                .get(&old_diagnostic.registration_id)
 7362                                                .is_some_and(|unchanged_buffers| {
 7363                                                    unchanged_buffers.contains(&document_uri)
 7364                                                })
 7365                                    }
 7366                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7367                                        true
 7368                                    }
 7369                                },
 7370                                cx,
 7371                            )
 7372                            .log_err();
 7373                    }
 7374                }
 7375            })
 7376        })
 7377    }
 7378
 7379    pub fn signature_help<T: ToPointUtf16>(
 7380        &mut self,
 7381        buffer: &Entity<Buffer>,
 7382        position: T,
 7383        cx: &mut Context<Self>,
 7384    ) -> Task<Option<Vec<SignatureHelp>>> {
 7385        let position = position.to_point_utf16(buffer.read(cx));
 7386
 7387        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7388            let request = GetSignatureHelp { position };
 7389            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7390                return Task::ready(None);
 7391            }
 7392            let request_timeout = ProjectSettings::get_global(cx)
 7393                .global_lsp_settings
 7394                .get_request_timeout();
 7395            let request_task = client.request_lsp(
 7396                upstream_project_id,
 7397                None,
 7398                request_timeout,
 7399                cx.background_executor().clone(),
 7400                request.to_proto(upstream_project_id, buffer.read(cx)),
 7401            );
 7402            let buffer = buffer.clone();
 7403            cx.spawn(async move |weak_lsp_store, cx| {
 7404                let lsp_store = weak_lsp_store.upgrade()?;
 7405                let signatures = join_all(
 7406                    request_task
 7407                        .await
 7408                        .log_err()
 7409                        .flatten()
 7410                        .map(|response| response.payload)
 7411                        .unwrap_or_default()
 7412                        .into_iter()
 7413                        .map(|response| {
 7414                            let response = GetSignatureHelp { position }.response_from_proto(
 7415                                response.response,
 7416                                lsp_store.clone(),
 7417                                buffer.clone(),
 7418                                cx.clone(),
 7419                            );
 7420                            async move { response.await.log_err().flatten() }
 7421                        }),
 7422                )
 7423                .await
 7424                .into_iter()
 7425                .flatten()
 7426                .collect();
 7427                Some(signatures)
 7428            })
 7429        } else {
 7430            let all_actions_task = self.request_multiple_lsp_locally(
 7431                buffer,
 7432                Some(position),
 7433                GetSignatureHelp { position },
 7434                cx,
 7435            );
 7436            cx.background_spawn(async move {
 7437                Some(
 7438                    all_actions_task
 7439                        .await
 7440                        .into_iter()
 7441                        .flat_map(|(_, actions)| actions)
 7442                        .collect::<Vec<_>>(),
 7443                )
 7444            })
 7445        }
 7446    }
 7447
 7448    pub fn hover(
 7449        &mut self,
 7450        buffer: &Entity<Buffer>,
 7451        position: PointUtf16,
 7452        cx: &mut Context<Self>,
 7453    ) -> Task<Option<Vec<Hover>>> {
 7454        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7455            let request = GetHover { position };
 7456            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7457                return Task::ready(None);
 7458            }
 7459            let request_timeout = ProjectSettings::get_global(cx)
 7460                .global_lsp_settings
 7461                .get_request_timeout();
 7462            let request_task = client.request_lsp(
 7463                upstream_project_id,
 7464                None,
 7465                request_timeout,
 7466                cx.background_executor().clone(),
 7467                request.to_proto(upstream_project_id, buffer.read(cx)),
 7468            );
 7469            let buffer = buffer.clone();
 7470            cx.spawn(async move |weak_lsp_store, cx| {
 7471                let lsp_store = weak_lsp_store.upgrade()?;
 7472                let hovers = join_all(
 7473                    request_task
 7474                        .await
 7475                        .log_err()
 7476                        .flatten()
 7477                        .map(|response| response.payload)
 7478                        .unwrap_or_default()
 7479                        .into_iter()
 7480                        .map(|response| {
 7481                            let response = GetHover { position }.response_from_proto(
 7482                                response.response,
 7483                                lsp_store.clone(),
 7484                                buffer.clone(),
 7485                                cx.clone(),
 7486                            );
 7487                            async move {
 7488                                response
 7489                                    .await
 7490                                    .log_err()
 7491                                    .flatten()
 7492                                    .and_then(remove_empty_hover_blocks)
 7493                            }
 7494                        }),
 7495                )
 7496                .await
 7497                .into_iter()
 7498                .flatten()
 7499                .collect();
 7500                Some(hovers)
 7501            })
 7502        } else {
 7503            let all_actions_task = self.request_multiple_lsp_locally(
 7504                buffer,
 7505                Some(position),
 7506                GetHover { position },
 7507                cx,
 7508            );
 7509            cx.background_spawn(async move {
 7510                Some(
 7511                    all_actions_task
 7512                        .await
 7513                        .into_iter()
 7514                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7515                        .collect::<Vec<Hover>>(),
 7516                )
 7517            })
 7518        }
 7519    }
 7520
 7521    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7522        let language_registry = self.languages.clone();
 7523
 7524        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7525            let request = upstream_client.request(proto::GetProjectSymbols {
 7526                project_id: *project_id,
 7527                query: query.to_string(),
 7528            });
 7529            cx.foreground_executor().spawn(async move {
 7530                let response = request.await?;
 7531                let mut symbols = Vec::new();
 7532                let core_symbols = response
 7533                    .symbols
 7534                    .into_iter()
 7535                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7536                    .collect::<Vec<_>>();
 7537                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7538                    .await;
 7539                Ok(symbols)
 7540            })
 7541        } else if let Some(local) = self.as_local() {
 7542            struct WorkspaceSymbolsResult {
 7543                server_id: LanguageServerId,
 7544                lsp_adapter: Arc<CachedLspAdapter>,
 7545                worktree: WeakEntity<Worktree>,
 7546                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7547            }
 7548
 7549            let mut requests = Vec::new();
 7550            let mut requested_servers = BTreeSet::new();
 7551            let request_timeout = ProjectSettings::get_global(cx)
 7552                .global_lsp_settings
 7553                .get_request_timeout();
 7554
 7555            for (seed, state) in local.language_server_ids.iter() {
 7556                let Some(worktree_handle) = self
 7557                    .worktree_store
 7558                    .read(cx)
 7559                    .worktree_for_id(seed.worktree_id, cx)
 7560                else {
 7561                    continue;
 7562                };
 7563
 7564                let worktree = worktree_handle.read(cx);
 7565                if !worktree.is_visible() {
 7566                    continue;
 7567                }
 7568
 7569                if !requested_servers.insert(state.id) {
 7570                    continue;
 7571                }
 7572
 7573                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7574                    Some(LanguageServerState::Running {
 7575                        adapter, server, ..
 7576                    }) => (adapter.clone(), server),
 7577
 7578                    _ => continue,
 7579                };
 7580
 7581                let supports_workspace_symbol_request =
 7582                    match server.capabilities().workspace_symbol_provider {
 7583                        Some(OneOf::Left(supported)) => supported,
 7584                        Some(OneOf::Right(_)) => true,
 7585                        None => false,
 7586                    };
 7587
 7588                if !supports_workspace_symbol_request {
 7589                    continue;
 7590                }
 7591
 7592                let worktree_handle = worktree_handle.clone();
 7593                let server_id = server.server_id();
 7594                requests.push(
 7595                    server
 7596                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7597                            lsp::WorkspaceSymbolParams {
 7598                                query: query.to_string(),
 7599                                ..Default::default()
 7600                            },
 7601                            request_timeout,
 7602                        )
 7603                        .map(move |response| {
 7604                            let lsp_symbols = response
 7605                                .into_response()
 7606                                .context("workspace symbols request")
 7607                                .log_err()
 7608                                .flatten()
 7609                                .map(|symbol_response| match symbol_response {
 7610                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7611                                        flat_responses
 7612                                            .into_iter()
 7613                                            .map(|lsp_symbol| {
 7614                                                (
 7615                                                    lsp_symbol.name,
 7616                                                    lsp_symbol.kind,
 7617                                                    lsp_symbol.location,
 7618                                                    lsp_symbol.container_name,
 7619                                                )
 7620                                            })
 7621                                            .collect::<Vec<_>>()
 7622                                    }
 7623                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7624                                        nested_responses
 7625                                            .into_iter()
 7626                                            .filter_map(|lsp_symbol| {
 7627                                                let location = match lsp_symbol.location {
 7628                                                    OneOf::Left(location) => location,
 7629                                                    OneOf::Right(_) => {
 7630                                                        log::error!(
 7631                                                            "Unexpected: client capabilities \
 7632                                                            forbid symbol resolutions in \
 7633                                                            workspace.symbol.resolveSupport"
 7634                                                        );
 7635                                                        return None;
 7636                                                    }
 7637                                                };
 7638                                                Some((
 7639                                                    lsp_symbol.name,
 7640                                                    lsp_symbol.kind,
 7641                                                    location,
 7642                                                    lsp_symbol.container_name,
 7643                                                ))
 7644                                            })
 7645                                            .collect::<Vec<_>>()
 7646                                    }
 7647                                })
 7648                                .unwrap_or_default();
 7649
 7650                            WorkspaceSymbolsResult {
 7651                                server_id,
 7652                                lsp_adapter,
 7653                                worktree: worktree_handle.downgrade(),
 7654                                lsp_symbols,
 7655                            }
 7656                        }),
 7657                );
 7658            }
 7659
 7660            cx.spawn(async move |this, cx| {
 7661                let responses = futures::future::join_all(requests).await;
 7662                let this = match this.upgrade() {
 7663                    Some(this) => this,
 7664                    None => return Ok(Vec::new()),
 7665                };
 7666
 7667                let mut symbols = Vec::new();
 7668                for result in responses {
 7669                    let core_symbols = this.update(cx, |this, cx| {
 7670                        result
 7671                            .lsp_symbols
 7672                            .into_iter()
 7673                            .filter_map(
 7674                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7675                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7676                                    let source_worktree = result.worktree.upgrade()?;
 7677                                    let source_worktree_id = source_worktree.read(cx).id();
 7678
 7679                                    let path = if let Some((tree, rel_path)) =
 7680                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7681                                    {
 7682                                        let worktree_id = tree.read(cx).id();
 7683                                        SymbolLocation::InProject(ProjectPath {
 7684                                            worktree_id,
 7685                                            path: rel_path,
 7686                                        })
 7687                                    } else {
 7688                                        SymbolLocation::OutsideProject {
 7689                                            signature: this.symbol_signature(&abs_path),
 7690                                            abs_path: abs_path.into(),
 7691                                        }
 7692                                    };
 7693
 7694                                    Some(CoreSymbol {
 7695                                        source_language_server_id: result.server_id,
 7696                                        language_server_name: result.lsp_adapter.name.clone(),
 7697                                        source_worktree_id,
 7698                                        path,
 7699                                        kind: symbol_kind,
 7700                                        name: collapse_newlines(&symbol_name, ""),
 7701                                        range: range_from_lsp(symbol_location.range),
 7702                                        container_name: container_name
 7703                                            .map(|c| collapse_newlines(&c, "")),
 7704                                    })
 7705                                },
 7706                            )
 7707                            .collect::<Vec<_>>()
 7708                    });
 7709
 7710                    populate_labels_for_symbols(
 7711                        core_symbols,
 7712                        &language_registry,
 7713                        Some(result.lsp_adapter),
 7714                        &mut symbols,
 7715                    )
 7716                    .await;
 7717                }
 7718
 7719                Ok(symbols)
 7720            })
 7721        } else {
 7722            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7723        }
 7724    }
 7725
 7726    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7727        let mut summary = DiagnosticSummary::default();
 7728        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7729            summary.error_count += path_summary.error_count;
 7730            summary.warning_count += path_summary.warning_count;
 7731        }
 7732        summary
 7733    }
 7734
 7735    /// Returns the diagnostic summary for a specific project path.
 7736    pub fn diagnostic_summary_for_path(
 7737        &self,
 7738        project_path: &ProjectPath,
 7739        _: &App,
 7740    ) -> DiagnosticSummary {
 7741        if let Some(summaries) = self
 7742            .diagnostic_summaries
 7743            .get(&project_path.worktree_id)
 7744            .and_then(|map| map.get(&project_path.path))
 7745        {
 7746            let (error_count, warning_count) = summaries.iter().fold(
 7747                (0, 0),
 7748                |(error_count, warning_count), (_language_server_id, summary)| {
 7749                    (
 7750                        error_count + summary.error_count,
 7751                        warning_count + summary.warning_count,
 7752                    )
 7753                },
 7754            );
 7755
 7756            DiagnosticSummary {
 7757                error_count,
 7758                warning_count,
 7759            }
 7760        } else {
 7761            DiagnosticSummary::default()
 7762        }
 7763    }
 7764
 7765    pub fn diagnostic_summaries<'a>(
 7766        &'a self,
 7767        include_ignored: bool,
 7768        cx: &'a App,
 7769    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7770        self.worktree_store
 7771            .read(cx)
 7772            .visible_worktrees(cx)
 7773            .filter_map(|worktree| {
 7774                let worktree = worktree.read(cx);
 7775                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7776            })
 7777            .flat_map(move |(worktree, summaries)| {
 7778                let worktree_id = worktree.id();
 7779                summaries
 7780                    .iter()
 7781                    .filter(move |(path, _)| {
 7782                        include_ignored
 7783                            || worktree
 7784                                .entry_for_path(path.as_ref())
 7785                                .is_some_and(|entry| !entry.is_ignored)
 7786                    })
 7787                    .flat_map(move |(path, summaries)| {
 7788                        summaries.iter().map(move |(server_id, summary)| {
 7789                            (
 7790                                ProjectPath {
 7791                                    worktree_id,
 7792                                    path: path.clone(),
 7793                                },
 7794                                *server_id,
 7795                                *summary,
 7796                            )
 7797                        })
 7798                    })
 7799            })
 7800    }
 7801
 7802    pub fn on_buffer_edited(
 7803        &mut self,
 7804        buffer: Entity<Buffer>,
 7805        cx: &mut Context<Self>,
 7806    ) -> Option<()> {
 7807        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7808            Some(
 7809                self.as_local()?
 7810                    .language_servers_for_buffer(buffer, cx)
 7811                    .map(|i| i.1.clone())
 7812                    .collect(),
 7813            )
 7814        })?;
 7815
 7816        let buffer = buffer.read(cx);
 7817        let file = File::from_dyn(buffer.file())?;
 7818        let abs_path = file.as_local()?.abs_path(cx);
 7819        let uri = lsp::Uri::from_file_path(&abs_path)
 7820            .ok()
 7821            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7822            .log_err()?;
 7823        let next_snapshot = buffer.text_snapshot();
 7824        for language_server in language_servers {
 7825            let language_server = language_server.clone();
 7826
 7827            let buffer_snapshots = self
 7828                .as_local_mut()?
 7829                .buffer_snapshots
 7830                .get_mut(&buffer.remote_id())
 7831                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7832            let previous_snapshot = buffer_snapshots.last()?;
 7833
 7834            let build_incremental_change = || {
 7835                buffer
 7836                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7837                        previous_snapshot.snapshot.version(),
 7838                    )
 7839                    .map(|edit| {
 7840                        let edit_start = edit.new.start.0;
 7841                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7842                        let new_text = next_snapshot
 7843                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7844                            .collect();
 7845                        lsp::TextDocumentContentChangeEvent {
 7846                            range: Some(lsp::Range::new(
 7847                                point_to_lsp(edit_start),
 7848                                point_to_lsp(edit_end),
 7849                            )),
 7850                            range_length: None,
 7851                            text: new_text,
 7852                        }
 7853                    })
 7854                    .collect()
 7855            };
 7856
 7857            let document_sync_kind = language_server
 7858                .capabilities()
 7859                .text_document_sync
 7860                .as_ref()
 7861                .and_then(|sync| match sync {
 7862                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7863                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7864                });
 7865
 7866            let content_changes: Vec<_> = match document_sync_kind {
 7867                Some(lsp::TextDocumentSyncKind::FULL) => {
 7868                    vec![lsp::TextDocumentContentChangeEvent {
 7869                        range: None,
 7870                        range_length: None,
 7871                        text: next_snapshot.text(),
 7872                    }]
 7873                }
 7874                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7875                _ => {
 7876                    #[cfg(any(test, feature = "test-support"))]
 7877                    {
 7878                        build_incremental_change()
 7879                    }
 7880
 7881                    #[cfg(not(any(test, feature = "test-support")))]
 7882                    {
 7883                        continue;
 7884                    }
 7885                }
 7886            };
 7887
 7888            let next_version = previous_snapshot.version + 1;
 7889            buffer_snapshots.push(LspBufferSnapshot {
 7890                version: next_version,
 7891                snapshot: next_snapshot.clone(),
 7892            });
 7893
 7894            language_server
 7895                .notify::<lsp::notification::DidChangeTextDocument>(
 7896                    lsp::DidChangeTextDocumentParams {
 7897                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7898                            uri.clone(),
 7899                            next_version,
 7900                        ),
 7901                        content_changes,
 7902                    },
 7903                )
 7904                .ok();
 7905            self.pull_workspace_diagnostics(language_server.server_id());
 7906        }
 7907
 7908        None
 7909    }
 7910
 7911    pub fn on_buffer_saved(
 7912        &mut self,
 7913        buffer: Entity<Buffer>,
 7914        cx: &mut Context<Self>,
 7915    ) -> Option<()> {
 7916        let file = File::from_dyn(buffer.read(cx).file())?;
 7917        let worktree_id = file.worktree_id(cx);
 7918        let abs_path = file.as_local()?.abs_path(cx);
 7919        let text_document = lsp::TextDocumentIdentifier {
 7920            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7921        };
 7922        let local = self.as_local()?;
 7923
 7924        for server in local.language_servers_for_worktree(worktree_id) {
 7925            if let Some(include_text) = include_text(server.as_ref()) {
 7926                let text = if include_text {
 7927                    Some(buffer.read(cx).text())
 7928                } else {
 7929                    None
 7930                };
 7931                server
 7932                    .notify::<lsp::notification::DidSaveTextDocument>(
 7933                        lsp::DidSaveTextDocumentParams {
 7934                            text_document: text_document.clone(),
 7935                            text,
 7936                        },
 7937                    )
 7938                    .ok();
 7939            }
 7940        }
 7941
 7942        let language_servers = buffer.update(cx, |buffer, cx| {
 7943            local.language_server_ids_for_buffer(buffer, cx)
 7944        });
 7945        for language_server_id in language_servers {
 7946            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7947        }
 7948
 7949        None
 7950    }
 7951
 7952    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7953        maybe!(async move {
 7954            let mut refreshed_servers = HashSet::default();
 7955            let servers = lsp_store
 7956                .update(cx, |lsp_store, cx| {
 7957                    let local = lsp_store.as_local()?;
 7958
 7959                    let servers = local
 7960                        .language_server_ids
 7961                        .iter()
 7962                        .filter_map(|(seed, state)| {
 7963                            let worktree = lsp_store
 7964                                .worktree_store
 7965                                .read(cx)
 7966                                .worktree_for_id(seed.worktree_id, cx);
 7967                            let delegate: Arc<dyn LspAdapterDelegate> =
 7968                                worktree.map(|worktree| {
 7969                                    LocalLspAdapterDelegate::new(
 7970                                        local.languages.clone(),
 7971                                        &local.environment,
 7972                                        cx.weak_entity(),
 7973                                        &worktree,
 7974                                        local.http_client.clone(),
 7975                                        local.fs.clone(),
 7976                                        cx,
 7977                                    )
 7978                                })?;
 7979                            let server_id = state.id;
 7980
 7981                            let states = local.language_servers.get(&server_id)?;
 7982
 7983                            match states {
 7984                                LanguageServerState::Starting { .. } => None,
 7985                                LanguageServerState::Running {
 7986                                    adapter, server, ..
 7987                                } => {
 7988                                    let adapter = adapter.clone();
 7989                                    let server = server.clone();
 7990                                    refreshed_servers.insert(server.name());
 7991                                    let toolchain = seed.toolchain.clone();
 7992                                    Some(cx.spawn(async move |_, cx| {
 7993                                        let settings =
 7994                                            LocalLspStore::workspace_configuration_for_adapter(
 7995                                                adapter.adapter.clone(),
 7996                                                &delegate,
 7997                                                toolchain,
 7998                                                None,
 7999                                                cx,
 8000                                            )
 8001                                            .await
 8002                                            .ok()?;
 8003                                        server
 8004                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8005                                                lsp::DidChangeConfigurationParams { settings },
 8006                                            )
 8007                                            .ok()?;
 8008                                        Some(())
 8009                                    }))
 8010                                }
 8011                            }
 8012                        })
 8013                        .collect::<Vec<_>>();
 8014
 8015                    Some(servers)
 8016                })
 8017                .ok()
 8018                .flatten()?;
 8019
 8020            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8021            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8022            // to stop and unregister its language server wrapper.
 8023            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8024            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8025            let _: Vec<Option<()>> = join_all(servers).await;
 8026
 8027            Some(())
 8028        })
 8029        .await;
 8030    }
 8031
 8032    fn maintain_workspace_config(
 8033        external_refresh_requests: watch::Receiver<()>,
 8034        cx: &mut Context<Self>,
 8035    ) -> Task<Result<()>> {
 8036        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8037        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8038
 8039        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8040            *settings_changed_tx.borrow_mut() = ();
 8041        });
 8042
 8043        let mut joint_future =
 8044            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8045        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8046        // - 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).
 8047        // - 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.
 8048        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8049        // - 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,
 8050        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8051        cx.spawn(async move |this, cx| {
 8052            while let Some(()) = joint_future.next().await {
 8053                this.update(cx, |this, cx| {
 8054                    this.refresh_server_tree(cx);
 8055                })
 8056                .ok();
 8057
 8058                Self::refresh_workspace_configurations(&this, cx).await;
 8059            }
 8060
 8061            drop(settings_observation);
 8062            anyhow::Ok(())
 8063        })
 8064    }
 8065
 8066    pub fn running_language_servers_for_local_buffer<'a>(
 8067        &'a self,
 8068        buffer: &Buffer,
 8069        cx: &mut App,
 8070    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8071        let local = self.as_local();
 8072        let language_server_ids = local
 8073            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8074            .unwrap_or_default();
 8075
 8076        language_server_ids
 8077            .into_iter()
 8078            .filter_map(
 8079                move |server_id| match local?.language_servers.get(&server_id)? {
 8080                    LanguageServerState::Running {
 8081                        adapter, server, ..
 8082                    } => Some((adapter, server)),
 8083                    _ => None,
 8084                },
 8085            )
 8086    }
 8087
 8088    pub fn language_servers_for_local_buffer(
 8089        &self,
 8090        buffer: &Buffer,
 8091        cx: &mut App,
 8092    ) -> Vec<LanguageServerId> {
 8093        let local = self.as_local();
 8094        local
 8095            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8096            .unwrap_or_default()
 8097    }
 8098
 8099    pub fn language_server_for_local_buffer<'a>(
 8100        &'a self,
 8101        buffer: &'a Buffer,
 8102        server_id: LanguageServerId,
 8103        cx: &'a mut App,
 8104    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8105        self.as_local()?
 8106            .language_servers_for_buffer(buffer, cx)
 8107            .find(|(_, s)| s.server_id() == server_id)
 8108    }
 8109
 8110    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8111        self.diagnostic_summaries.remove(&id_to_remove);
 8112        if let Some(local) = self.as_local_mut() {
 8113            let to_remove = local.remove_worktree(id_to_remove, cx);
 8114            for server in to_remove {
 8115                self.language_server_statuses.remove(&server);
 8116            }
 8117        }
 8118    }
 8119
 8120    pub fn shared(
 8121        &mut self,
 8122        project_id: u64,
 8123        downstream_client: AnyProtoClient,
 8124        _: &mut Context<Self>,
 8125    ) {
 8126        self.downstream_client = Some((downstream_client.clone(), project_id));
 8127
 8128        for (server_id, status) in &self.language_server_statuses {
 8129            if let Some(server) = self.language_server_for_id(*server_id) {
 8130                downstream_client
 8131                    .send(proto::StartLanguageServer {
 8132                        project_id,
 8133                        server: Some(proto::LanguageServer {
 8134                            id: server_id.to_proto(),
 8135                            name: status.name.to_string(),
 8136                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8137                        }),
 8138                        capabilities: serde_json::to_string(&server.capabilities())
 8139                            .expect("serializing server LSP capabilities"),
 8140                    })
 8141                    .log_err();
 8142            }
 8143        }
 8144    }
 8145
 8146    pub fn disconnected_from_host(&mut self) {
 8147        self.downstream_client.take();
 8148    }
 8149
 8150    pub fn disconnected_from_ssh_remote(&mut self) {
 8151        if let LspStoreMode::Remote(RemoteLspStore {
 8152            upstream_client, ..
 8153        }) = &mut self.mode
 8154        {
 8155            upstream_client.take();
 8156        }
 8157    }
 8158
 8159    pub(crate) fn set_language_server_statuses_from_proto(
 8160        &mut self,
 8161        project: WeakEntity<Project>,
 8162        language_servers: Vec<proto::LanguageServer>,
 8163        server_capabilities: Vec<String>,
 8164        cx: &mut Context<Self>,
 8165    ) {
 8166        let lsp_logs = cx
 8167            .try_global::<GlobalLogStore>()
 8168            .map(|lsp_store| lsp_store.0.clone());
 8169
 8170        self.language_server_statuses = language_servers
 8171            .into_iter()
 8172            .zip(server_capabilities)
 8173            .map(|(server, server_capabilities)| {
 8174                let server_id = LanguageServerId(server.id as usize);
 8175                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8176                    self.lsp_server_capabilities
 8177                        .insert(server_id, server_capabilities);
 8178                }
 8179
 8180                let name = LanguageServerName::from_proto(server.name);
 8181                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8182
 8183                if let Some(lsp_logs) = &lsp_logs {
 8184                    lsp_logs.update(cx, |lsp_logs, cx| {
 8185                        lsp_logs.add_language_server(
 8186                            // Only remote clients get their language servers set from proto
 8187                            LanguageServerKind::Remote {
 8188                                project: project.clone(),
 8189                            },
 8190                            server_id,
 8191                            Some(name.clone()),
 8192                            worktree,
 8193                            None,
 8194                            cx,
 8195                        );
 8196                    });
 8197                }
 8198
 8199                (
 8200                    server_id,
 8201                    LanguageServerStatus {
 8202                        name,
 8203                        server_version: None,
 8204                        pending_work: Default::default(),
 8205                        has_pending_diagnostic_updates: false,
 8206                        progress_tokens: Default::default(),
 8207                        worktree,
 8208                        binary: None,
 8209                        configuration: None,
 8210                        workspace_folders: BTreeSet::new(),
 8211                        process_id: None,
 8212                    },
 8213                )
 8214            })
 8215            .collect();
 8216    }
 8217
 8218    #[cfg(feature = "test-support")]
 8219    pub fn update_diagnostic_entries(
 8220        &mut self,
 8221        server_id: LanguageServerId,
 8222        abs_path: PathBuf,
 8223        result_id: Option<SharedString>,
 8224        version: Option<i32>,
 8225        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8226        cx: &mut Context<Self>,
 8227    ) -> anyhow::Result<()> {
 8228        self.merge_diagnostic_entries(
 8229            vec![DocumentDiagnosticsUpdate {
 8230                diagnostics: DocumentDiagnostics {
 8231                    diagnostics,
 8232                    document_abs_path: abs_path,
 8233                    version,
 8234                },
 8235                result_id,
 8236                server_id,
 8237                disk_based_sources: Cow::Borrowed(&[]),
 8238                registration_id: None,
 8239            }],
 8240            |_, _, _| false,
 8241            cx,
 8242        )?;
 8243        Ok(())
 8244    }
 8245
 8246    pub fn merge_diagnostic_entries<'a>(
 8247        &mut self,
 8248        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8249        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8250        cx: &mut Context<Self>,
 8251    ) -> anyhow::Result<()> {
 8252        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8253        let mut updated_diagnostics_paths = HashMap::default();
 8254        for mut update in diagnostic_updates {
 8255            let abs_path = &update.diagnostics.document_abs_path;
 8256            let server_id = update.server_id;
 8257            let Some((worktree, relative_path)) =
 8258                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8259            else {
 8260                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8261                return Ok(());
 8262            };
 8263
 8264            let worktree_id = worktree.read(cx).id();
 8265            let project_path = ProjectPath {
 8266                worktree_id,
 8267                path: relative_path,
 8268            };
 8269
 8270            let document_uri = lsp::Uri::from_file_path(abs_path)
 8271                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8272            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8273                let snapshot = buffer_handle.read(cx).snapshot();
 8274                let buffer = buffer_handle.read(cx);
 8275                let reused_diagnostics = buffer
 8276                    .buffer_diagnostics(Some(server_id))
 8277                    .iter()
 8278                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8279                    .map(|v| {
 8280                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8281                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8282                        DiagnosticEntry {
 8283                            range: start..end,
 8284                            diagnostic: v.diagnostic.clone(),
 8285                        }
 8286                    })
 8287                    .collect::<Vec<_>>();
 8288
 8289                self.as_local_mut()
 8290                    .context("cannot merge diagnostics on a remote LspStore")?
 8291                    .update_buffer_diagnostics(
 8292                        &buffer_handle,
 8293                        server_id,
 8294                        Some(update.registration_id),
 8295                        update.result_id,
 8296                        update.diagnostics.version,
 8297                        update.diagnostics.diagnostics.clone(),
 8298                        reused_diagnostics.clone(),
 8299                        cx,
 8300                    )?;
 8301
 8302                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8303            } else if let Some(local) = self.as_local() {
 8304                let reused_diagnostics = local
 8305                    .diagnostics
 8306                    .get(&worktree_id)
 8307                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8308                    .and_then(|diagnostics_by_server_id| {
 8309                        diagnostics_by_server_id
 8310                            .binary_search_by_key(&server_id, |e| e.0)
 8311                            .ok()
 8312                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8313                    })
 8314                    .into_iter()
 8315                    .flatten()
 8316                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8317
 8318                update
 8319                    .diagnostics
 8320                    .diagnostics
 8321                    .extend(reused_diagnostics.cloned());
 8322            }
 8323
 8324            let updated = worktree.update(cx, |worktree, cx| {
 8325                self.update_worktree_diagnostics(
 8326                    worktree.id(),
 8327                    server_id,
 8328                    project_path.path.clone(),
 8329                    update.diagnostics.diagnostics,
 8330                    cx,
 8331                )
 8332            })?;
 8333            match updated {
 8334                ControlFlow::Continue(new_summary) => {
 8335                    if let Some((project_id, new_summary)) = new_summary {
 8336                        match &mut diagnostics_summary {
 8337                            Some(diagnostics_summary) => {
 8338                                diagnostics_summary
 8339                                    .more_summaries
 8340                                    .push(proto::DiagnosticSummary {
 8341                                        path: project_path.path.as_ref().to_proto(),
 8342                                        language_server_id: server_id.0 as u64,
 8343                                        error_count: new_summary.error_count,
 8344                                        warning_count: new_summary.warning_count,
 8345                                    })
 8346                            }
 8347                            None => {
 8348                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8349                                    project_id,
 8350                                    worktree_id: worktree_id.to_proto(),
 8351                                    summary: Some(proto::DiagnosticSummary {
 8352                                        path: project_path.path.as_ref().to_proto(),
 8353                                        language_server_id: server_id.0 as u64,
 8354                                        error_count: new_summary.error_count,
 8355                                        warning_count: new_summary.warning_count,
 8356                                    }),
 8357                                    more_summaries: Vec::new(),
 8358                                })
 8359                            }
 8360                        }
 8361                    }
 8362                    updated_diagnostics_paths
 8363                        .entry(server_id)
 8364                        .or_insert_with(Vec::new)
 8365                        .push(project_path);
 8366                }
 8367                ControlFlow::Break(()) => {}
 8368            }
 8369        }
 8370
 8371        if let Some((diagnostics_summary, (downstream_client, _))) =
 8372            diagnostics_summary.zip(self.downstream_client.as_ref())
 8373        {
 8374            downstream_client.send(diagnostics_summary).log_err();
 8375        }
 8376        for (server_id, paths) in updated_diagnostics_paths {
 8377            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8378        }
 8379        Ok(())
 8380    }
 8381
 8382    fn update_worktree_diagnostics(
 8383        &mut self,
 8384        worktree_id: WorktreeId,
 8385        server_id: LanguageServerId,
 8386        path_in_worktree: Arc<RelPath>,
 8387        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8388        _: &mut Context<Worktree>,
 8389    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8390        let local = match &mut self.mode {
 8391            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8392            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8393        };
 8394
 8395        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8396        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8397        let summaries_by_server_id = summaries_for_tree
 8398            .entry(path_in_worktree.clone())
 8399            .or_default();
 8400
 8401        let old_summary = summaries_by_server_id
 8402            .remove(&server_id)
 8403            .unwrap_or_default();
 8404
 8405        let new_summary = DiagnosticSummary::new(&diagnostics);
 8406        if diagnostics.is_empty() {
 8407            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8408            {
 8409                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8410                    diagnostics_by_server_id.remove(ix);
 8411                }
 8412                if diagnostics_by_server_id.is_empty() {
 8413                    diagnostics_for_tree.remove(&path_in_worktree);
 8414                }
 8415            }
 8416        } else {
 8417            summaries_by_server_id.insert(server_id, new_summary);
 8418            let diagnostics_by_server_id = diagnostics_for_tree
 8419                .entry(path_in_worktree.clone())
 8420                .or_default();
 8421            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8422                Ok(ix) => {
 8423                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8424                }
 8425                Err(ix) => {
 8426                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8427                }
 8428            }
 8429        }
 8430
 8431        if !old_summary.is_empty() || !new_summary.is_empty() {
 8432            if let Some((_, project_id)) = &self.downstream_client {
 8433                Ok(ControlFlow::Continue(Some((
 8434                    *project_id,
 8435                    proto::DiagnosticSummary {
 8436                        path: path_in_worktree.to_proto(),
 8437                        language_server_id: server_id.0 as u64,
 8438                        error_count: new_summary.error_count as u32,
 8439                        warning_count: new_summary.warning_count as u32,
 8440                    },
 8441                ))))
 8442            } else {
 8443                Ok(ControlFlow::Continue(None))
 8444            }
 8445        } else {
 8446            Ok(ControlFlow::Break(()))
 8447        }
 8448    }
 8449
 8450    pub fn open_buffer_for_symbol(
 8451        &mut self,
 8452        symbol: &Symbol,
 8453        cx: &mut Context<Self>,
 8454    ) -> Task<Result<Entity<Buffer>>> {
 8455        if let Some((client, project_id)) = self.upstream_client() {
 8456            let request = client.request(proto::OpenBufferForSymbol {
 8457                project_id,
 8458                symbol: Some(Self::serialize_symbol(symbol)),
 8459            });
 8460            cx.spawn(async move |this, cx| {
 8461                let response = request.await?;
 8462                let buffer_id = BufferId::new(response.buffer_id)?;
 8463                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8464                    .await
 8465            })
 8466        } else if let Some(local) = self.as_local() {
 8467            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8468                seed.worktree_id == symbol.source_worktree_id
 8469                    && state.id == symbol.source_language_server_id
 8470                    && symbol.language_server_name == seed.name
 8471            });
 8472            if !is_valid {
 8473                return Task::ready(Err(anyhow!(
 8474                    "language server for worktree and language not found"
 8475                )));
 8476            };
 8477
 8478            let symbol_abs_path = match &symbol.path {
 8479                SymbolLocation::InProject(project_path) => self
 8480                    .worktree_store
 8481                    .read(cx)
 8482                    .absolutize(&project_path, cx)
 8483                    .context("no such worktree"),
 8484                SymbolLocation::OutsideProject {
 8485                    abs_path,
 8486                    signature: _,
 8487                } => Ok(abs_path.to_path_buf()),
 8488            };
 8489            let symbol_abs_path = match symbol_abs_path {
 8490                Ok(abs_path) => abs_path,
 8491                Err(err) => return Task::ready(Err(err)),
 8492            };
 8493            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8494                uri
 8495            } else {
 8496                return Task::ready(Err(anyhow!("invalid symbol path")));
 8497            };
 8498
 8499            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8500        } else {
 8501            Task::ready(Err(anyhow!("no upstream client or local store")))
 8502        }
 8503    }
 8504
 8505    pub(crate) fn open_local_buffer_via_lsp(
 8506        &mut self,
 8507        abs_path: lsp::Uri,
 8508        language_server_id: LanguageServerId,
 8509        cx: &mut Context<Self>,
 8510    ) -> Task<Result<Entity<Buffer>>> {
 8511        let path_style = self.worktree_store.read(cx).path_style();
 8512        cx.spawn(async move |lsp_store, cx| {
 8513            // Escape percent-encoded string.
 8514            let current_scheme = abs_path.scheme().to_owned();
 8515            // Uri is immutable, so we can't modify the scheme
 8516
 8517            let abs_path = abs_path
 8518                .to_file_path_ext(path_style)
 8519                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8520            let p = abs_path.clone();
 8521            let yarn_worktree = lsp_store
 8522                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8523                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8524                        cx.spawn(async move |this, cx| {
 8525                            let t = this
 8526                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8527                                .ok()?;
 8528                            t.await
 8529                        })
 8530                    }),
 8531                    None => Task::ready(None),
 8532                })?
 8533                .await;
 8534            let (worktree_root_target, known_relative_path) =
 8535                if let Some((zip_root, relative_path)) = yarn_worktree {
 8536                    (zip_root, Some(relative_path))
 8537                } else {
 8538                    (Arc::<Path>::from(abs_path.as_path()), None)
 8539                };
 8540            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8541                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8542                    worktree_store.find_worktree(&worktree_root_target, cx)
 8543                })
 8544            })?;
 8545            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8546                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8547                (result.0, relative_path, None)
 8548            } else {
 8549                let worktree = lsp_store
 8550                    .update(cx, |lsp_store, cx| {
 8551                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8552                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8553                        })
 8554                    })?
 8555                    .await?;
 8556                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8557                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8558                    lsp_store
 8559                        .update(cx, |lsp_store, cx| {
 8560                            if let Some(local) = lsp_store.as_local_mut() {
 8561                                local.register_language_server_for_invisible_worktree(
 8562                                    &worktree,
 8563                                    language_server_id,
 8564                                    cx,
 8565                                )
 8566                            }
 8567                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8568                                Some(status) => status.worktree,
 8569                                None => None,
 8570                            }
 8571                        })
 8572                        .ok()
 8573                        .flatten()
 8574                        .zip(Some(worktree_root.clone()))
 8575                } else {
 8576                    None
 8577                };
 8578                let relative_path = if let Some(known_path) = known_relative_path {
 8579                    known_path
 8580                } else {
 8581                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8582                        .into_arc()
 8583                };
 8584                (worktree, relative_path, source_ws)
 8585            };
 8586            let project_path = ProjectPath {
 8587                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8588                path: relative_path,
 8589            };
 8590            let buffer = lsp_store
 8591                .update(cx, |lsp_store, cx| {
 8592                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8593                        buffer_store.open_buffer(project_path, cx)
 8594                    })
 8595                })?
 8596                .await?;
 8597            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8598            if let Some((source_ws, worktree_root)) = source_ws {
 8599                buffer.update(cx, |buffer, cx| {
 8600                    let settings = WorktreeSettings::get(
 8601                        Some(
 8602                            (&ProjectPath {
 8603                                worktree_id: source_ws,
 8604                                path: Arc::from(RelPath::empty()),
 8605                            })
 8606                                .into(),
 8607                        ),
 8608                        cx,
 8609                    );
 8610                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8611                    if is_read_only {
 8612                        buffer.set_capability(Capability::ReadOnly, cx);
 8613                    }
 8614                });
 8615            }
 8616            Ok(buffer)
 8617        })
 8618    }
 8619
 8620    fn local_lsp_servers_for_buffer(
 8621        &self,
 8622        buffer: &Entity<Buffer>,
 8623        cx: &mut Context<Self>,
 8624    ) -> Vec<LanguageServerId> {
 8625        let Some(local) = self.as_local() else {
 8626            return Vec::new();
 8627        };
 8628
 8629        let snapshot = buffer.read(cx).snapshot();
 8630
 8631        buffer.update(cx, |buffer, cx| {
 8632            local
 8633                .language_servers_for_buffer(buffer, cx)
 8634                .map(|(_, server)| server.server_id())
 8635                .filter(|server_id| {
 8636                    self.as_local().is_none_or(|local| {
 8637                        local
 8638                            .buffers_opened_in_servers
 8639                            .get(&snapshot.remote_id())
 8640                            .is_some_and(|servers| servers.contains(server_id))
 8641                    })
 8642                })
 8643                .collect()
 8644        })
 8645    }
 8646
 8647    fn request_multiple_lsp_locally<P, R>(
 8648        &mut self,
 8649        buffer: &Entity<Buffer>,
 8650        position: Option<P>,
 8651        request: R,
 8652        cx: &mut Context<Self>,
 8653    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8654    where
 8655        P: ToOffset,
 8656        R: LspCommand + Clone,
 8657        <R::LspRequest as lsp::request::Request>::Result: Send,
 8658        <R::LspRequest as lsp::request::Request>::Params: Send,
 8659    {
 8660        let Some(local) = self.as_local() else {
 8661            return Task::ready(Vec::new());
 8662        };
 8663
 8664        let snapshot = buffer.read(cx).snapshot();
 8665        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8666
 8667        let server_ids = buffer.update(cx, |buffer, cx| {
 8668            local
 8669                .language_servers_for_buffer(buffer, cx)
 8670                .filter(|(adapter, _)| {
 8671                    scope
 8672                        .as_ref()
 8673                        .map(|scope| scope.language_allowed(&adapter.name))
 8674                        .unwrap_or(true)
 8675                })
 8676                .map(|(_, server)| server.server_id())
 8677                .filter(|server_id| {
 8678                    self.as_local().is_none_or(|local| {
 8679                        local
 8680                            .buffers_opened_in_servers
 8681                            .get(&snapshot.remote_id())
 8682                            .is_some_and(|servers| servers.contains(server_id))
 8683                    })
 8684                })
 8685                .collect::<Vec<_>>()
 8686        });
 8687
 8688        let mut response_results = server_ids
 8689            .into_iter()
 8690            .map(|server_id| {
 8691                let task = self.request_lsp(
 8692                    buffer.clone(),
 8693                    LanguageServerToQuery::Other(server_id),
 8694                    request.clone(),
 8695                    cx,
 8696                );
 8697                async move { (server_id, task.await) }
 8698            })
 8699            .collect::<FuturesUnordered<_>>();
 8700
 8701        cx.background_spawn(async move {
 8702            let mut responses = Vec::with_capacity(response_results.len());
 8703            while let Some((server_id, response_result)) = response_results.next().await {
 8704                match response_result {
 8705                    Ok(response) => responses.push((server_id, response)),
 8706                    // rust-analyzer likes to error with this when its still loading up
 8707                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8708                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8709                }
 8710            }
 8711            responses
 8712        })
 8713    }
 8714
 8715    async fn handle_lsp_get_completions(
 8716        this: Entity<Self>,
 8717        envelope: TypedEnvelope<proto::GetCompletions>,
 8718        mut cx: AsyncApp,
 8719    ) -> Result<proto::GetCompletionsResponse> {
 8720        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8721
 8722        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8723        let buffer_handle = this.update(&mut cx, |this, cx| {
 8724            this.buffer_store.read(cx).get_existing(buffer_id)
 8725        })?;
 8726        let request = GetCompletions::from_proto(
 8727            envelope.payload,
 8728            this.clone(),
 8729            buffer_handle.clone(),
 8730            cx.clone(),
 8731        )
 8732        .await?;
 8733
 8734        let server_to_query = match request.server_id {
 8735            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8736            None => LanguageServerToQuery::FirstCapable,
 8737        };
 8738
 8739        let response = this
 8740            .update(&mut cx, |this, cx| {
 8741                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8742            })
 8743            .await?;
 8744        this.update(&mut cx, |this, cx| {
 8745            Ok(GetCompletions::response_to_proto(
 8746                response,
 8747                this,
 8748                sender_id,
 8749                &buffer_handle.read(cx).version(),
 8750                cx,
 8751            ))
 8752        })
 8753    }
 8754
 8755    async fn handle_lsp_command<T: LspCommand>(
 8756        this: Entity<Self>,
 8757        envelope: TypedEnvelope<T::ProtoRequest>,
 8758        mut cx: AsyncApp,
 8759    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8760    where
 8761        <T::LspRequest as lsp::request::Request>::Params: Send,
 8762        <T::LspRequest as lsp::request::Request>::Result: Send,
 8763    {
 8764        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8765        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8766        let buffer_handle = this.update(&mut cx, |this, cx| {
 8767            this.buffer_store.read(cx).get_existing(buffer_id)
 8768        })?;
 8769        let request = T::from_proto(
 8770            envelope.payload,
 8771            this.clone(),
 8772            buffer_handle.clone(),
 8773            cx.clone(),
 8774        )
 8775        .await?;
 8776        let response = this
 8777            .update(&mut cx, |this, cx| {
 8778                this.request_lsp(
 8779                    buffer_handle.clone(),
 8780                    LanguageServerToQuery::FirstCapable,
 8781                    request,
 8782                    cx,
 8783                )
 8784            })
 8785            .await?;
 8786        this.update(&mut cx, |this, cx| {
 8787            Ok(T::response_to_proto(
 8788                response,
 8789                this,
 8790                sender_id,
 8791                &buffer_handle.read(cx).version(),
 8792                cx,
 8793            ))
 8794        })
 8795    }
 8796
 8797    async fn handle_lsp_query(
 8798        lsp_store: Entity<Self>,
 8799        envelope: TypedEnvelope<proto::LspQuery>,
 8800        mut cx: AsyncApp,
 8801    ) -> Result<proto::Ack> {
 8802        use proto::lsp_query::Request;
 8803        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8804        let lsp_query = envelope.payload;
 8805        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8806        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8807        match lsp_query.request.context("invalid LSP query request")? {
 8808            Request::GetReferences(get_references) => {
 8809                let position = get_references.position.clone().and_then(deserialize_anchor);
 8810                Self::query_lsp_locally::<GetReferences>(
 8811                    lsp_store,
 8812                    server_id,
 8813                    sender_id,
 8814                    lsp_request_id,
 8815                    get_references,
 8816                    position,
 8817                    &mut cx,
 8818                )
 8819                .await?;
 8820            }
 8821            Request::GetDocumentColor(get_document_color) => {
 8822                Self::query_lsp_locally::<GetDocumentColor>(
 8823                    lsp_store,
 8824                    server_id,
 8825                    sender_id,
 8826                    lsp_request_id,
 8827                    get_document_color,
 8828                    None,
 8829                    &mut cx,
 8830                )
 8831                .await?;
 8832            }
 8833            Request::GetFoldingRanges(get_folding_ranges) => {
 8834                Self::query_lsp_locally::<GetFoldingRanges>(
 8835                    lsp_store,
 8836                    server_id,
 8837                    sender_id,
 8838                    lsp_request_id,
 8839                    get_folding_ranges,
 8840                    None,
 8841                    &mut cx,
 8842                )
 8843                .await?;
 8844            }
 8845            Request::GetDocumentSymbols(get_document_symbols) => {
 8846                Self::query_lsp_locally::<GetDocumentSymbols>(
 8847                    lsp_store,
 8848                    server_id,
 8849                    sender_id,
 8850                    lsp_request_id,
 8851                    get_document_symbols,
 8852                    None,
 8853                    &mut cx,
 8854                )
 8855                .await?;
 8856            }
 8857            Request::GetHover(get_hover) => {
 8858                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8859                Self::query_lsp_locally::<GetHover>(
 8860                    lsp_store,
 8861                    server_id,
 8862                    sender_id,
 8863                    lsp_request_id,
 8864                    get_hover,
 8865                    position,
 8866                    &mut cx,
 8867                )
 8868                .await?;
 8869            }
 8870            Request::GetCodeActions(get_code_actions) => {
 8871                Self::query_lsp_locally::<GetCodeActions>(
 8872                    lsp_store,
 8873                    server_id,
 8874                    sender_id,
 8875                    lsp_request_id,
 8876                    get_code_actions,
 8877                    None,
 8878                    &mut cx,
 8879                )
 8880                .await?;
 8881            }
 8882            Request::GetSignatureHelp(get_signature_help) => {
 8883                let position = get_signature_help
 8884                    .position
 8885                    .clone()
 8886                    .and_then(deserialize_anchor);
 8887                Self::query_lsp_locally::<GetSignatureHelp>(
 8888                    lsp_store,
 8889                    server_id,
 8890                    sender_id,
 8891                    lsp_request_id,
 8892                    get_signature_help,
 8893                    position,
 8894                    &mut cx,
 8895                )
 8896                .await?;
 8897            }
 8898            Request::GetCodeLens(get_code_lens) => {
 8899                Self::query_lsp_locally::<GetCodeLens>(
 8900                    lsp_store,
 8901                    server_id,
 8902                    sender_id,
 8903                    lsp_request_id,
 8904                    get_code_lens,
 8905                    None,
 8906                    &mut cx,
 8907                )
 8908                .await?;
 8909            }
 8910            Request::GetDefinition(get_definition) => {
 8911                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8912                Self::query_lsp_locally::<GetDefinitions>(
 8913                    lsp_store,
 8914                    server_id,
 8915                    sender_id,
 8916                    lsp_request_id,
 8917                    get_definition,
 8918                    position,
 8919                    &mut cx,
 8920                )
 8921                .await?;
 8922            }
 8923            Request::GetDeclaration(get_declaration) => {
 8924                let position = get_declaration
 8925                    .position
 8926                    .clone()
 8927                    .and_then(deserialize_anchor);
 8928                Self::query_lsp_locally::<GetDeclarations>(
 8929                    lsp_store,
 8930                    server_id,
 8931                    sender_id,
 8932                    lsp_request_id,
 8933                    get_declaration,
 8934                    position,
 8935                    &mut cx,
 8936                )
 8937                .await?;
 8938            }
 8939            Request::GetTypeDefinition(get_type_definition) => {
 8940                let position = get_type_definition
 8941                    .position
 8942                    .clone()
 8943                    .and_then(deserialize_anchor);
 8944                Self::query_lsp_locally::<GetTypeDefinitions>(
 8945                    lsp_store,
 8946                    server_id,
 8947                    sender_id,
 8948                    lsp_request_id,
 8949                    get_type_definition,
 8950                    position,
 8951                    &mut cx,
 8952                )
 8953                .await?;
 8954            }
 8955            Request::GetImplementation(get_implementation) => {
 8956                let position = get_implementation
 8957                    .position
 8958                    .clone()
 8959                    .and_then(deserialize_anchor);
 8960                Self::query_lsp_locally::<GetImplementations>(
 8961                    lsp_store,
 8962                    server_id,
 8963                    sender_id,
 8964                    lsp_request_id,
 8965                    get_implementation,
 8966                    position,
 8967                    &mut cx,
 8968                )
 8969                .await?;
 8970            }
 8971            Request::InlayHints(inlay_hints) => {
 8972                let query_start = inlay_hints
 8973                    .start
 8974                    .clone()
 8975                    .and_then(deserialize_anchor)
 8976                    .context("invalid inlay hints range start")?;
 8977                let query_end = inlay_hints
 8978                    .end
 8979                    .clone()
 8980                    .and_then(deserialize_anchor)
 8981                    .context("invalid inlay hints range end")?;
 8982                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 8983                    &lsp_store,
 8984                    server_id,
 8985                    lsp_request_id,
 8986                    &inlay_hints,
 8987                    query_start..query_end,
 8988                    &mut cx,
 8989                )
 8990                .await
 8991                .context("preparing inlay hints request")?;
 8992                Self::query_lsp_locally::<InlayHints>(
 8993                    lsp_store,
 8994                    server_id,
 8995                    sender_id,
 8996                    lsp_request_id,
 8997                    inlay_hints,
 8998                    None,
 8999                    &mut cx,
 9000                )
 9001                .await
 9002                .context("querying for inlay hints")?
 9003            }
 9004            //////////////////////////////
 9005            // Below are LSP queries that need to fetch more data,
 9006            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 9007            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9008                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 9009                    &lsp_store,
 9010                    &get_document_diagnostics,
 9011                    &mut cx,
 9012                )
 9013                .await?;
 9014                lsp_store.update(&mut cx, |lsp_store, cx| {
 9015                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9016                    let key = LspKey {
 9017                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9018                        server_queried: server_id,
 9019                    };
 9020                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9021                    ) {
 9022                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9023                            lsp_requests.clear();
 9024                        };
 9025                    }
 9026
 9027                    lsp_data.lsp_requests.entry(key).or_default().insert(
 9028                        lsp_request_id,
 9029                        cx.spawn(async move |lsp_store, cx| {
 9030                            let diagnostics_pull = lsp_store
 9031                                .update(cx, |lsp_store, cx| {
 9032                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9033                                })
 9034                                .ok();
 9035                            if let Some(diagnostics_pull) = diagnostics_pull {
 9036                                match diagnostics_pull.await {
 9037                                    Ok(()) => {}
 9038                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9039                                };
 9040                            }
 9041                        }),
 9042                    );
 9043                });
 9044            }
 9045            Request::SemanticTokens(semantic_tokens) => {
 9046                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 9047                    &lsp_store,
 9048                    &semantic_tokens,
 9049                    &mut cx,
 9050                )
 9051                .await?;
 9052                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9053                lsp_store.update(&mut cx, |lsp_store, cx| {
 9054                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9055                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9056                        let key = LspKey {
 9057                            request_type: TypeId::of::<SemanticTokensFull>(),
 9058                            server_queried: server_id,
 9059                        };
 9060                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9061                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9062                                lsp_requests.clear();
 9063                            };
 9064                        }
 9065
 9066                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9067                            lsp_request_id,
 9068                            cx.spawn(async move |lsp_store, cx| {
 9069                                let tokens_fetch = lsp_store
 9070                                    .update(cx, |lsp_store, cx| {
 9071                                        lsp_store
 9072                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9073                                    })
 9074                                    .ok();
 9075                                if let Some(tokens_fetch) = tokens_fetch {
 9076                                    let new_tokens = tokens_fetch.await;
 9077                                    if let Some(new_tokens) = new_tokens {
 9078                                        lsp_store
 9079                                            .update(cx, |lsp_store, cx| {
 9080                                                let response = new_tokens
 9081                                                    .into_iter()
 9082                                                    .map(|(server_id, response)| {
 9083                                                        (
 9084                                                            server_id.to_proto(),
 9085                                                            SemanticTokensFull::response_to_proto(
 9086                                                                response,
 9087                                                                lsp_store,
 9088                                                                sender_id,
 9089                                                                &buffer_version,
 9090                                                                cx,
 9091                                                            ),
 9092                                                        )
 9093                                                    })
 9094                                                    .collect::<HashMap<_, _>>();
 9095                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9096                                                    project_id,
 9097                                                    lsp_request_id,
 9098                                                    response,
 9099                                                ) {
 9100                                                    Ok(()) => {}
 9101                                                    Err(e) => {
 9102                                                        log::error!(
 9103                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9104                                                        )
 9105                                                    }
 9106                                                }
 9107                                            })
 9108                                            .ok();
 9109                                    }
 9110                                }
 9111                            }),
 9112                        );
 9113                    }
 9114                });
 9115            }
 9116        }
 9117        Ok(proto::Ack {})
 9118    }
 9119
 9120    async fn handle_lsp_query_response(
 9121        lsp_store: Entity<Self>,
 9122        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9123        cx: AsyncApp,
 9124    ) -> Result<()> {
 9125        lsp_store.read_with(&cx, |lsp_store, _| {
 9126            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9127                upstream_client.handle_lsp_response(envelope.clone());
 9128            }
 9129        });
 9130        Ok(())
 9131    }
 9132
 9133    async fn handle_apply_code_action(
 9134        this: Entity<Self>,
 9135        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9136        mut cx: AsyncApp,
 9137    ) -> Result<proto::ApplyCodeActionResponse> {
 9138        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9139        let action =
 9140            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9141        let apply_code_action = this.update(&mut cx, |this, cx| {
 9142            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9143            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9144            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9145        })?;
 9146
 9147        let project_transaction = apply_code_action.await?;
 9148        let project_transaction = this.update(&mut cx, |this, cx| {
 9149            this.buffer_store.update(cx, |buffer_store, cx| {
 9150                buffer_store.serialize_project_transaction_for_peer(
 9151                    project_transaction,
 9152                    sender_id,
 9153                    cx,
 9154                )
 9155            })
 9156        });
 9157        Ok(proto::ApplyCodeActionResponse {
 9158            transaction: Some(project_transaction),
 9159        })
 9160    }
 9161
 9162    async fn handle_register_buffer_with_language_servers(
 9163        this: Entity<Self>,
 9164        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9165        mut cx: AsyncApp,
 9166    ) -> Result<proto::Ack> {
 9167        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9168        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9169        this.update(&mut cx, |this, cx| {
 9170            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9171                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9172                    project_id: upstream_project_id,
 9173                    buffer_id: buffer_id.to_proto(),
 9174                    only_servers: envelope.payload.only_servers,
 9175                });
 9176            }
 9177
 9178            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9179                anyhow::bail!("buffer is not open");
 9180            };
 9181
 9182            let handle = this.register_buffer_with_language_servers(
 9183                &buffer,
 9184                envelope
 9185                    .payload
 9186                    .only_servers
 9187                    .into_iter()
 9188                    .filter_map(|selector| {
 9189                        Some(match selector.selector? {
 9190                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9191                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9192                            }
 9193                            proto::language_server_selector::Selector::Name(name) => {
 9194                                LanguageServerSelector::Name(LanguageServerName(
 9195                                    SharedString::from(name),
 9196                                ))
 9197                            }
 9198                        })
 9199                    })
 9200                    .collect(),
 9201                false,
 9202                cx,
 9203            );
 9204            // Pull diagnostics for the buffer even if it was already registered.
 9205            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9206            // but it's unclear if we need it.
 9207            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9208                .detach();
 9209            this.buffer_store().update(cx, |buffer_store, _| {
 9210                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9211            });
 9212
 9213            Ok(())
 9214        })?;
 9215        Ok(proto::Ack {})
 9216    }
 9217
 9218    async fn handle_rename_project_entry(
 9219        this: Entity<Self>,
 9220        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9221        mut cx: AsyncApp,
 9222    ) -> Result<proto::ProjectEntryResponse> {
 9223        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9224        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9225        let new_path =
 9226            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9227
 9228        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9229            .update(&mut cx, |this, cx| {
 9230                let (worktree, entry) = this
 9231                    .worktree_store
 9232                    .read(cx)
 9233                    .worktree_and_entry_for_id(entry_id, cx)?;
 9234                let new_worktree = this
 9235                    .worktree_store
 9236                    .read(cx)
 9237                    .worktree_for_id(new_worktree_id, cx)?;
 9238                Some((
 9239                    this.worktree_store.clone(),
 9240                    worktree,
 9241                    new_worktree,
 9242                    entry.clone(),
 9243                ))
 9244            })
 9245            .context("worktree not found")?;
 9246        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9247            (worktree.absolutize(&old_entry.path), worktree.id())
 9248        });
 9249        let new_abs_path =
 9250            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9251
 9252        let _transaction = Self::will_rename_entry(
 9253            this.downgrade(),
 9254            old_worktree_id,
 9255            &old_abs_path,
 9256            &new_abs_path,
 9257            old_entry.is_dir(),
 9258            cx.clone(),
 9259        )
 9260        .await;
 9261        let response = WorktreeStore::handle_rename_project_entry(
 9262            worktree_store,
 9263            envelope.payload,
 9264            cx.clone(),
 9265        )
 9266        .await;
 9267        this.read_with(&cx, |this, _| {
 9268            this.did_rename_entry(
 9269                old_worktree_id,
 9270                &old_abs_path,
 9271                &new_abs_path,
 9272                old_entry.is_dir(),
 9273            );
 9274        });
 9275        response
 9276    }
 9277
 9278    async fn handle_update_diagnostic_summary(
 9279        this: Entity<Self>,
 9280        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9281        mut cx: AsyncApp,
 9282    ) -> Result<()> {
 9283        this.update(&mut cx, |lsp_store, cx| {
 9284            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9285            let mut updated_diagnostics_paths = HashMap::default();
 9286            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9287            for message_summary in envelope
 9288                .payload
 9289                .summary
 9290                .into_iter()
 9291                .chain(envelope.payload.more_summaries)
 9292            {
 9293                let project_path = ProjectPath {
 9294                    worktree_id,
 9295                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9296                };
 9297                let path = project_path.path.clone();
 9298                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9299                let summary = DiagnosticSummary {
 9300                    error_count: message_summary.error_count as usize,
 9301                    warning_count: message_summary.warning_count as usize,
 9302                };
 9303
 9304                if summary.is_empty() {
 9305                    if let Some(worktree_summaries) =
 9306                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9307                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9308                    {
 9309                        summaries.remove(&server_id);
 9310                        if summaries.is_empty() {
 9311                            worktree_summaries.remove(&path);
 9312                        }
 9313                    }
 9314                } else {
 9315                    lsp_store
 9316                        .diagnostic_summaries
 9317                        .entry(worktree_id)
 9318                        .or_default()
 9319                        .entry(path)
 9320                        .or_default()
 9321                        .insert(server_id, summary);
 9322                }
 9323
 9324                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9325                    match &mut diagnostics_summary {
 9326                        Some(diagnostics_summary) => {
 9327                            diagnostics_summary
 9328                                .more_summaries
 9329                                .push(proto::DiagnosticSummary {
 9330                                    path: project_path.path.as_ref().to_proto(),
 9331                                    language_server_id: server_id.0 as u64,
 9332                                    error_count: summary.error_count as u32,
 9333                                    warning_count: summary.warning_count as u32,
 9334                                })
 9335                        }
 9336                        None => {
 9337                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9338                                project_id: *project_id,
 9339                                worktree_id: worktree_id.to_proto(),
 9340                                summary: Some(proto::DiagnosticSummary {
 9341                                    path: project_path.path.as_ref().to_proto(),
 9342                                    language_server_id: server_id.0 as u64,
 9343                                    error_count: summary.error_count as u32,
 9344                                    warning_count: summary.warning_count as u32,
 9345                                }),
 9346                                more_summaries: Vec::new(),
 9347                            })
 9348                        }
 9349                    }
 9350                }
 9351                updated_diagnostics_paths
 9352                    .entry(server_id)
 9353                    .or_insert_with(Vec::new)
 9354                    .push(project_path);
 9355            }
 9356
 9357            if let Some((diagnostics_summary, (downstream_client, _))) =
 9358                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9359            {
 9360                downstream_client.send(diagnostics_summary).log_err();
 9361            }
 9362            for (server_id, paths) in updated_diagnostics_paths {
 9363                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9364            }
 9365            Ok(())
 9366        })
 9367    }
 9368
 9369    async fn handle_start_language_server(
 9370        lsp_store: Entity<Self>,
 9371        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9372        mut cx: AsyncApp,
 9373    ) -> Result<()> {
 9374        let server = envelope.payload.server.context("invalid server")?;
 9375        let server_capabilities =
 9376            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9377                .with_context(|| {
 9378                    format!(
 9379                        "incorrect server capabilities {}",
 9380                        envelope.payload.capabilities
 9381                    )
 9382                })?;
 9383        lsp_store.update(&mut cx, |lsp_store, cx| {
 9384            let server_id = LanguageServerId(server.id as usize);
 9385            let server_name = LanguageServerName::from_proto(server.name.clone());
 9386            lsp_store
 9387                .lsp_server_capabilities
 9388                .insert(server_id, server_capabilities);
 9389            lsp_store.language_server_statuses.insert(
 9390                server_id,
 9391                LanguageServerStatus {
 9392                    name: server_name.clone(),
 9393                    server_version: None,
 9394                    pending_work: Default::default(),
 9395                    has_pending_diagnostic_updates: false,
 9396                    progress_tokens: Default::default(),
 9397                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9398                    binary: None,
 9399                    configuration: None,
 9400                    workspace_folders: BTreeSet::new(),
 9401                    process_id: None,
 9402                },
 9403            );
 9404            cx.emit(LspStoreEvent::LanguageServerAdded(
 9405                server_id,
 9406                server_name,
 9407                server.worktree_id.map(WorktreeId::from_proto),
 9408            ));
 9409            cx.notify();
 9410        });
 9411        Ok(())
 9412    }
 9413
 9414    async fn handle_update_language_server(
 9415        lsp_store: Entity<Self>,
 9416        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9417        mut cx: AsyncApp,
 9418    ) -> Result<()> {
 9419        lsp_store.update(&mut cx, |lsp_store, cx| {
 9420            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9421
 9422            match envelope.payload.variant.context("invalid variant")? {
 9423                proto::update_language_server::Variant::WorkStart(payload) => {
 9424                    lsp_store.on_lsp_work_start(
 9425                        language_server_id,
 9426                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9427                            .context("invalid progress token value")?,
 9428                        LanguageServerProgress {
 9429                            title: payload.title,
 9430                            is_disk_based_diagnostics_progress: false,
 9431                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9432                            message: payload.message,
 9433                            percentage: payload.percentage.map(|p| p as usize),
 9434                            last_update_at: cx.background_executor().now(),
 9435                        },
 9436                        cx,
 9437                    );
 9438                }
 9439                proto::update_language_server::Variant::WorkProgress(payload) => {
 9440                    lsp_store.on_lsp_work_progress(
 9441                        language_server_id,
 9442                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9443                            .context("invalid progress token value")?,
 9444                        LanguageServerProgress {
 9445                            title: None,
 9446                            is_disk_based_diagnostics_progress: false,
 9447                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9448                            message: payload.message,
 9449                            percentage: payload.percentage.map(|p| p as usize),
 9450                            last_update_at: cx.background_executor().now(),
 9451                        },
 9452                        cx,
 9453                    );
 9454                }
 9455
 9456                proto::update_language_server::Variant::WorkEnd(payload) => {
 9457                    lsp_store.on_lsp_work_end(
 9458                        language_server_id,
 9459                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9460                            .context("invalid progress token value")?,
 9461                        cx,
 9462                    );
 9463                }
 9464
 9465                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9466                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9467                }
 9468
 9469                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9470                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9471                }
 9472
 9473                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9474                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9475                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9476                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9477                        language_server_id,
 9478                        name: envelope
 9479                            .payload
 9480                            .server_name
 9481                            .map(SharedString::new)
 9482                            .map(LanguageServerName),
 9483                        message: non_lsp,
 9484                    });
 9485                }
 9486            }
 9487
 9488            Ok(())
 9489        })
 9490    }
 9491
 9492    async fn handle_language_server_log(
 9493        this: Entity<Self>,
 9494        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9495        mut cx: AsyncApp,
 9496    ) -> Result<()> {
 9497        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9498        let log_type = envelope
 9499            .payload
 9500            .log_type
 9501            .map(LanguageServerLogType::from_proto)
 9502            .context("invalid language server log type")?;
 9503
 9504        let message = envelope.payload.message;
 9505
 9506        this.update(&mut cx, |_, cx| {
 9507            cx.emit(LspStoreEvent::LanguageServerLog(
 9508                language_server_id,
 9509                log_type,
 9510                message,
 9511            ));
 9512        });
 9513        Ok(())
 9514    }
 9515
 9516    async fn handle_lsp_ext_cancel_flycheck(
 9517        lsp_store: Entity<Self>,
 9518        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9519        cx: AsyncApp,
 9520    ) -> Result<proto::Ack> {
 9521        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9522        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9523            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9524                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9525            } else {
 9526                None
 9527            }
 9528        });
 9529        if let Some(task) = task {
 9530            task.context("handling lsp ext cancel flycheck")?;
 9531        }
 9532
 9533        Ok(proto::Ack {})
 9534    }
 9535
 9536    async fn handle_lsp_ext_run_flycheck(
 9537        lsp_store: Entity<Self>,
 9538        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9539        mut cx: AsyncApp,
 9540    ) -> Result<proto::Ack> {
 9541        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9542        lsp_store.update(&mut cx, |lsp_store, cx| {
 9543            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9544                let text_document = if envelope.payload.current_file_only {
 9545                    let buffer_id = envelope
 9546                        .payload
 9547                        .buffer_id
 9548                        .map(|id| BufferId::new(id))
 9549                        .transpose()?;
 9550                    buffer_id
 9551                        .and_then(|buffer_id| {
 9552                            lsp_store
 9553                                .buffer_store()
 9554                                .read(cx)
 9555                                .get(buffer_id)
 9556                                .and_then(|buffer| {
 9557                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9558                                })
 9559                                .map(|path| make_text_document_identifier(&path))
 9560                        })
 9561                        .transpose()?
 9562                } else {
 9563                    None
 9564                };
 9565                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9566                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9567                )?;
 9568            }
 9569            anyhow::Ok(())
 9570        })?;
 9571
 9572        Ok(proto::Ack {})
 9573    }
 9574
 9575    async fn handle_lsp_ext_clear_flycheck(
 9576        lsp_store: Entity<Self>,
 9577        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9578        cx: AsyncApp,
 9579    ) -> Result<proto::Ack> {
 9580        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9581        lsp_store.read_with(&cx, |lsp_store, _| {
 9582            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9583                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9584            } else {
 9585                None
 9586            }
 9587        });
 9588
 9589        Ok(proto::Ack {})
 9590    }
 9591
 9592    pub fn disk_based_diagnostics_started(
 9593        &mut self,
 9594        language_server_id: LanguageServerId,
 9595        cx: &mut Context<Self>,
 9596    ) {
 9597        if let Some(language_server_status) =
 9598            self.language_server_statuses.get_mut(&language_server_id)
 9599        {
 9600            language_server_status.has_pending_diagnostic_updates = true;
 9601        }
 9602
 9603        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9604        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9605            language_server_id,
 9606            name: self
 9607                .language_server_adapter_for_id(language_server_id)
 9608                .map(|adapter| adapter.name()),
 9609            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9610                Default::default(),
 9611            ),
 9612        })
 9613    }
 9614
 9615    pub fn disk_based_diagnostics_finished(
 9616        &mut self,
 9617        language_server_id: LanguageServerId,
 9618        cx: &mut Context<Self>,
 9619    ) {
 9620        if let Some(language_server_status) =
 9621            self.language_server_statuses.get_mut(&language_server_id)
 9622        {
 9623            language_server_status.has_pending_diagnostic_updates = false;
 9624        }
 9625
 9626        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9627        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9628            language_server_id,
 9629            name: self
 9630                .language_server_adapter_for_id(language_server_id)
 9631                .map(|adapter| adapter.name()),
 9632            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9633                Default::default(),
 9634            ),
 9635        })
 9636    }
 9637
 9638    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9639    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9640    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9641    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9642    // the language server might take some time to publish diagnostics.
 9643    fn simulate_disk_based_diagnostics_events_if_needed(
 9644        &mut self,
 9645        language_server_id: LanguageServerId,
 9646        cx: &mut Context<Self>,
 9647    ) {
 9648        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9649
 9650        let Some(LanguageServerState::Running {
 9651            simulate_disk_based_diagnostics_completion,
 9652            adapter,
 9653            ..
 9654        }) = self
 9655            .as_local_mut()
 9656            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9657        else {
 9658            return;
 9659        };
 9660
 9661        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9662            return;
 9663        }
 9664
 9665        let prev_task =
 9666            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9667                cx.background_executor()
 9668                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9669                    .await;
 9670
 9671                this.update(cx, |this, cx| {
 9672                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9673
 9674                    if let Some(LanguageServerState::Running {
 9675                        simulate_disk_based_diagnostics_completion,
 9676                        ..
 9677                    }) = this.as_local_mut().and_then(|local_store| {
 9678                        local_store.language_servers.get_mut(&language_server_id)
 9679                    }) {
 9680                        *simulate_disk_based_diagnostics_completion = None;
 9681                    }
 9682                })
 9683                .ok();
 9684            }));
 9685
 9686        if prev_task.is_none() {
 9687            self.disk_based_diagnostics_started(language_server_id, cx);
 9688        }
 9689    }
 9690
 9691    pub fn language_server_statuses(
 9692        &self,
 9693    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9694        self.language_server_statuses
 9695            .iter()
 9696            .map(|(key, value)| (*key, value))
 9697    }
 9698
 9699    pub(super) fn did_rename_entry(
 9700        &self,
 9701        worktree_id: WorktreeId,
 9702        old_path: &Path,
 9703        new_path: &Path,
 9704        is_dir: bool,
 9705    ) {
 9706        maybe!({
 9707            let local_store = self.as_local()?;
 9708
 9709            let old_uri = lsp::Uri::from_file_path(old_path)
 9710                .ok()
 9711                .map(|uri| uri.to_string())?;
 9712            let new_uri = lsp::Uri::from_file_path(new_path)
 9713                .ok()
 9714                .map(|uri| uri.to_string())?;
 9715
 9716            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9717                let Some(filter) = local_store
 9718                    .language_server_paths_watched_for_rename
 9719                    .get(&language_server.server_id())
 9720                else {
 9721                    continue;
 9722                };
 9723
 9724                if filter.should_send_did_rename(&old_uri, is_dir) {
 9725                    language_server
 9726                        .notify::<DidRenameFiles>(RenameFilesParams {
 9727                            files: vec![FileRename {
 9728                                old_uri: old_uri.clone(),
 9729                                new_uri: new_uri.clone(),
 9730                            }],
 9731                        })
 9732                        .ok();
 9733                }
 9734            }
 9735            Some(())
 9736        });
 9737    }
 9738
 9739    pub(super) fn will_rename_entry(
 9740        this: WeakEntity<Self>,
 9741        worktree_id: WorktreeId,
 9742        old_path: &Path,
 9743        new_path: &Path,
 9744        is_dir: bool,
 9745        cx: AsyncApp,
 9746    ) -> Task<ProjectTransaction> {
 9747        let old_uri = lsp::Uri::from_file_path(old_path)
 9748            .ok()
 9749            .map(|uri| uri.to_string());
 9750        let new_uri = lsp::Uri::from_file_path(new_path)
 9751            .ok()
 9752            .map(|uri| uri.to_string());
 9753        cx.spawn(async move |cx| {
 9754            let mut tasks = vec![];
 9755            this.update(cx, |this, cx| {
 9756                let local_store = this.as_local()?;
 9757                let old_uri = old_uri?;
 9758                let new_uri = new_uri?;
 9759                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9760                    let Some(filter) = local_store
 9761                        .language_server_paths_watched_for_rename
 9762                        .get(&language_server.server_id())
 9763                    else {
 9764                        continue;
 9765                    };
 9766
 9767                    if !filter.should_send_will_rename(&old_uri, is_dir) {
 9768                        continue;
 9769                    }
 9770                    let request_timeout = ProjectSettings::get_global(cx)
 9771                        .global_lsp_settings
 9772                        .get_request_timeout();
 9773
 9774                    let apply_edit = cx.spawn({
 9775                        let old_uri = old_uri.clone();
 9776                        let new_uri = new_uri.clone();
 9777                        let language_server = language_server.clone();
 9778                        async move |this, cx| {
 9779                            let edit = language_server
 9780                                .request::<WillRenameFiles>(
 9781                                    RenameFilesParams {
 9782                                        files: vec![FileRename { old_uri, new_uri }],
 9783                                    },
 9784                                    request_timeout,
 9785                                )
 9786                                .await
 9787                                .into_response()
 9788                                .context("will rename files")
 9789                                .log_err()
 9790                                .flatten()?;
 9791
 9792                            LocalLspStore::deserialize_workspace_edit(
 9793                                this.upgrade()?,
 9794                                edit,
 9795                                false,
 9796                                language_server.clone(),
 9797                                cx,
 9798                            )
 9799                            .await
 9800                            .ok()
 9801                        }
 9802                    });
 9803                    tasks.push(apply_edit);
 9804                }
 9805                Some(())
 9806            })
 9807            .ok()
 9808            .flatten();
 9809            let mut merged_transaction = ProjectTransaction::default();
 9810            for task in tasks {
 9811                // Await on tasks sequentially so that the order of application of edits is deterministic
 9812                // (at least with regards to the order of registration of language servers)
 9813                if let Some(transaction) = task.await {
 9814                    for (buffer, buffer_transaction) in transaction.0 {
 9815                        merged_transaction.0.insert(buffer, buffer_transaction);
 9816                    }
 9817                }
 9818            }
 9819            merged_transaction
 9820        })
 9821    }
 9822
 9823    fn lsp_notify_abs_paths_changed(
 9824        &mut self,
 9825        server_id: LanguageServerId,
 9826        changes: Vec<PathEvent>,
 9827    ) {
 9828        maybe!({
 9829            let server = self.language_server_for_id(server_id)?;
 9830            let changes = changes
 9831                .into_iter()
 9832                .filter_map(|event| {
 9833                    let typ = match event.kind? {
 9834                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9835                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9836                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9837                    };
 9838                    Some(lsp::FileEvent {
 9839                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9840                        typ,
 9841                    })
 9842                })
 9843                .collect::<Vec<_>>();
 9844            if !changes.is_empty() {
 9845                server
 9846                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9847                        lsp::DidChangeWatchedFilesParams { changes },
 9848                    )
 9849                    .ok();
 9850            }
 9851            Some(())
 9852        });
 9853    }
 9854
 9855    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9856        self.as_local()?.language_server_for_id(id)
 9857    }
 9858
 9859    fn on_lsp_progress(
 9860        &mut self,
 9861        progress_params: lsp::ProgressParams,
 9862        language_server_id: LanguageServerId,
 9863        disk_based_diagnostics_progress_token: Option<String>,
 9864        cx: &mut Context<Self>,
 9865    ) {
 9866        match progress_params.value {
 9867            lsp::ProgressParamsValue::WorkDone(progress) => {
 9868                self.handle_work_done_progress(
 9869                    progress,
 9870                    language_server_id,
 9871                    disk_based_diagnostics_progress_token,
 9872                    ProgressToken::from_lsp(progress_params.token),
 9873                    cx,
 9874                );
 9875            }
 9876            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9877                let registration_id = match progress_params.token {
 9878                    lsp::NumberOrString::Number(_) => None,
 9879                    lsp::NumberOrString::String(token) => token
 9880                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9881                        .map(|(_, id)| id.to_owned()),
 9882                };
 9883                if let Some(LanguageServerState::Running {
 9884                    workspace_diagnostics_refresh_tasks,
 9885                    ..
 9886                }) = self
 9887                    .as_local_mut()
 9888                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9889                    && let Some(workspace_diagnostics) =
 9890                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9891                {
 9892                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9893                    self.apply_workspace_diagnostic_report(
 9894                        language_server_id,
 9895                        report,
 9896                        registration_id.map(SharedString::from),
 9897                        cx,
 9898                    )
 9899                }
 9900            }
 9901        }
 9902    }
 9903
 9904    fn handle_work_done_progress(
 9905        &mut self,
 9906        progress: lsp::WorkDoneProgress,
 9907        language_server_id: LanguageServerId,
 9908        disk_based_diagnostics_progress_token: Option<String>,
 9909        token: ProgressToken,
 9910        cx: &mut Context<Self>,
 9911    ) {
 9912        let language_server_status =
 9913            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9914                status
 9915            } else {
 9916                return;
 9917            };
 9918
 9919        if !language_server_status.progress_tokens.contains(&token) {
 9920            return;
 9921        }
 9922
 9923        let is_disk_based_diagnostics_progress =
 9924            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9925                (&disk_based_diagnostics_progress_token, &token)
 9926            {
 9927                token.starts_with(disk_based_token)
 9928            } else {
 9929                false
 9930            };
 9931
 9932        match progress {
 9933            lsp::WorkDoneProgress::Begin(report) => {
 9934                if is_disk_based_diagnostics_progress {
 9935                    self.disk_based_diagnostics_started(language_server_id, cx);
 9936                }
 9937                self.on_lsp_work_start(
 9938                    language_server_id,
 9939                    token.clone(),
 9940                    LanguageServerProgress {
 9941                        title: Some(report.title),
 9942                        is_disk_based_diagnostics_progress,
 9943                        is_cancellable: report.cancellable.unwrap_or(false),
 9944                        message: report.message.clone(),
 9945                        percentage: report.percentage.map(|p| p as usize),
 9946                        last_update_at: cx.background_executor().now(),
 9947                    },
 9948                    cx,
 9949                );
 9950            }
 9951            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9952                language_server_id,
 9953                token,
 9954                LanguageServerProgress {
 9955                    title: None,
 9956                    is_disk_based_diagnostics_progress,
 9957                    is_cancellable: report.cancellable.unwrap_or(false),
 9958                    message: report.message,
 9959                    percentage: report.percentage.map(|p| p as usize),
 9960                    last_update_at: cx.background_executor().now(),
 9961                },
 9962                cx,
 9963            ),
 9964            lsp::WorkDoneProgress::End(_) => {
 9965                language_server_status.progress_tokens.remove(&token);
 9966                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9967                if is_disk_based_diagnostics_progress {
 9968                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9969                }
 9970            }
 9971        }
 9972    }
 9973
 9974    fn on_lsp_work_start(
 9975        &mut self,
 9976        language_server_id: LanguageServerId,
 9977        token: ProgressToken,
 9978        progress: LanguageServerProgress,
 9979        cx: &mut Context<Self>,
 9980    ) {
 9981        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9982            status.pending_work.insert(token.clone(), progress.clone());
 9983            cx.notify();
 9984        }
 9985        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9986            language_server_id,
 9987            name: self
 9988                .language_server_adapter_for_id(language_server_id)
 9989                .map(|adapter| adapter.name()),
 9990            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9991                token: Some(token.to_proto()),
 9992                title: progress.title,
 9993                message: progress.message,
 9994                percentage: progress.percentage.map(|p| p as u32),
 9995                is_cancellable: Some(progress.is_cancellable),
 9996            }),
 9997        })
 9998    }
 9999
10000    fn on_lsp_work_progress(
10001        &mut self,
10002        language_server_id: LanguageServerId,
10003        token: ProgressToken,
10004        progress: LanguageServerProgress,
10005        cx: &mut Context<Self>,
10006    ) {
10007        let mut did_update = false;
10008        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10009            match status.pending_work.entry(token.clone()) {
10010                btree_map::Entry::Vacant(entry) => {
10011                    entry.insert(progress.clone());
10012                    did_update = true;
10013                }
10014                btree_map::Entry::Occupied(mut entry) => {
10015                    let entry = entry.get_mut();
10016                    if (progress.last_update_at - entry.last_update_at)
10017                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10018                    {
10019                        entry.last_update_at = progress.last_update_at;
10020                        if progress.message.is_some() {
10021                            entry.message = progress.message.clone();
10022                        }
10023                        if progress.percentage.is_some() {
10024                            entry.percentage = progress.percentage;
10025                        }
10026                        if progress.is_cancellable != entry.is_cancellable {
10027                            entry.is_cancellable = progress.is_cancellable;
10028                        }
10029                        did_update = true;
10030                    }
10031                }
10032            }
10033        }
10034
10035        if did_update {
10036            cx.emit(LspStoreEvent::LanguageServerUpdate {
10037                language_server_id,
10038                name: self
10039                    .language_server_adapter_for_id(language_server_id)
10040                    .map(|adapter| adapter.name()),
10041                message: proto::update_language_server::Variant::WorkProgress(
10042                    proto::LspWorkProgress {
10043                        token: Some(token.to_proto()),
10044                        message: progress.message,
10045                        percentage: progress.percentage.map(|p| p as u32),
10046                        is_cancellable: Some(progress.is_cancellable),
10047                    },
10048                ),
10049            })
10050        }
10051    }
10052
10053    fn on_lsp_work_end(
10054        &mut self,
10055        language_server_id: LanguageServerId,
10056        token: ProgressToken,
10057        cx: &mut Context<Self>,
10058    ) {
10059        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10060            if let Some(work) = status.pending_work.remove(&token)
10061                && !work.is_disk_based_diagnostics_progress
10062            {
10063                cx.emit(LspStoreEvent::RefreshInlayHints {
10064                    server_id: language_server_id,
10065                    request_id: None,
10066                });
10067            }
10068            cx.notify();
10069        }
10070
10071        cx.emit(LspStoreEvent::LanguageServerUpdate {
10072            language_server_id,
10073            name: self
10074                .language_server_adapter_for_id(language_server_id)
10075                .map(|adapter| adapter.name()),
10076            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10077                token: Some(token.to_proto()),
10078            }),
10079        })
10080    }
10081
10082    pub async fn handle_resolve_completion_documentation(
10083        this: Entity<Self>,
10084        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10085        mut cx: AsyncApp,
10086    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10087        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10088
10089        let completion = this
10090            .read_with(&cx, |this, cx| {
10091                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10092                let server = this
10093                    .language_server_for_id(id)
10094                    .with_context(|| format!("No language server {id}"))?;
10095
10096                let request_timeout = ProjectSettings::get_global(cx)
10097                    .global_lsp_settings
10098                    .get_request_timeout();
10099
10100                anyhow::Ok(cx.background_spawn(async move {
10101                    let can_resolve = server
10102                        .capabilities()
10103                        .completion_provider
10104                        .as_ref()
10105                        .and_then(|options| options.resolve_provider)
10106                        .unwrap_or(false);
10107                    if can_resolve {
10108                        server
10109                            .request::<lsp::request::ResolveCompletionItem>(
10110                                lsp_completion,
10111                                request_timeout,
10112                            )
10113                            .await
10114                            .into_response()
10115                            .context("resolve completion item")
10116                    } else {
10117                        anyhow::Ok(lsp_completion)
10118                    }
10119                }))
10120            })?
10121            .await?;
10122
10123        let mut documentation_is_markdown = false;
10124        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10125        let documentation = match completion.documentation {
10126            Some(lsp::Documentation::String(text)) => text,
10127
10128            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10129                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10130                value
10131            }
10132
10133            _ => String::new(),
10134        };
10135
10136        // If we have a new buffer_id, that means we're talking to a new client
10137        // and want to check for new text_edits in the completion too.
10138        let mut old_replace_start = None;
10139        let mut old_replace_end = None;
10140        let mut old_insert_start = None;
10141        let mut old_insert_end = None;
10142        let mut new_text = String::default();
10143        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10144            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10145                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10146                anyhow::Ok(buffer.read(cx).snapshot())
10147            })?;
10148
10149            if let Some(text_edit) = completion.text_edit.as_ref() {
10150                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10151
10152                if let Some(mut edit) = edit {
10153                    LineEnding::normalize(&mut edit.new_text);
10154
10155                    new_text = edit.new_text;
10156                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10157                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10158                    if let Some(insert_range) = edit.insert_range {
10159                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10160                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10161                    }
10162                }
10163            }
10164        }
10165
10166        Ok(proto::ResolveCompletionDocumentationResponse {
10167            documentation,
10168            documentation_is_markdown,
10169            old_replace_start,
10170            old_replace_end,
10171            new_text,
10172            lsp_completion,
10173            old_insert_start,
10174            old_insert_end,
10175        })
10176    }
10177
10178    async fn handle_on_type_formatting(
10179        this: Entity<Self>,
10180        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10181        mut cx: AsyncApp,
10182    ) -> Result<proto::OnTypeFormattingResponse> {
10183        let on_type_formatting = this.update(&mut cx, |this, cx| {
10184            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10185            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10186            let position = envelope
10187                .payload
10188                .position
10189                .and_then(deserialize_anchor)
10190                .context("invalid position")?;
10191            anyhow::Ok(this.apply_on_type_formatting(
10192                buffer,
10193                position,
10194                envelope.payload.trigger.clone(),
10195                cx,
10196            ))
10197        })?;
10198
10199        let transaction = on_type_formatting
10200            .await?
10201            .as_ref()
10202            .map(language::proto::serialize_transaction);
10203        Ok(proto::OnTypeFormattingResponse { transaction })
10204    }
10205
10206    async fn handle_pull_workspace_diagnostics(
10207        lsp_store: Entity<Self>,
10208        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10209        mut cx: AsyncApp,
10210    ) -> Result<proto::Ack> {
10211        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10212        lsp_store.update(&mut cx, |lsp_store, _| {
10213            lsp_store.pull_workspace_diagnostics(server_id);
10214        });
10215        Ok(proto::Ack {})
10216    }
10217
10218    async fn handle_open_buffer_for_symbol(
10219        this: Entity<Self>,
10220        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10221        mut cx: AsyncApp,
10222    ) -> Result<proto::OpenBufferForSymbolResponse> {
10223        let peer_id = envelope.original_sender_id().unwrap_or_default();
10224        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10225        let symbol = Self::deserialize_symbol(symbol)?;
10226        this.read_with(&cx, |this, _| {
10227            if let SymbolLocation::OutsideProject {
10228                abs_path,
10229                signature,
10230            } = &symbol.path
10231            {
10232                let new_signature = this.symbol_signature(&abs_path);
10233                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10234            }
10235            Ok(())
10236        })?;
10237        let buffer = this
10238            .update(&mut cx, |this, cx| {
10239                this.open_buffer_for_symbol(
10240                    &Symbol {
10241                        language_server_name: symbol.language_server_name,
10242                        source_worktree_id: symbol.source_worktree_id,
10243                        source_language_server_id: symbol.source_language_server_id,
10244                        path: symbol.path,
10245                        name: symbol.name,
10246                        kind: symbol.kind,
10247                        range: symbol.range,
10248                        label: CodeLabel::default(),
10249                        container_name: symbol.container_name,
10250                    },
10251                    cx,
10252                )
10253            })
10254            .await?;
10255
10256        this.update(&mut cx, |this, cx| {
10257            let is_private = buffer
10258                .read(cx)
10259                .file()
10260                .map(|f| f.is_private())
10261                .unwrap_or_default();
10262            if is_private {
10263                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10264            } else {
10265                this.buffer_store
10266                    .update(cx, |buffer_store, cx| {
10267                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10268                    })
10269                    .detach_and_log_err(cx);
10270                let buffer_id = buffer.read(cx).remote_id().to_proto();
10271                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10272            }
10273        })
10274    }
10275
10276    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10277        let mut hasher = Sha256::new();
10278        hasher.update(abs_path.to_string_lossy().as_bytes());
10279        hasher.update(self.nonce.to_be_bytes());
10280        hasher.finalize().as_slice().try_into().unwrap()
10281    }
10282
10283    pub async fn handle_get_project_symbols(
10284        this: Entity<Self>,
10285        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10286        mut cx: AsyncApp,
10287    ) -> Result<proto::GetProjectSymbolsResponse> {
10288        let symbols = this
10289            .update(&mut cx, |this, cx| {
10290                this.symbols(&envelope.payload.query, cx)
10291            })
10292            .await?;
10293
10294        Ok(proto::GetProjectSymbolsResponse {
10295            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10296        })
10297    }
10298
10299    pub async fn handle_restart_language_servers(
10300        this: Entity<Self>,
10301        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10302        mut cx: AsyncApp,
10303    ) -> Result<proto::Ack> {
10304        this.update(&mut cx, |lsp_store, cx| {
10305            let buffers =
10306                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10307            lsp_store.restart_language_servers_for_buffers(
10308                buffers,
10309                envelope
10310                    .payload
10311                    .only_servers
10312                    .into_iter()
10313                    .filter_map(|selector| {
10314                        Some(match selector.selector? {
10315                            proto::language_server_selector::Selector::ServerId(server_id) => {
10316                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10317                            }
10318                            proto::language_server_selector::Selector::Name(name) => {
10319                                LanguageServerSelector::Name(LanguageServerName(
10320                                    SharedString::from(name),
10321                                ))
10322                            }
10323                        })
10324                    })
10325                    .collect(),
10326                cx,
10327            );
10328        });
10329
10330        Ok(proto::Ack {})
10331    }
10332
10333    pub async fn handle_stop_language_servers(
10334        lsp_store: Entity<Self>,
10335        envelope: TypedEnvelope<proto::StopLanguageServers>,
10336        mut cx: AsyncApp,
10337    ) -> Result<proto::Ack> {
10338        lsp_store.update(&mut cx, |lsp_store, cx| {
10339            if envelope.payload.all
10340                && envelope.payload.also_servers.is_empty()
10341                && envelope.payload.buffer_ids.is_empty()
10342            {
10343                lsp_store.stop_all_language_servers(cx);
10344            } else {
10345                let buffers =
10346                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10347                lsp_store
10348                    .stop_language_servers_for_buffers(
10349                        buffers,
10350                        envelope
10351                            .payload
10352                            .also_servers
10353                            .into_iter()
10354                            .filter_map(|selector| {
10355                                Some(match selector.selector? {
10356                                    proto::language_server_selector::Selector::ServerId(
10357                                        server_id,
10358                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10359                                        server_id,
10360                                    )),
10361                                    proto::language_server_selector::Selector::Name(name) => {
10362                                        LanguageServerSelector::Name(LanguageServerName(
10363                                            SharedString::from(name),
10364                                        ))
10365                                    }
10366                                })
10367                            })
10368                            .collect(),
10369                        cx,
10370                    )
10371                    .detach_and_log_err(cx);
10372            }
10373        });
10374
10375        Ok(proto::Ack {})
10376    }
10377
10378    pub async fn handle_cancel_language_server_work(
10379        lsp_store: Entity<Self>,
10380        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10381        mut cx: AsyncApp,
10382    ) -> Result<proto::Ack> {
10383        lsp_store.update(&mut cx, |lsp_store, cx| {
10384            if let Some(work) = envelope.payload.work {
10385                match work {
10386                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10387                        let buffers =
10388                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10389                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10390                    }
10391                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10392                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10393                        let token = work
10394                            .token
10395                            .map(|token| {
10396                                ProgressToken::from_proto(token)
10397                                    .context("invalid work progress token")
10398                            })
10399                            .transpose()?;
10400                        lsp_store.cancel_language_server_work(server_id, token, cx);
10401                    }
10402                }
10403            }
10404            anyhow::Ok(())
10405        })?;
10406
10407        Ok(proto::Ack {})
10408    }
10409
10410    fn buffer_ids_to_buffers(
10411        &mut self,
10412        buffer_ids: impl Iterator<Item = u64>,
10413        cx: &mut Context<Self>,
10414    ) -> Vec<Entity<Buffer>> {
10415        buffer_ids
10416            .into_iter()
10417            .flat_map(|buffer_id| {
10418                self.buffer_store
10419                    .read(cx)
10420                    .get(BufferId::new(buffer_id).log_err()?)
10421            })
10422            .collect::<Vec<_>>()
10423    }
10424
10425    async fn handle_apply_additional_edits_for_completion(
10426        this: Entity<Self>,
10427        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10428        mut cx: AsyncApp,
10429    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10430        let (buffer, completion, all_commit_ranges) = this.update(&mut cx, |this, cx| {
10431            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10432            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10433            let completion = Self::deserialize_completion(
10434                envelope.payload.completion.context("invalid completion")?,
10435            )?;
10436            let all_commit_ranges = envelope
10437                .payload
10438                .all_commit_ranges
10439                .into_iter()
10440                .map(language::proto::deserialize_anchor_range)
10441                .collect::<Result<Vec<_>, _>>()?;
10442            anyhow::Ok((buffer, completion, all_commit_ranges))
10443        })?;
10444
10445        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10446            this.apply_additional_edits_for_completion(
10447                buffer,
10448                Rc::new(RefCell::new(Box::new([Completion {
10449                    replace_range: completion.replace_range,
10450                    new_text: completion.new_text,
10451                    source: completion.source,
10452                    documentation: None,
10453                    label: CodeLabel::default(),
10454                    match_start: None,
10455                    snippet_deduplication_key: None,
10456                    insert_text_mode: None,
10457                    icon_path: None,
10458                    confirm: None,
10459                }]))),
10460                0,
10461                false,
10462                all_commit_ranges,
10463                cx,
10464            )
10465        });
10466
10467        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10468            transaction: apply_additional_edits
10469                .await?
10470                .as_ref()
10471                .map(language::proto::serialize_transaction),
10472        })
10473    }
10474
10475    pub fn last_formatting_failure(&self) -> Option<&str> {
10476        self.last_formatting_failure.as_deref()
10477    }
10478
10479    pub fn reset_last_formatting_failure(&mut self) {
10480        self.last_formatting_failure = None;
10481    }
10482
10483    pub fn environment_for_buffer(
10484        &self,
10485        buffer: &Entity<Buffer>,
10486        cx: &mut Context<Self>,
10487    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10488        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10489            environment.update(cx, |env, cx| {
10490                env.buffer_environment(buffer, &self.worktree_store, cx)
10491            })
10492        } else {
10493            Task::ready(None).shared()
10494        }
10495    }
10496
10497    pub fn format(
10498        &mut self,
10499        buffers: HashSet<Entity<Buffer>>,
10500        target: LspFormatTarget,
10501        push_to_history: bool,
10502        trigger: FormatTrigger,
10503        cx: &mut Context<Self>,
10504    ) -> Task<anyhow::Result<ProjectTransaction>> {
10505        let logger = zlog::scoped!("format");
10506        if self.as_local().is_some() {
10507            zlog::trace!(logger => "Formatting locally");
10508            let logger = zlog::scoped!(logger => "local");
10509            let buffers = buffers
10510                .into_iter()
10511                .map(|buffer_handle| {
10512                    let buffer = buffer_handle.read(cx);
10513                    let buffer_abs_path = File::from_dyn(buffer.file())
10514                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10515
10516                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10517                })
10518                .collect::<Vec<_>>();
10519
10520            cx.spawn(async move |lsp_store, cx| {
10521                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10522
10523                for (handle, abs_path, id) in buffers {
10524                    let env = lsp_store
10525                        .update(cx, |lsp_store, cx| {
10526                            lsp_store.environment_for_buffer(&handle, cx)
10527                        })?
10528                        .await;
10529
10530                    let ranges = match &target {
10531                        LspFormatTarget::Buffers => None,
10532                        LspFormatTarget::Ranges(ranges) => {
10533                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10534                        }
10535                    };
10536
10537                    formattable_buffers.push(FormattableBuffer {
10538                        handle,
10539                        abs_path,
10540                        env,
10541                        ranges,
10542                    });
10543                }
10544                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10545
10546                let format_timer = zlog::time!(logger => "Formatting buffers");
10547                let result = LocalLspStore::format_locally(
10548                    lsp_store.clone(),
10549                    formattable_buffers,
10550                    push_to_history,
10551                    trigger,
10552                    logger,
10553                    cx,
10554                )
10555                .await;
10556                format_timer.end();
10557
10558                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10559
10560                lsp_store.update(cx, |lsp_store, _| {
10561                    lsp_store.update_last_formatting_failure(&result);
10562                })?;
10563
10564                result
10565            })
10566        } else if let Some((client, project_id)) = self.upstream_client() {
10567            zlog::trace!(logger => "Formatting remotely");
10568            let logger = zlog::scoped!(logger => "remote");
10569
10570            let buffer_ranges = match &target {
10571                LspFormatTarget::Buffers => Vec::new(),
10572                LspFormatTarget::Ranges(ranges) => ranges
10573                    .iter()
10574                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10575                        buffer_id: buffer_id.to_proto(),
10576                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10577                    })
10578                    .collect(),
10579            };
10580
10581            let buffer_store = self.buffer_store();
10582            cx.spawn(async move |lsp_store, cx| {
10583                zlog::trace!(logger => "Sending remote format request");
10584                let request_timer = zlog::time!(logger => "remote format request");
10585                let result = client
10586                    .request(proto::FormatBuffers {
10587                        project_id,
10588                        trigger: trigger as i32,
10589                        buffer_ids: buffers
10590                            .iter()
10591                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10592                            .collect(),
10593                        buffer_ranges,
10594                    })
10595                    .await
10596                    .and_then(|result| result.transaction.context("missing transaction"));
10597                request_timer.end();
10598
10599                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10600
10601                lsp_store.update(cx, |lsp_store, _| {
10602                    lsp_store.update_last_formatting_failure(&result);
10603                })?;
10604
10605                let transaction_response = result?;
10606                let _timer = zlog::time!(logger => "deserializing project transaction");
10607                buffer_store
10608                    .update(cx, |buffer_store, cx| {
10609                        buffer_store.deserialize_project_transaction(
10610                            transaction_response,
10611                            push_to_history,
10612                            cx,
10613                        )
10614                    })
10615                    .await
10616            })
10617        } else {
10618            zlog::trace!(logger => "Not formatting");
10619            Task::ready(Ok(ProjectTransaction::default()))
10620        }
10621    }
10622
10623    async fn handle_format_buffers(
10624        this: Entity<Self>,
10625        envelope: TypedEnvelope<proto::FormatBuffers>,
10626        mut cx: AsyncApp,
10627    ) -> Result<proto::FormatBuffersResponse> {
10628        let sender_id = envelope.original_sender_id().unwrap_or_default();
10629        let format = this.update(&mut cx, |this, cx| {
10630            let mut buffers = HashSet::default();
10631            for buffer_id in &envelope.payload.buffer_ids {
10632                let buffer_id = BufferId::new(*buffer_id)?;
10633                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10634            }
10635
10636            let target = if envelope.payload.buffer_ranges.is_empty() {
10637                LspFormatTarget::Buffers
10638            } else {
10639                let mut ranges_map = BTreeMap::new();
10640                for buffer_range in &envelope.payload.buffer_ranges {
10641                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10642                    let ranges: Result<Vec<_>> = buffer_range
10643                        .ranges
10644                        .iter()
10645                        .map(|range| {
10646                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10647                        })
10648                        .collect();
10649                    ranges_map.insert(buffer_id, ranges?);
10650                }
10651                LspFormatTarget::Ranges(ranges_map)
10652            };
10653
10654            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10655            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10656        })?;
10657
10658        let project_transaction = format.await?;
10659        let project_transaction = this.update(&mut cx, |this, cx| {
10660            this.buffer_store.update(cx, |buffer_store, cx| {
10661                buffer_store.serialize_project_transaction_for_peer(
10662                    project_transaction,
10663                    sender_id,
10664                    cx,
10665                )
10666            })
10667        });
10668        Ok(proto::FormatBuffersResponse {
10669            transaction: Some(project_transaction),
10670        })
10671    }
10672
10673    async fn handle_apply_code_action_kind(
10674        this: Entity<Self>,
10675        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10676        mut cx: AsyncApp,
10677    ) -> Result<proto::ApplyCodeActionKindResponse> {
10678        let sender_id = envelope.original_sender_id().unwrap_or_default();
10679        let format = this.update(&mut cx, |this, cx| {
10680            let mut buffers = HashSet::default();
10681            for buffer_id in &envelope.payload.buffer_ids {
10682                let buffer_id = BufferId::new(*buffer_id)?;
10683                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10684            }
10685            let kind = match envelope.payload.kind.as_str() {
10686                "" => CodeActionKind::EMPTY,
10687                "quickfix" => CodeActionKind::QUICKFIX,
10688                "refactor" => CodeActionKind::REFACTOR,
10689                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10690                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10691                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10692                "source" => CodeActionKind::SOURCE,
10693                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10694                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10695                _ => anyhow::bail!(
10696                    "Invalid code action kind {}",
10697                    envelope.payload.kind.as_str()
10698                ),
10699            };
10700            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10701        })?;
10702
10703        let project_transaction = format.await?;
10704        let project_transaction = this.update(&mut cx, |this, cx| {
10705            this.buffer_store.update(cx, |buffer_store, cx| {
10706                buffer_store.serialize_project_transaction_for_peer(
10707                    project_transaction,
10708                    sender_id,
10709                    cx,
10710                )
10711            })
10712        });
10713        Ok(proto::ApplyCodeActionKindResponse {
10714            transaction: Some(project_transaction),
10715        })
10716    }
10717
10718    async fn shutdown_language_server(
10719        server_state: Option<LanguageServerState>,
10720        name: LanguageServerName,
10721        cx: &mut AsyncApp,
10722    ) {
10723        let server = match server_state {
10724            Some(LanguageServerState::Starting { startup, .. }) => {
10725                let mut timer = cx
10726                    .background_executor()
10727                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10728                    .fuse();
10729
10730                select! {
10731                    server = startup.fuse() => server,
10732                    () = timer => {
10733                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10734                        None
10735                    },
10736                }
10737            }
10738
10739            Some(LanguageServerState::Running { server, .. }) => Some(server),
10740
10741            None => None,
10742        };
10743
10744        let Some(server) = server else { return };
10745        if let Some(shutdown) = server.shutdown() {
10746            shutdown.await;
10747        }
10748    }
10749
10750    // Returns a list of all of the worktrees which no longer have a language server and the root path
10751    // for the stopped server
10752    fn stop_local_language_server(
10753        &mut self,
10754        server_id: LanguageServerId,
10755        cx: &mut Context<Self>,
10756    ) -> Task<()> {
10757        let local = match &mut self.mode {
10758            LspStoreMode::Local(local) => local,
10759            _ => {
10760                return Task::ready(());
10761            }
10762        };
10763
10764        // Remove this server ID from all entries in the given worktree.
10765        local
10766            .language_server_ids
10767            .retain(|_, state| state.id != server_id);
10768        self.buffer_store.update(cx, |buffer_store, cx| {
10769            for buffer in buffer_store.buffers() {
10770                buffer.update(cx, |buffer, cx| {
10771                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10772                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10773                });
10774            }
10775        });
10776
10777        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10778            summaries.retain(|path, summaries_by_server_id| {
10779                if summaries_by_server_id.remove(&server_id).is_some() {
10780                    if let Some((client, project_id)) = self.downstream_client.clone() {
10781                        client
10782                            .send(proto::UpdateDiagnosticSummary {
10783                                project_id,
10784                                worktree_id: worktree_id.to_proto(),
10785                                summary: Some(proto::DiagnosticSummary {
10786                                    path: path.as_ref().to_proto(),
10787                                    language_server_id: server_id.0 as u64,
10788                                    error_count: 0,
10789                                    warning_count: 0,
10790                                }),
10791                                more_summaries: Vec::new(),
10792                            })
10793                            .log_err();
10794                    }
10795                    !summaries_by_server_id.is_empty()
10796                } else {
10797                    true
10798                }
10799            });
10800        }
10801
10802        let local = self.as_local_mut().unwrap();
10803        for diagnostics in local.diagnostics.values_mut() {
10804            diagnostics.retain(|_, diagnostics_by_server_id| {
10805                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10806                    diagnostics_by_server_id.remove(ix);
10807                    !diagnostics_by_server_id.is_empty()
10808                } else {
10809                    true
10810                }
10811            });
10812        }
10813        local.language_server_watched_paths.remove(&server_id);
10814
10815        let server_state = local.language_servers.remove(&server_id);
10816        self.cleanup_lsp_data(server_id);
10817        let name = self
10818            .language_server_statuses
10819            .remove(&server_id)
10820            .map(|status| status.name)
10821            .or_else(|| {
10822                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10823                    Some(adapter.name())
10824                } else {
10825                    None
10826                }
10827            });
10828
10829        if let Some(name) = name {
10830            log::info!("stopping language server {name}");
10831            self.languages
10832                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10833            cx.notify();
10834
10835            return cx.spawn(async move |lsp_store, cx| {
10836                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10837                lsp_store
10838                    .update(cx, |lsp_store, cx| {
10839                        lsp_store
10840                            .languages
10841                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10842                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10843                        cx.notify();
10844                    })
10845                    .ok();
10846            });
10847        }
10848
10849        if server_state.is_some() {
10850            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10851        }
10852        Task::ready(())
10853    }
10854
10855    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10856        self.shutdown_all_language_servers(cx).detach();
10857    }
10858
10859    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
10860        if let Some((client, project_id)) = self.upstream_client() {
10861            let request = client.request(proto::StopLanguageServers {
10862                project_id,
10863                buffer_ids: Vec::new(),
10864                also_servers: Vec::new(),
10865                all: true,
10866            });
10867            cx.background_spawn(async move {
10868                request.await.ok();
10869            })
10870        } else {
10871            let Some(local) = self.as_local_mut() else {
10872                return Task::ready(());
10873            };
10874            let language_servers_to_stop = local
10875                .language_server_ids
10876                .values()
10877                .map(|state| state.id)
10878                .collect();
10879            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10880            let tasks = language_servers_to_stop
10881                .into_iter()
10882                .map(|server| self.stop_local_language_server(server, cx))
10883                .collect::<Vec<_>>();
10884            cx.background_spawn(async move {
10885                futures::future::join_all(tasks).await;
10886            })
10887        }
10888    }
10889
10890    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
10891        let buffers = self.buffer_store.read(cx).buffers().collect();
10892        self.restart_language_servers_for_buffers(buffers, HashSet::default(), cx);
10893    }
10894
10895    pub fn restart_language_servers_for_buffers(
10896        &mut self,
10897        buffers: Vec<Entity<Buffer>>,
10898        only_restart_servers: HashSet<LanguageServerSelector>,
10899        cx: &mut Context<Self>,
10900    ) {
10901        if let Some((client, project_id)) = self.upstream_client() {
10902            let request = client.request(proto::RestartLanguageServers {
10903                project_id,
10904                buffer_ids: buffers
10905                    .into_iter()
10906                    .map(|b| b.read(cx).remote_id().to_proto())
10907                    .collect(),
10908                only_servers: only_restart_servers
10909                    .into_iter()
10910                    .map(|selector| {
10911                        let selector = match selector {
10912                            LanguageServerSelector::Id(language_server_id) => {
10913                                proto::language_server_selector::Selector::ServerId(
10914                                    language_server_id.to_proto(),
10915                                )
10916                            }
10917                            LanguageServerSelector::Name(language_server_name) => {
10918                                proto::language_server_selector::Selector::Name(
10919                                    language_server_name.to_string(),
10920                                )
10921                            }
10922                        };
10923                        proto::LanguageServerSelector {
10924                            selector: Some(selector),
10925                        }
10926                    })
10927                    .collect(),
10928                all: false,
10929            });
10930            cx.background_spawn(request).detach_and_log_err(cx);
10931        } else {
10932            let stop_task = if only_restart_servers.is_empty() {
10933                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10934            } else {
10935                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10936            };
10937            cx.spawn(async move |lsp_store, cx| {
10938                stop_task.await;
10939                lsp_store.update(cx, |lsp_store, cx| {
10940                    for buffer in buffers {
10941                        lsp_store.register_buffer_with_language_servers(
10942                            &buffer,
10943                            only_restart_servers.clone(),
10944                            true,
10945                            cx,
10946                        );
10947                    }
10948                })
10949            })
10950            .detach();
10951        }
10952    }
10953
10954    pub fn stop_language_servers_for_buffers(
10955        &mut self,
10956        buffers: Vec<Entity<Buffer>>,
10957        also_stop_servers: HashSet<LanguageServerSelector>,
10958        cx: &mut Context<Self>,
10959    ) -> Task<Result<()>> {
10960        if let Some((client, project_id)) = self.upstream_client() {
10961            let request = client.request(proto::StopLanguageServers {
10962                project_id,
10963                buffer_ids: buffers
10964                    .into_iter()
10965                    .map(|b| b.read(cx).remote_id().to_proto())
10966                    .collect(),
10967                also_servers: also_stop_servers
10968                    .into_iter()
10969                    .map(|selector| {
10970                        let selector = match selector {
10971                            LanguageServerSelector::Id(language_server_id) => {
10972                                proto::language_server_selector::Selector::ServerId(
10973                                    language_server_id.to_proto(),
10974                                )
10975                            }
10976                            LanguageServerSelector::Name(language_server_name) => {
10977                                proto::language_server_selector::Selector::Name(
10978                                    language_server_name.to_string(),
10979                                )
10980                            }
10981                        };
10982                        proto::LanguageServerSelector {
10983                            selector: Some(selector),
10984                        }
10985                    })
10986                    .collect(),
10987                all: false,
10988            });
10989            cx.background_spawn(async move {
10990                let _ = request.await?;
10991                Ok(())
10992            })
10993        } else {
10994            let task =
10995                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10996            cx.background_spawn(async move {
10997                task.await;
10998                Ok(())
10999            })
11000        }
11001    }
11002
11003    fn stop_local_language_servers_for_buffers(
11004        &mut self,
11005        buffers: &[Entity<Buffer>],
11006        also_stop_servers: HashSet<LanguageServerSelector>,
11007        cx: &mut Context<Self>,
11008    ) -> Task<()> {
11009        let Some(local) = self.as_local_mut() else {
11010            return Task::ready(());
11011        };
11012        let mut language_server_names_to_stop = BTreeSet::default();
11013        let mut language_servers_to_stop = also_stop_servers
11014            .into_iter()
11015            .flat_map(|selector| match selector {
11016                LanguageServerSelector::Id(id) => Some(id),
11017                LanguageServerSelector::Name(name) => {
11018                    language_server_names_to_stop.insert(name);
11019                    None
11020                }
11021            })
11022            .collect::<BTreeSet<_>>();
11023
11024        let mut covered_worktrees = HashSet::default();
11025        for buffer in buffers {
11026            buffer.update(cx, |buffer, cx| {
11027                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11028                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11029                    && covered_worktrees.insert(worktree_id)
11030                {
11031                    language_server_names_to_stop.retain(|name| {
11032                        let old_ids_count = language_servers_to_stop.len();
11033                        let all_language_servers_with_this_name = local
11034                            .language_server_ids
11035                            .iter()
11036                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11037                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11038                        old_ids_count == language_servers_to_stop.len()
11039                    });
11040                }
11041            });
11042        }
11043        for name in language_server_names_to_stop {
11044            language_servers_to_stop.extend(
11045                local
11046                    .language_server_ids
11047                    .iter()
11048                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11049            );
11050        }
11051
11052        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11053        let tasks = language_servers_to_stop
11054            .into_iter()
11055            .map(|server| self.stop_local_language_server(server, cx))
11056            .collect::<Vec<_>>();
11057
11058        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11059    }
11060
11061    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11062        let (worktree, relative_path) =
11063            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11064
11065        let project_path = ProjectPath {
11066            worktree_id: worktree.read(cx).id(),
11067            path: relative_path,
11068        };
11069
11070        Some(
11071            self.buffer_store()
11072                .read(cx)
11073                .get_by_path(&project_path)?
11074                .read(cx),
11075        )
11076    }
11077
11078    #[cfg(any(test, feature = "test-support"))]
11079    pub fn update_diagnostics(
11080        &mut self,
11081        server_id: LanguageServerId,
11082        diagnostics: lsp::PublishDiagnosticsParams,
11083        result_id: Option<SharedString>,
11084        source_kind: DiagnosticSourceKind,
11085        disk_based_sources: &[String],
11086        cx: &mut Context<Self>,
11087    ) -> Result<()> {
11088        self.merge_lsp_diagnostics(
11089            source_kind,
11090            vec![DocumentDiagnosticsUpdate {
11091                diagnostics,
11092                result_id,
11093                server_id,
11094                disk_based_sources: Cow::Borrowed(disk_based_sources),
11095                registration_id: None,
11096            }],
11097            |_, _, _| false,
11098            cx,
11099        )
11100    }
11101
11102    pub fn merge_lsp_diagnostics(
11103        &mut self,
11104        source_kind: DiagnosticSourceKind,
11105        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11106        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11107        cx: &mut Context<Self>,
11108    ) -> Result<()> {
11109        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11110        let updates = lsp_diagnostics
11111            .into_iter()
11112            .filter_map(|update| {
11113                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11114                Some(DocumentDiagnosticsUpdate {
11115                    diagnostics: self.lsp_to_document_diagnostics(
11116                        abs_path,
11117                        source_kind,
11118                        update.server_id,
11119                        update.diagnostics,
11120                        &update.disk_based_sources,
11121                        update.registration_id.clone(),
11122                    ),
11123                    result_id: update.result_id,
11124                    server_id: update.server_id,
11125                    disk_based_sources: update.disk_based_sources,
11126                    registration_id: update.registration_id,
11127                })
11128            })
11129            .collect();
11130        self.merge_diagnostic_entries(updates, merge, cx)?;
11131        Ok(())
11132    }
11133
11134    fn lsp_to_document_diagnostics(
11135        &mut self,
11136        document_abs_path: PathBuf,
11137        source_kind: DiagnosticSourceKind,
11138        server_id: LanguageServerId,
11139        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11140        disk_based_sources: &[String],
11141        registration_id: Option<SharedString>,
11142    ) -> DocumentDiagnostics {
11143        let mut diagnostics = Vec::default();
11144        let mut primary_diagnostic_group_ids = HashMap::default();
11145        let mut sources_by_group_id = HashMap::default();
11146        let mut supporting_diagnostics = HashMap::default();
11147
11148        let adapter = self.language_server_adapter_for_id(server_id);
11149
11150        // Ensure that primary diagnostics are always the most severe
11151        lsp_diagnostics
11152            .diagnostics
11153            .sort_by_key(|item| item.severity);
11154
11155        for diagnostic in &lsp_diagnostics.diagnostics {
11156            let source = diagnostic.source.as_ref();
11157            let range = range_from_lsp(diagnostic.range);
11158            let is_supporting = diagnostic
11159                .related_information
11160                .as_ref()
11161                .is_some_and(|infos| {
11162                    infos.iter().any(|info| {
11163                        primary_diagnostic_group_ids.contains_key(&(
11164                            source,
11165                            diagnostic.code.clone(),
11166                            range_from_lsp(info.location.range),
11167                        ))
11168                    })
11169                });
11170
11171            let is_unnecessary = diagnostic
11172                .tags
11173                .as_ref()
11174                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11175
11176            let underline = self
11177                .language_server_adapter_for_id(server_id)
11178                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11179
11180            if is_supporting {
11181                supporting_diagnostics.insert(
11182                    (source, diagnostic.code.clone(), range),
11183                    (diagnostic.severity, is_unnecessary),
11184                );
11185            } else {
11186                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11187                let is_disk_based =
11188                    source.is_some_and(|source| disk_based_sources.contains(source));
11189
11190                sources_by_group_id.insert(group_id, source);
11191                primary_diagnostic_group_ids
11192                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11193
11194                diagnostics.push(DiagnosticEntry {
11195                    range,
11196                    diagnostic: Diagnostic {
11197                        source: diagnostic.source.clone(),
11198                        source_kind,
11199                        code: diagnostic.code.clone(),
11200                        code_description: diagnostic
11201                            .code_description
11202                            .as_ref()
11203                            .and_then(|d| d.href.clone()),
11204                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11205                        markdown: adapter.as_ref().and_then(|adapter| {
11206                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11207                        }),
11208                        message: diagnostic.message.trim().to_string(),
11209                        group_id,
11210                        is_primary: true,
11211                        is_disk_based,
11212                        is_unnecessary,
11213                        underline,
11214                        data: diagnostic.data.clone(),
11215                        registration_id: registration_id.clone(),
11216                    },
11217                });
11218                if let Some(infos) = &diagnostic.related_information {
11219                    for info in infos {
11220                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11221                            let range = range_from_lsp(info.location.range);
11222                            diagnostics.push(DiagnosticEntry {
11223                                range,
11224                                diagnostic: Diagnostic {
11225                                    source: diagnostic.source.clone(),
11226                                    source_kind,
11227                                    code: diagnostic.code.clone(),
11228                                    code_description: diagnostic
11229                                        .code_description
11230                                        .as_ref()
11231                                        .and_then(|d| d.href.clone()),
11232                                    severity: DiagnosticSeverity::INFORMATION,
11233                                    markdown: adapter.as_ref().and_then(|adapter| {
11234                                        adapter.diagnostic_message_to_markdown(&info.message)
11235                                    }),
11236                                    message: info.message.trim().to_string(),
11237                                    group_id,
11238                                    is_primary: false,
11239                                    is_disk_based,
11240                                    is_unnecessary: false,
11241                                    underline,
11242                                    data: diagnostic.data.clone(),
11243                                    registration_id: registration_id.clone(),
11244                                },
11245                            });
11246                        }
11247                    }
11248                }
11249            }
11250        }
11251
11252        for entry in &mut diagnostics {
11253            let diagnostic = &mut entry.diagnostic;
11254            if !diagnostic.is_primary {
11255                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11256                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11257                    source,
11258                    diagnostic.code.clone(),
11259                    entry.range.clone(),
11260                )) {
11261                    if let Some(severity) = severity {
11262                        diagnostic.severity = severity;
11263                    }
11264                    diagnostic.is_unnecessary = is_unnecessary;
11265                }
11266            }
11267        }
11268
11269        DocumentDiagnostics {
11270            diagnostics,
11271            document_abs_path,
11272            version: lsp_diagnostics.version,
11273        }
11274    }
11275
11276    fn insert_newly_running_language_server(
11277        &mut self,
11278        adapter: Arc<CachedLspAdapter>,
11279        language_server: Arc<LanguageServer>,
11280        server_id: LanguageServerId,
11281        key: LanguageServerSeed,
11282        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11283        cx: &mut Context<Self>,
11284    ) {
11285        let Some(local) = self.as_local_mut() else {
11286            return;
11287        };
11288        // If the language server for this key doesn't match the server id, don't store the
11289        // server. Which will cause it to be dropped, killing the process
11290        if local
11291            .language_server_ids
11292            .get(&key)
11293            .map(|state| state.id != server_id)
11294            .unwrap_or(false)
11295        {
11296            return;
11297        }
11298
11299        // Update language_servers collection with Running variant of LanguageServerState
11300        // indicating that the server is up and running and ready
11301        let workspace_folders = workspace_folders.lock().clone();
11302        language_server.set_workspace_folders(workspace_folders);
11303
11304        let workspace_diagnostics_refresh_tasks = language_server
11305            .capabilities()
11306            .diagnostic_provider
11307            .and_then(|provider| {
11308                local
11309                    .language_server_dynamic_registrations
11310                    .entry(server_id)
11311                    .or_default()
11312                    .diagnostics
11313                    .entry(None)
11314                    .or_insert(provider.clone());
11315                let workspace_refresher =
11316                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11317
11318                Some((None, workspace_refresher))
11319            })
11320            .into_iter()
11321            .collect();
11322        local.language_servers.insert(
11323            server_id,
11324            LanguageServerState::Running {
11325                workspace_diagnostics_refresh_tasks,
11326                adapter: adapter.clone(),
11327                server: language_server.clone(),
11328                simulate_disk_based_diagnostics_completion: None,
11329            },
11330        );
11331        local
11332            .languages
11333            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11334        if let Some(file_ops_caps) = language_server
11335            .capabilities()
11336            .workspace
11337            .as_ref()
11338            .and_then(|ws| ws.file_operations.as_ref())
11339        {
11340            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11341            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11342            if did_rename_caps.or(will_rename_caps).is_some() {
11343                let watcher = RenamePathsWatchedForServer::default()
11344                    .with_did_rename_patterns(did_rename_caps)
11345                    .with_will_rename_patterns(will_rename_caps);
11346                local
11347                    .language_server_paths_watched_for_rename
11348                    .insert(server_id, watcher);
11349            }
11350        }
11351
11352        self.language_server_statuses.insert(
11353            server_id,
11354            LanguageServerStatus {
11355                name: language_server.name(),
11356                server_version: language_server.version(),
11357                pending_work: Default::default(),
11358                has_pending_diagnostic_updates: false,
11359                progress_tokens: Default::default(),
11360                worktree: Some(key.worktree_id),
11361                binary: Some(language_server.binary().clone()),
11362                configuration: Some(language_server.configuration().clone()),
11363                workspace_folders: language_server.workspace_folders(),
11364                process_id: language_server.process_id(),
11365            },
11366        );
11367
11368        cx.emit(LspStoreEvent::LanguageServerAdded(
11369            server_id,
11370            language_server.name(),
11371            Some(key.worktree_id),
11372        ));
11373
11374        let server_capabilities = language_server.capabilities();
11375        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11376            downstream_client
11377                .send(proto::StartLanguageServer {
11378                    project_id: *project_id,
11379                    server: Some(proto::LanguageServer {
11380                        id: server_id.to_proto(),
11381                        name: language_server.name().to_string(),
11382                        worktree_id: Some(key.worktree_id.to_proto()),
11383                    }),
11384                    capabilities: serde_json::to_string(&server_capabilities)
11385                        .expect("serializing server LSP capabilities"),
11386                })
11387                .log_err();
11388        }
11389        self.lsp_server_capabilities
11390            .insert(server_id, server_capabilities);
11391
11392        // Tell the language server about every open buffer in the worktree that matches the language.
11393        // Also check for buffers in worktrees that reused this server
11394        let mut worktrees_using_server = vec![key.worktree_id];
11395        if let Some(local) = self.as_local() {
11396            // Find all worktrees that have this server in their language server tree
11397            for (worktree_id, servers) in &local.lsp_tree.instances {
11398                if *worktree_id != key.worktree_id {
11399                    for server_map in servers.roots.values() {
11400                        if server_map
11401                            .values()
11402                            .any(|(node, _)| node.id() == Some(server_id))
11403                        {
11404                            worktrees_using_server.push(*worktree_id);
11405                        }
11406                    }
11407                }
11408            }
11409        }
11410
11411        let mut buffer_paths_registered = Vec::new();
11412        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11413            let mut lsp_adapters = HashMap::default();
11414            for buffer_handle in buffer_store.buffers() {
11415                let buffer = buffer_handle.read(cx);
11416                let file = match File::from_dyn(buffer.file()) {
11417                    Some(file) => file,
11418                    None => continue,
11419                };
11420                let language = match buffer.language() {
11421                    Some(language) => language,
11422                    None => continue,
11423                };
11424
11425                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11426                    || !lsp_adapters
11427                        .entry(language.name())
11428                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11429                        .iter()
11430                        .any(|a| a.name == key.name)
11431                {
11432                    continue;
11433                }
11434                // didOpen
11435                let file = match file.as_local() {
11436                    Some(file) => file,
11437                    None => continue,
11438                };
11439
11440                let local = self.as_local_mut().unwrap();
11441
11442                let buffer_id = buffer.remote_id();
11443                if local.registered_buffers.contains_key(&buffer_id) {
11444                    let abs_path = file.abs_path(cx);
11445                    let uri = match lsp::Uri::from_file_path(&abs_path) {
11446                        Ok(uri) => uri,
11447                        Err(()) => {
11448                            log::error!("failed to convert path to URI: {:?}", abs_path);
11449                            continue;
11450                        }
11451                    };
11452
11453                    let versions = local
11454                        .buffer_snapshots
11455                        .entry(buffer_id)
11456                        .or_default()
11457                        .entry(server_id)
11458                        .and_modify(|_| {
11459                            assert!(
11460                            false,
11461                            "There should not be an existing snapshot for a newly inserted buffer"
11462                        )
11463                        })
11464                        .or_insert_with(|| {
11465                            vec![LspBufferSnapshot {
11466                                version: 0,
11467                                snapshot: buffer.text_snapshot(),
11468                            }]
11469                        });
11470
11471                    let snapshot = versions.last().unwrap();
11472                    let version = snapshot.version;
11473                    let initial_snapshot = &snapshot.snapshot;
11474                    language_server.register_buffer(
11475                        uri,
11476                        adapter.language_id(&language.name()),
11477                        version,
11478                        initial_snapshot.text(),
11479                    );
11480                    buffer_paths_registered.push((buffer_id, abs_path));
11481                    local
11482                        .buffers_opened_in_servers
11483                        .entry(buffer_id)
11484                        .or_default()
11485                        .insert(server_id);
11486                }
11487                buffer_handle.update(cx, |buffer, cx| {
11488                    buffer.set_completion_triggers(
11489                        server_id,
11490                        language_server
11491                            .capabilities()
11492                            .completion_provider
11493                            .as_ref()
11494                            .and_then(|provider| {
11495                                provider
11496                                    .trigger_characters
11497                                    .as_ref()
11498                                    .map(|characters| characters.iter().cloned().collect())
11499                            })
11500                            .unwrap_or_default(),
11501                        cx,
11502                    )
11503                });
11504            }
11505        });
11506
11507        for (buffer_id, abs_path) in buffer_paths_registered {
11508            cx.emit(LspStoreEvent::LanguageServerUpdate {
11509                language_server_id: server_id,
11510                name: Some(adapter.name()),
11511                message: proto::update_language_server::Variant::RegisteredForBuffer(
11512                    proto::RegisteredForBuffer {
11513                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11514                        buffer_id: buffer_id.to_proto(),
11515                    },
11516                ),
11517            });
11518        }
11519
11520        cx.notify();
11521    }
11522
11523    pub fn language_servers_running_disk_based_diagnostics(
11524        &self,
11525    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11526        self.language_server_statuses
11527            .iter()
11528            .filter_map(|(id, status)| {
11529                if status.has_pending_diagnostic_updates {
11530                    Some(*id)
11531                } else {
11532                    None
11533                }
11534            })
11535    }
11536
11537    pub(crate) fn cancel_language_server_work_for_buffers(
11538        &mut self,
11539        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11540        cx: &mut Context<Self>,
11541    ) {
11542        if let Some((client, project_id)) = self.upstream_client() {
11543            let request = client.request(proto::CancelLanguageServerWork {
11544                project_id,
11545                work: Some(proto::cancel_language_server_work::Work::Buffers(
11546                    proto::cancel_language_server_work::Buffers {
11547                        buffer_ids: buffers
11548                            .into_iter()
11549                            .map(|b| b.read(cx).remote_id().to_proto())
11550                            .collect(),
11551                    },
11552                )),
11553            });
11554            cx.background_spawn(request).detach_and_log_err(cx);
11555        } else if let Some(local) = self.as_local() {
11556            let servers = buffers
11557                .into_iter()
11558                .flat_map(|buffer| {
11559                    buffer.update(cx, |buffer, cx| {
11560                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11561                    })
11562                })
11563                .collect::<HashSet<_>>();
11564            for server_id in servers {
11565                self.cancel_language_server_work(server_id, None, cx);
11566            }
11567        }
11568    }
11569
11570    pub(crate) fn cancel_language_server_work(
11571        &mut self,
11572        server_id: LanguageServerId,
11573        token_to_cancel: Option<ProgressToken>,
11574        cx: &mut Context<Self>,
11575    ) {
11576        if let Some(local) = self.as_local() {
11577            let status = self.language_server_statuses.get(&server_id);
11578            let server = local.language_servers.get(&server_id);
11579            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11580            {
11581                for (token, progress) in &status.pending_work {
11582                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11583                        && token != token_to_cancel
11584                    {
11585                        continue;
11586                    }
11587                    if progress.is_cancellable {
11588                        server
11589                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11590                                WorkDoneProgressCancelParams {
11591                                    token: token.to_lsp(),
11592                                },
11593                            )
11594                            .ok();
11595                    }
11596                }
11597            }
11598        } else if let Some((client, project_id)) = self.upstream_client() {
11599            let request = client.request(proto::CancelLanguageServerWork {
11600                project_id,
11601                work: Some(
11602                    proto::cancel_language_server_work::Work::LanguageServerWork(
11603                        proto::cancel_language_server_work::LanguageServerWork {
11604                            language_server_id: server_id.to_proto(),
11605                            token: token_to_cancel.map(|token| token.to_proto()),
11606                        },
11607                    ),
11608                ),
11609            });
11610            cx.background_spawn(request).detach_and_log_err(cx);
11611        }
11612    }
11613
11614    fn register_supplementary_language_server(
11615        &mut self,
11616        id: LanguageServerId,
11617        name: LanguageServerName,
11618        server: Arc<LanguageServer>,
11619        cx: &mut Context<Self>,
11620    ) {
11621        if let Some(local) = self.as_local_mut() {
11622            local
11623                .supplementary_language_servers
11624                .insert(id, (name.clone(), server));
11625            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11626        }
11627    }
11628
11629    fn unregister_supplementary_language_server(
11630        &mut self,
11631        id: LanguageServerId,
11632        cx: &mut Context<Self>,
11633    ) {
11634        if let Some(local) = self.as_local_mut() {
11635            local.supplementary_language_servers.remove(&id);
11636            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11637        }
11638    }
11639
11640    pub(crate) fn supplementary_language_servers(
11641        &self,
11642    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11643        self.as_local().into_iter().flat_map(|local| {
11644            local
11645                .supplementary_language_servers
11646                .iter()
11647                .map(|(id, (name, _))| (*id, name.clone()))
11648        })
11649    }
11650
11651    pub fn language_server_adapter_for_id(
11652        &self,
11653        id: LanguageServerId,
11654    ) -> Option<Arc<CachedLspAdapter>> {
11655        self.as_local()
11656            .and_then(|local| local.language_servers.get(&id))
11657            .and_then(|language_server_state| match language_server_state {
11658                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11659                _ => None,
11660            })
11661    }
11662
11663    pub(super) fn update_local_worktree_language_servers(
11664        &mut self,
11665        worktree_handle: &Entity<Worktree>,
11666        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11667        cx: &mut Context<Self>,
11668    ) {
11669        if changes.is_empty() {
11670            return;
11671        }
11672
11673        let Some(local) = self.as_local() else { return };
11674
11675        local.prettier_store.update(cx, |prettier_store, cx| {
11676            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11677        });
11678
11679        let worktree_id = worktree_handle.read(cx).id();
11680        let mut language_server_ids = local
11681            .language_server_ids
11682            .iter()
11683            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11684            .collect::<Vec<_>>();
11685        language_server_ids.sort();
11686        language_server_ids.dedup();
11687
11688        // let abs_path = worktree_handle.read(cx).abs_path();
11689        for server_id in &language_server_ids {
11690            if let Some(LanguageServerState::Running { server, .. }) =
11691                local.language_servers.get(server_id)
11692                && let Some(watched_paths) = local
11693                    .language_server_watched_paths
11694                    .get(server_id)
11695                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11696            {
11697                let params = lsp::DidChangeWatchedFilesParams {
11698                    changes: changes
11699                        .iter()
11700                        .filter_map(|(path, _, change)| {
11701                            if !watched_paths.is_match(path.as_std_path()) {
11702                                return None;
11703                            }
11704                            let typ = match change {
11705                                PathChange::Loaded => return None,
11706                                PathChange::Added => lsp::FileChangeType::CREATED,
11707                                PathChange::Removed => lsp::FileChangeType::DELETED,
11708                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11709                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11710                            };
11711                            let uri = lsp::Uri::from_file_path(
11712                                worktree_handle.read(cx).absolutize(&path),
11713                            )
11714                            .ok()?;
11715                            Some(lsp::FileEvent { uri, typ })
11716                        })
11717                        .collect(),
11718                };
11719                if !params.changes.is_empty() {
11720                    server
11721                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11722                        .ok();
11723                }
11724            }
11725        }
11726        for (path, _, _) in changes {
11727            if let Some(file_name) = path.file_name()
11728                && local.watched_manifest_filenames.contains(file_name)
11729            {
11730                self.request_workspace_config_refresh();
11731                break;
11732            }
11733        }
11734    }
11735
11736    pub fn wait_for_remote_buffer(
11737        &mut self,
11738        id: BufferId,
11739        cx: &mut Context<Self>,
11740    ) -> Task<Result<Entity<Buffer>>> {
11741        self.buffer_store.update(cx, |buffer_store, cx| {
11742            buffer_store.wait_for_remote_buffer(id, cx)
11743        })
11744    }
11745
11746    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11747        let mut result = proto::Symbol {
11748            language_server_name: symbol.language_server_name.0.to_string(),
11749            source_worktree_id: symbol.source_worktree_id.to_proto(),
11750            language_server_id: symbol.source_language_server_id.to_proto(),
11751            name: symbol.name.clone(),
11752            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11753            start: Some(proto::PointUtf16 {
11754                row: symbol.range.start.0.row,
11755                column: symbol.range.start.0.column,
11756            }),
11757            end: Some(proto::PointUtf16 {
11758                row: symbol.range.end.0.row,
11759                column: symbol.range.end.0.column,
11760            }),
11761            worktree_id: Default::default(),
11762            path: Default::default(),
11763            signature: Default::default(),
11764            container_name: symbol.container_name.clone(),
11765        };
11766        match &symbol.path {
11767            SymbolLocation::InProject(path) => {
11768                result.worktree_id = path.worktree_id.to_proto();
11769                result.path = path.path.to_proto();
11770            }
11771            SymbolLocation::OutsideProject {
11772                abs_path,
11773                signature,
11774            } => {
11775                result.path = abs_path.to_string_lossy().into_owned();
11776                result.signature = signature.to_vec();
11777            }
11778        }
11779        result
11780    }
11781
11782    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11783        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11784        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11785        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11786
11787        let path = if serialized_symbol.signature.is_empty() {
11788            SymbolLocation::InProject(ProjectPath {
11789                worktree_id,
11790                path: RelPath::from_proto(&serialized_symbol.path)
11791                    .context("invalid symbol path")?,
11792            })
11793        } else {
11794            SymbolLocation::OutsideProject {
11795                abs_path: Path::new(&serialized_symbol.path).into(),
11796                signature: serialized_symbol
11797                    .signature
11798                    .try_into()
11799                    .map_err(|_| anyhow!("invalid signature"))?,
11800            }
11801        };
11802
11803        let start = serialized_symbol.start.context("invalid start")?;
11804        let end = serialized_symbol.end.context("invalid end")?;
11805        Ok(CoreSymbol {
11806            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11807            source_worktree_id,
11808            source_language_server_id: LanguageServerId::from_proto(
11809                serialized_symbol.language_server_id,
11810            ),
11811            path,
11812            name: serialized_symbol.name,
11813            range: Unclipped(PointUtf16::new(start.row, start.column))
11814                ..Unclipped(PointUtf16::new(end.row, end.column)),
11815            kind,
11816            container_name: serialized_symbol.container_name,
11817        })
11818    }
11819
11820    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11821        let mut serialized_completion = proto::Completion {
11822            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11823            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11824            new_text: completion.new_text.clone(),
11825            ..proto::Completion::default()
11826        };
11827        match &completion.source {
11828            CompletionSource::Lsp {
11829                insert_range,
11830                server_id,
11831                lsp_completion,
11832                lsp_defaults,
11833                resolved,
11834            } => {
11835                let (old_insert_start, old_insert_end) = insert_range
11836                    .as_ref()
11837                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11838                    .unzip();
11839
11840                serialized_completion.old_insert_start = old_insert_start;
11841                serialized_completion.old_insert_end = old_insert_end;
11842                serialized_completion.source = proto::completion::Source::Lsp as i32;
11843                serialized_completion.server_id = server_id.0 as u64;
11844                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11845                serialized_completion.lsp_defaults = lsp_defaults
11846                    .as_deref()
11847                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11848                serialized_completion.resolved = *resolved;
11849            }
11850            CompletionSource::BufferWord {
11851                word_range,
11852                resolved,
11853            } => {
11854                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11855                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11856                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11857                serialized_completion.resolved = *resolved;
11858            }
11859            CompletionSource::Custom => {
11860                serialized_completion.source = proto::completion::Source::Custom as i32;
11861                serialized_completion.resolved = true;
11862            }
11863            CompletionSource::Dap { sort_text } => {
11864                serialized_completion.source = proto::completion::Source::Dap as i32;
11865                serialized_completion.sort_text = Some(sort_text.clone());
11866            }
11867        }
11868
11869        serialized_completion
11870    }
11871
11872    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11873        let old_replace_start = completion
11874            .old_replace_start
11875            .and_then(deserialize_anchor)
11876            .context("invalid old start")?;
11877        let old_replace_end = completion
11878            .old_replace_end
11879            .and_then(deserialize_anchor)
11880            .context("invalid old end")?;
11881        let insert_range = {
11882            match completion.old_insert_start.zip(completion.old_insert_end) {
11883                Some((start, end)) => {
11884                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11885                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11886                    Some(start..end)
11887                }
11888                None => None,
11889            }
11890        };
11891        Ok(CoreCompletion {
11892            replace_range: old_replace_start..old_replace_end,
11893            new_text: completion.new_text,
11894            source: match proto::completion::Source::from_i32(completion.source) {
11895                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11896                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11897                    insert_range,
11898                    server_id: LanguageServerId::from_proto(completion.server_id),
11899                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11900                    lsp_defaults: completion
11901                        .lsp_defaults
11902                        .as_deref()
11903                        .map(serde_json::from_slice)
11904                        .transpose()?,
11905                    resolved: completion.resolved,
11906                },
11907                Some(proto::completion::Source::BufferWord) => {
11908                    let word_range = completion
11909                        .buffer_word_start
11910                        .and_then(deserialize_anchor)
11911                        .context("invalid buffer word start")?
11912                        ..completion
11913                            .buffer_word_end
11914                            .and_then(deserialize_anchor)
11915                            .context("invalid buffer word end")?;
11916                    CompletionSource::BufferWord {
11917                        word_range,
11918                        resolved: completion.resolved,
11919                    }
11920                }
11921                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11922                    sort_text: completion
11923                        .sort_text
11924                        .context("expected sort text to exist")?,
11925                },
11926                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11927            },
11928        })
11929    }
11930
11931    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11932        let (kind, lsp_action) = match &action.lsp_action {
11933            LspAction::Action(code_action) => (
11934                proto::code_action::Kind::Action as i32,
11935                serde_json::to_vec(code_action).unwrap(),
11936            ),
11937            LspAction::Command(command) => (
11938                proto::code_action::Kind::Command as i32,
11939                serde_json::to_vec(command).unwrap(),
11940            ),
11941            LspAction::CodeLens(code_lens) => (
11942                proto::code_action::Kind::CodeLens as i32,
11943                serde_json::to_vec(code_lens).unwrap(),
11944            ),
11945        };
11946
11947        proto::CodeAction {
11948            server_id: action.server_id.0 as u64,
11949            start: Some(serialize_anchor(&action.range.start)),
11950            end: Some(serialize_anchor(&action.range.end)),
11951            lsp_action,
11952            kind,
11953            resolved: action.resolved,
11954        }
11955    }
11956
11957    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11958        let start = action
11959            .start
11960            .and_then(deserialize_anchor)
11961            .context("invalid start")?;
11962        let end = action
11963            .end
11964            .and_then(deserialize_anchor)
11965            .context("invalid end")?;
11966        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11967            Some(proto::code_action::Kind::Action) => {
11968                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11969            }
11970            Some(proto::code_action::Kind::Command) => {
11971                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11972            }
11973            Some(proto::code_action::Kind::CodeLens) => {
11974                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11975            }
11976            None => anyhow::bail!("Unknown action kind {}", action.kind),
11977        };
11978        Ok(CodeAction {
11979            server_id: LanguageServerId(action.server_id as usize),
11980            range: start..end,
11981            resolved: action.resolved,
11982            lsp_action,
11983        })
11984    }
11985
11986    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11987        match &formatting_result {
11988            Ok(_) => self.last_formatting_failure = None,
11989            Err(error) => {
11990                let error_string = format!("{error:#}");
11991                log::error!("Formatting failed: {error_string}");
11992                self.last_formatting_failure
11993                    .replace(error_string.lines().join(" "));
11994            }
11995        }
11996    }
11997
11998    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11999        self.lsp_server_capabilities.remove(&for_server);
12000        self.semantic_token_config.remove_server_data(for_server);
12001        for lsp_data in self.lsp_data.values_mut() {
12002            lsp_data.remove_server_data(for_server);
12003        }
12004        if let Some(local) = self.as_local_mut() {
12005            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12006            local
12007                .workspace_pull_diagnostics_result_ids
12008                .remove(&for_server);
12009            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12010                buffer_servers.remove(&for_server);
12011            }
12012        }
12013    }
12014
12015    pub fn result_id_for_buffer_pull(
12016        &self,
12017        server_id: LanguageServerId,
12018        buffer_id: BufferId,
12019        registration_id: &Option<SharedString>,
12020        cx: &App,
12021    ) -> Option<SharedString> {
12022        let abs_path = self
12023            .buffer_store
12024            .read(cx)
12025            .get(buffer_id)
12026            .and_then(|b| File::from_dyn(b.read(cx).file()))
12027            .map(|f| f.abs_path(cx))?;
12028        self.as_local()?
12029            .buffer_pull_diagnostics_result_ids
12030            .get(&server_id)?
12031            .get(registration_id)?
12032            .get(&abs_path)?
12033            .clone()
12034    }
12035
12036    /// Gets all result_ids for a workspace diagnostics pull request.
12037    /// 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.
12038    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12039    pub fn result_ids_for_workspace_refresh(
12040        &self,
12041        server_id: LanguageServerId,
12042        registration_id: &Option<SharedString>,
12043    ) -> HashMap<PathBuf, SharedString> {
12044        let Some(local) = self.as_local() else {
12045            return HashMap::default();
12046        };
12047        local
12048            .workspace_pull_diagnostics_result_ids
12049            .get(&server_id)
12050            .into_iter()
12051            .filter_map(|diagnostics| diagnostics.get(registration_id))
12052            .flatten()
12053            .filter_map(|(abs_path, result_id)| {
12054                let result_id = local
12055                    .buffer_pull_diagnostics_result_ids
12056                    .get(&server_id)
12057                    .and_then(|buffer_ids_result_ids| {
12058                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12059                    })
12060                    .cloned()
12061                    .flatten()
12062                    .or_else(|| result_id.clone())?;
12063                Some((abs_path.clone(), result_id))
12064            })
12065            .collect()
12066    }
12067
12068    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12069        if let Some(LanguageServerState::Running {
12070            workspace_diagnostics_refresh_tasks,
12071            ..
12072        }) = self
12073            .as_local_mut()
12074            .and_then(|local| local.language_servers.get_mut(&server_id))
12075        {
12076            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12077                diagnostics.refresh_tx.try_send(()).ok();
12078            }
12079        }
12080    }
12081
12082    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12083    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12084    /// which requires refreshing both workspace and document diagnostics.
12085    pub fn pull_document_diagnostics_for_server(
12086        &mut self,
12087        server_id: LanguageServerId,
12088        source_buffer_id: Option<BufferId>,
12089        cx: &mut Context<Self>,
12090    ) -> Shared<Task<()>> {
12091        let Some(local) = self.as_local_mut() else {
12092            return Task::ready(()).shared();
12093        };
12094        let mut buffers_to_refresh = HashSet::default();
12095        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12096            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12097                buffers_to_refresh.insert(*buffer_id);
12098            }
12099        }
12100
12101        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12102    }
12103
12104    pub fn pull_document_diagnostics_for_buffer_edit(
12105        &mut self,
12106        buffer_id: BufferId,
12107        cx: &mut Context<Self>,
12108    ) {
12109        let Some(local) = self.as_local_mut() else {
12110            return;
12111        };
12112        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12113        else {
12114            return;
12115        };
12116        for server_id in languages_servers {
12117            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12118        }
12119    }
12120
12121    fn apply_workspace_diagnostic_report(
12122        &mut self,
12123        server_id: LanguageServerId,
12124        report: lsp::WorkspaceDiagnosticReportResult,
12125        registration_id: Option<SharedString>,
12126        cx: &mut Context<Self>,
12127    ) {
12128        let mut workspace_diagnostics =
12129            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12130                report,
12131                server_id,
12132                registration_id,
12133            );
12134        workspace_diagnostics.retain(|d| match &d.diagnostics {
12135            LspPullDiagnostics::Response {
12136                server_id,
12137                registration_id,
12138                ..
12139            } => self.diagnostic_registration_exists(*server_id, registration_id),
12140            LspPullDiagnostics::Default => false,
12141        });
12142        let mut unchanged_buffers = HashMap::default();
12143        let workspace_diagnostics_updates = workspace_diagnostics
12144            .into_iter()
12145            .filter_map(
12146                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12147                    LspPullDiagnostics::Response {
12148                        server_id,
12149                        uri,
12150                        diagnostics,
12151                        registration_id,
12152                    } => Some((
12153                        server_id,
12154                        uri,
12155                        diagnostics,
12156                        workspace_diagnostics.version,
12157                        registration_id,
12158                    )),
12159                    LspPullDiagnostics::Default => None,
12160                },
12161            )
12162            .fold(
12163                HashMap::default(),
12164                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12165                    let (result_id, diagnostics) = match diagnostics {
12166                        PulledDiagnostics::Unchanged { result_id } => {
12167                            unchanged_buffers
12168                                .entry(new_registration_id.clone())
12169                                .or_insert_with(HashSet::default)
12170                                .insert(uri.clone());
12171                            (Some(result_id), Vec::new())
12172                        }
12173                        PulledDiagnostics::Changed {
12174                            result_id,
12175                            diagnostics,
12176                        } => (result_id, diagnostics),
12177                    };
12178                    let disk_based_sources = Cow::Owned(
12179                        self.language_server_adapter_for_id(server_id)
12180                            .as_ref()
12181                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12182                            .unwrap_or(&[])
12183                            .to_vec(),
12184                    );
12185
12186                    let Some(abs_path) = uri.to_file_path().ok() else {
12187                        return acc;
12188                    };
12189                    let Some((worktree, relative_path)) =
12190                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12191                    else {
12192                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12193                        return acc;
12194                    };
12195                    let worktree_id = worktree.read(cx).id();
12196                    let project_path = ProjectPath {
12197                        worktree_id,
12198                        path: relative_path,
12199                    };
12200                    if let Some(local_lsp_store) = self.as_local_mut() {
12201                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12202                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12203                    }
12204                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12205                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12206                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12207                        acc.entry(server_id)
12208                            .or_insert_with(HashMap::default)
12209                            .entry(new_registration_id.clone())
12210                            .or_insert_with(Vec::new)
12211                            .push(DocumentDiagnosticsUpdate {
12212                                server_id,
12213                                diagnostics: lsp::PublishDiagnosticsParams {
12214                                    uri,
12215                                    diagnostics,
12216                                    version,
12217                                },
12218                                result_id: result_id.map(SharedString::new),
12219                                disk_based_sources,
12220                                registration_id: new_registration_id,
12221                            });
12222                    }
12223                    acc
12224                },
12225            );
12226
12227        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12228            for (registration_id, diagnostic_updates) in diagnostic_updates {
12229                self.merge_lsp_diagnostics(
12230                    DiagnosticSourceKind::Pulled,
12231                    diagnostic_updates,
12232                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12233                        DiagnosticSourceKind::Pulled => {
12234                            old_diagnostic.registration_id != registration_id
12235                                || unchanged_buffers
12236                                    .get(&old_diagnostic.registration_id)
12237                                    .is_some_and(|unchanged_buffers| {
12238                                        unchanged_buffers.contains(&document_uri)
12239                                    })
12240                        }
12241                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12242                    },
12243                    cx,
12244                )
12245                .log_err();
12246            }
12247        }
12248    }
12249
12250    fn register_server_capabilities(
12251        &mut self,
12252        server_id: LanguageServerId,
12253        params: lsp::RegistrationParams,
12254        cx: &mut Context<Self>,
12255    ) -> anyhow::Result<()> {
12256        let server = self
12257            .language_server_for_id(server_id)
12258            .with_context(|| format!("no server {server_id} found"))?;
12259        for reg in params.registrations {
12260            match reg.method.as_str() {
12261                "workspace/didChangeWatchedFiles" => {
12262                    if let Some(options) = reg.register_options {
12263                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12264                            let caps = serde_json::from_value(options)?;
12265                            local_lsp_store
12266                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12267                            true
12268                        } else {
12269                            false
12270                        };
12271                        if notify {
12272                            notify_server_capabilities_updated(&server, cx);
12273                        }
12274                    }
12275                }
12276                "workspace/didChangeConfiguration" => {
12277                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12278                }
12279                "workspace/didChangeWorkspaceFolders" => {
12280                    // In this case register options is an empty object, we can ignore it
12281                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12282                        supported: Some(true),
12283                        change_notifications: Some(OneOf::Right(reg.id)),
12284                    };
12285                    server.update_capabilities(|capabilities| {
12286                        capabilities
12287                            .workspace
12288                            .get_or_insert_default()
12289                            .workspace_folders = Some(caps);
12290                    });
12291                    notify_server_capabilities_updated(&server, cx);
12292                }
12293                "workspace/symbol" => {
12294                    let options = parse_register_capabilities(reg)?;
12295                    server.update_capabilities(|capabilities| {
12296                        capabilities.workspace_symbol_provider = Some(options);
12297                    });
12298                    notify_server_capabilities_updated(&server, cx);
12299                }
12300                "workspace/fileOperations" => {
12301                    if let Some(options) = reg.register_options {
12302                        let caps = serde_json::from_value(options)?;
12303                        server.update_capabilities(|capabilities| {
12304                            capabilities
12305                                .workspace
12306                                .get_or_insert_default()
12307                                .file_operations = Some(caps);
12308                        });
12309                        notify_server_capabilities_updated(&server, cx);
12310                    }
12311                }
12312                "workspace/executeCommand" => {
12313                    if let Some(options) = reg.register_options {
12314                        let options = serde_json::from_value(options)?;
12315                        server.update_capabilities(|capabilities| {
12316                            capabilities.execute_command_provider = Some(options);
12317                        });
12318                        notify_server_capabilities_updated(&server, cx);
12319                    }
12320                }
12321                "textDocument/rangeFormatting" => {
12322                    let options = parse_register_capabilities(reg)?;
12323                    server.update_capabilities(|capabilities| {
12324                        capabilities.document_range_formatting_provider = Some(options);
12325                    });
12326                    notify_server_capabilities_updated(&server, cx);
12327                }
12328                "textDocument/onTypeFormatting" => {
12329                    if let Some(options) = reg
12330                        .register_options
12331                        .map(serde_json::from_value)
12332                        .transpose()?
12333                    {
12334                        server.update_capabilities(|capabilities| {
12335                            capabilities.document_on_type_formatting_provider = Some(options);
12336                        });
12337                        notify_server_capabilities_updated(&server, cx);
12338                    }
12339                }
12340                "textDocument/formatting" => {
12341                    let options = parse_register_capabilities(reg)?;
12342                    server.update_capabilities(|capabilities| {
12343                        capabilities.document_formatting_provider = Some(options);
12344                    });
12345                    notify_server_capabilities_updated(&server, cx);
12346                }
12347                "textDocument/rename" => {
12348                    let options = parse_register_capabilities(reg)?;
12349                    server.update_capabilities(|capabilities| {
12350                        capabilities.rename_provider = Some(options);
12351                    });
12352                    notify_server_capabilities_updated(&server, cx);
12353                }
12354                "textDocument/inlayHint" => {
12355                    let options = parse_register_capabilities(reg)?;
12356                    server.update_capabilities(|capabilities| {
12357                        capabilities.inlay_hint_provider = Some(options);
12358                    });
12359                    notify_server_capabilities_updated(&server, cx);
12360                }
12361                "textDocument/documentSymbol" => {
12362                    let options = parse_register_capabilities(reg)?;
12363                    server.update_capabilities(|capabilities| {
12364                        capabilities.document_symbol_provider = Some(options);
12365                    });
12366                    notify_server_capabilities_updated(&server, cx);
12367                }
12368                "textDocument/codeAction" => {
12369                    let options = parse_register_capabilities(reg)?;
12370                    let provider = match options {
12371                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12372                        OneOf::Right(caps) => caps,
12373                    };
12374                    server.update_capabilities(|capabilities| {
12375                        capabilities.code_action_provider = Some(provider);
12376                    });
12377                    notify_server_capabilities_updated(&server, cx);
12378                }
12379                "textDocument/definition" => {
12380                    let options = parse_register_capabilities(reg)?;
12381                    server.update_capabilities(|capabilities| {
12382                        capabilities.definition_provider = Some(options);
12383                    });
12384                    notify_server_capabilities_updated(&server, cx);
12385                }
12386                "textDocument/completion" => {
12387                    if let Some(caps) = reg
12388                        .register_options
12389                        .map(serde_json::from_value::<CompletionOptions>)
12390                        .transpose()?
12391                    {
12392                        server.update_capabilities(|capabilities| {
12393                            capabilities.completion_provider = Some(caps.clone());
12394                        });
12395
12396                        if let Some(local) = self.as_local() {
12397                            let mut buffers_with_language_server = Vec::new();
12398                            for handle in self.buffer_store.read(cx).buffers() {
12399                                let buffer_id = handle.read(cx).remote_id();
12400                                if local
12401                                    .buffers_opened_in_servers
12402                                    .get(&buffer_id)
12403                                    .filter(|s| s.contains(&server_id))
12404                                    .is_some()
12405                                {
12406                                    buffers_with_language_server.push(handle);
12407                                }
12408                            }
12409                            let triggers = caps
12410                                .trigger_characters
12411                                .unwrap_or_default()
12412                                .into_iter()
12413                                .collect::<BTreeSet<_>>();
12414                            for handle in buffers_with_language_server {
12415                                let triggers = triggers.clone();
12416                                let _ = handle.update(cx, move |buffer, cx| {
12417                                    buffer.set_completion_triggers(server_id, triggers, cx);
12418                                });
12419                            }
12420                        }
12421                        notify_server_capabilities_updated(&server, cx);
12422                    }
12423                }
12424                "textDocument/hover" => {
12425                    let options = parse_register_capabilities(reg)?;
12426                    let provider = match options {
12427                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12428                        OneOf::Right(caps) => caps,
12429                    };
12430                    server.update_capabilities(|capabilities| {
12431                        capabilities.hover_provider = Some(provider);
12432                    });
12433                    notify_server_capabilities_updated(&server, cx);
12434                }
12435                "textDocument/signatureHelp" => {
12436                    if let Some(caps) = reg
12437                        .register_options
12438                        .map(serde_json::from_value)
12439                        .transpose()?
12440                    {
12441                        server.update_capabilities(|capabilities| {
12442                            capabilities.signature_help_provider = Some(caps);
12443                        });
12444                        notify_server_capabilities_updated(&server, cx);
12445                    }
12446                }
12447                "textDocument/didChange" => {
12448                    if let Some(sync_kind) = reg
12449                        .register_options
12450                        .and_then(|opts| opts.get("syncKind").cloned())
12451                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12452                        .transpose()?
12453                    {
12454                        server.update_capabilities(|capabilities| {
12455                            let mut sync_options =
12456                                Self::take_text_document_sync_options(capabilities);
12457                            sync_options.change = Some(sync_kind);
12458                            capabilities.text_document_sync =
12459                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12460                        });
12461                        notify_server_capabilities_updated(&server, cx);
12462                    }
12463                }
12464                "textDocument/didSave" => {
12465                    if let Some(include_text) = reg
12466                        .register_options
12467                        .map(|opts| {
12468                            let transpose = opts
12469                                .get("includeText")
12470                                .cloned()
12471                                .map(serde_json::from_value::<Option<bool>>)
12472                                .transpose();
12473                            match transpose {
12474                                Ok(value) => Ok(value.flatten()),
12475                                Err(e) => Err(e),
12476                            }
12477                        })
12478                        .transpose()?
12479                    {
12480                        server.update_capabilities(|capabilities| {
12481                            let mut sync_options =
12482                                Self::take_text_document_sync_options(capabilities);
12483                            sync_options.save =
12484                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12485                                    include_text,
12486                                }));
12487                            capabilities.text_document_sync =
12488                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12489                        });
12490                        notify_server_capabilities_updated(&server, cx);
12491                    }
12492                }
12493                "textDocument/codeLens" => {
12494                    if let Some(caps) = reg
12495                        .register_options
12496                        .map(serde_json::from_value)
12497                        .transpose()?
12498                    {
12499                        server.update_capabilities(|capabilities| {
12500                            capabilities.code_lens_provider = Some(caps);
12501                        });
12502                        notify_server_capabilities_updated(&server, cx);
12503                    }
12504                }
12505                "textDocument/diagnostic" => {
12506                    if let Some(caps) = reg
12507                        .register_options
12508                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12509                        .transpose()?
12510                    {
12511                        let local = self
12512                            .as_local_mut()
12513                            .context("Expected LSP Store to be local")?;
12514                        let state = local
12515                            .language_servers
12516                            .get_mut(&server_id)
12517                            .context("Could not obtain Language Servers state")?;
12518                        local
12519                            .language_server_dynamic_registrations
12520                            .entry(server_id)
12521                            .or_default()
12522                            .diagnostics
12523                            .insert(Some(reg.id.clone()), caps.clone());
12524
12525                        let supports_workspace_diagnostics =
12526                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12527                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12528                                    diagnostic_options.workspace_diagnostics
12529                                }
12530                                DiagnosticServerCapabilities::RegistrationOptions(
12531                                    diagnostic_registration_options,
12532                                ) => {
12533                                    diagnostic_registration_options
12534                                        .diagnostic_options
12535                                        .workspace_diagnostics
12536                                }
12537                            };
12538
12539                        if supports_workspace_diagnostics(&caps) {
12540                            if let LanguageServerState::Running {
12541                                workspace_diagnostics_refresh_tasks,
12542                                ..
12543                            } = state
12544                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12545                                    Some(reg.id.clone()),
12546                                    caps.clone(),
12547                                    server.clone(),
12548                                    cx,
12549                                )
12550                            {
12551                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12552                            }
12553                        }
12554
12555                        server.update_capabilities(|capabilities| {
12556                            capabilities.diagnostic_provider = Some(caps);
12557                        });
12558
12559                        notify_server_capabilities_updated(&server, cx);
12560
12561                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12562                    }
12563                }
12564                "textDocument/documentColor" => {
12565                    let options = parse_register_capabilities(reg)?;
12566                    let provider = match options {
12567                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12568                        OneOf::Right(caps) => caps,
12569                    };
12570                    server.update_capabilities(|capabilities| {
12571                        capabilities.color_provider = Some(provider);
12572                    });
12573                    notify_server_capabilities_updated(&server, cx);
12574                }
12575                "textDocument/foldingRange" => {
12576                    let options = parse_register_capabilities(reg)?;
12577                    let provider = match options {
12578                        OneOf::Left(value) => lsp::FoldingRangeProviderCapability::Simple(value),
12579                        OneOf::Right(caps) => caps,
12580                    };
12581                    server.update_capabilities(|capabilities| {
12582                        capabilities.folding_range_provider = Some(provider);
12583                    });
12584                    notify_server_capabilities_updated(&server, cx);
12585                }
12586                _ => log::warn!("unhandled capability registration: {reg:?}"),
12587            }
12588        }
12589
12590        Ok(())
12591    }
12592
12593    fn unregister_server_capabilities(
12594        &mut self,
12595        server_id: LanguageServerId,
12596        params: lsp::UnregistrationParams,
12597        cx: &mut Context<Self>,
12598    ) -> anyhow::Result<()> {
12599        let server = self
12600            .language_server_for_id(server_id)
12601            .with_context(|| format!("no server {server_id} found"))?;
12602        for unreg in params.unregisterations.iter() {
12603            match unreg.method.as_str() {
12604                "workspace/didChangeWatchedFiles" => {
12605                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12606                        local_lsp_store
12607                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12608                        true
12609                    } else {
12610                        false
12611                    };
12612                    if notify {
12613                        notify_server_capabilities_updated(&server, cx);
12614                    }
12615                }
12616                "workspace/didChangeConfiguration" => {
12617                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12618                }
12619                "workspace/didChangeWorkspaceFolders" => {
12620                    server.update_capabilities(|capabilities| {
12621                        capabilities
12622                            .workspace
12623                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12624                                workspace_folders: None,
12625                                file_operations: None,
12626                            })
12627                            .workspace_folders = None;
12628                    });
12629                    notify_server_capabilities_updated(&server, cx);
12630                }
12631                "workspace/symbol" => {
12632                    server.update_capabilities(|capabilities| {
12633                        capabilities.workspace_symbol_provider = None
12634                    });
12635                    notify_server_capabilities_updated(&server, cx);
12636                }
12637                "workspace/fileOperations" => {
12638                    server.update_capabilities(|capabilities| {
12639                        capabilities
12640                            .workspace
12641                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12642                                workspace_folders: None,
12643                                file_operations: None,
12644                            })
12645                            .file_operations = None;
12646                    });
12647                    notify_server_capabilities_updated(&server, cx);
12648                }
12649                "workspace/executeCommand" => {
12650                    server.update_capabilities(|capabilities| {
12651                        capabilities.execute_command_provider = None;
12652                    });
12653                    notify_server_capabilities_updated(&server, cx);
12654                }
12655                "textDocument/rangeFormatting" => {
12656                    server.update_capabilities(|capabilities| {
12657                        capabilities.document_range_formatting_provider = None
12658                    });
12659                    notify_server_capabilities_updated(&server, cx);
12660                }
12661                "textDocument/onTypeFormatting" => {
12662                    server.update_capabilities(|capabilities| {
12663                        capabilities.document_on_type_formatting_provider = None;
12664                    });
12665                    notify_server_capabilities_updated(&server, cx);
12666                }
12667                "textDocument/formatting" => {
12668                    server.update_capabilities(|capabilities| {
12669                        capabilities.document_formatting_provider = None;
12670                    });
12671                    notify_server_capabilities_updated(&server, cx);
12672                }
12673                "textDocument/rename" => {
12674                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12675                    notify_server_capabilities_updated(&server, cx);
12676                }
12677                "textDocument/codeAction" => {
12678                    server.update_capabilities(|capabilities| {
12679                        capabilities.code_action_provider = None;
12680                    });
12681                    notify_server_capabilities_updated(&server, cx);
12682                }
12683                "textDocument/definition" => {
12684                    server.update_capabilities(|capabilities| {
12685                        capabilities.definition_provider = None;
12686                    });
12687                    notify_server_capabilities_updated(&server, cx);
12688                }
12689                "textDocument/completion" => {
12690                    server.update_capabilities(|capabilities| {
12691                        capabilities.completion_provider = None;
12692                    });
12693                    notify_server_capabilities_updated(&server, cx);
12694                }
12695                "textDocument/hover" => {
12696                    server.update_capabilities(|capabilities| {
12697                        capabilities.hover_provider = None;
12698                    });
12699                    notify_server_capabilities_updated(&server, cx);
12700                }
12701                "textDocument/signatureHelp" => {
12702                    server.update_capabilities(|capabilities| {
12703                        capabilities.signature_help_provider = None;
12704                    });
12705                    notify_server_capabilities_updated(&server, cx);
12706                }
12707                "textDocument/didChange" => {
12708                    server.update_capabilities(|capabilities| {
12709                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12710                        sync_options.change = None;
12711                        capabilities.text_document_sync =
12712                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12713                    });
12714                    notify_server_capabilities_updated(&server, cx);
12715                }
12716                "textDocument/didSave" => {
12717                    server.update_capabilities(|capabilities| {
12718                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12719                        sync_options.save = None;
12720                        capabilities.text_document_sync =
12721                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12722                    });
12723                    notify_server_capabilities_updated(&server, cx);
12724                }
12725                "textDocument/codeLens" => {
12726                    server.update_capabilities(|capabilities| {
12727                        capabilities.code_lens_provider = None;
12728                    });
12729                    notify_server_capabilities_updated(&server, cx);
12730                }
12731                "textDocument/diagnostic" => {
12732                    let local = self
12733                        .as_local_mut()
12734                        .context("Expected LSP Store to be local")?;
12735
12736                    let state = local
12737                        .language_servers
12738                        .get_mut(&server_id)
12739                        .context("Could not obtain Language Servers state")?;
12740                    let registrations = local
12741                        .language_server_dynamic_registrations
12742                        .get_mut(&server_id)
12743                        .with_context(|| {
12744                            format!("Expected dynamic registration to exist for server {server_id}")
12745                        })?;
12746                    registrations.diagnostics
12747                        .remove(&Some(unreg.id.clone()))
12748                        .with_context(|| format!(
12749                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12750                            unreg.id)
12751                        )?;
12752                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12753
12754                    if let LanguageServerState::Running {
12755                        workspace_diagnostics_refresh_tasks,
12756                        ..
12757                    } = state
12758                    {
12759                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12760                    }
12761
12762                    self.clear_unregistered_diagnostics(
12763                        server_id,
12764                        SharedString::from(unreg.id.clone()),
12765                        cx,
12766                    )?;
12767
12768                    if removed_last_diagnostic_provider {
12769                        server.update_capabilities(|capabilities| {
12770                            debug_assert!(capabilities.diagnostic_provider.is_some());
12771                            capabilities.diagnostic_provider = None;
12772                        });
12773                    }
12774
12775                    notify_server_capabilities_updated(&server, cx);
12776                }
12777                "textDocument/documentColor" => {
12778                    server.update_capabilities(|capabilities| {
12779                        capabilities.color_provider = None;
12780                    });
12781                    notify_server_capabilities_updated(&server, cx);
12782                }
12783                "textDocument/foldingRange" => {
12784                    server.update_capabilities(|capabilities| {
12785                        capabilities.folding_range_provider = None;
12786                    });
12787                    notify_server_capabilities_updated(&server, cx);
12788                }
12789                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12790            }
12791        }
12792
12793        Ok(())
12794    }
12795
12796    fn clear_unregistered_diagnostics(
12797        &mut self,
12798        server_id: LanguageServerId,
12799        cleared_registration_id: SharedString,
12800        cx: &mut Context<Self>,
12801    ) -> anyhow::Result<()> {
12802        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12803
12804        self.buffer_store.update(cx, |buffer_store, cx| {
12805            for buffer_handle in buffer_store.buffers() {
12806                let buffer = buffer_handle.read(cx);
12807                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12808                let Some(abs_path) = abs_path else {
12809                    continue;
12810                };
12811                affected_abs_paths.insert(abs_path);
12812            }
12813        });
12814
12815        let local = self.as_local().context("Expected LSP Store to be local")?;
12816        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12817            let Some(worktree) = self
12818                .worktree_store
12819                .read(cx)
12820                .worktree_for_id(*worktree_id, cx)
12821            else {
12822                continue;
12823            };
12824
12825            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
12826                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
12827                    let has_matching_registration =
12828                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
12829                            entry.diagnostic.registration_id.as_ref()
12830                                == Some(&cleared_registration_id)
12831                        });
12832                    if has_matching_registration {
12833                        let abs_path = worktree.read(cx).absolutize(rel_path);
12834                        affected_abs_paths.insert(abs_path);
12835                    }
12836                }
12837            }
12838        }
12839
12840        if affected_abs_paths.is_empty() {
12841            return Ok(());
12842        }
12843
12844        // Send a fake diagnostic update which clears the state for the registration ID
12845        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
12846            affected_abs_paths
12847                .into_iter()
12848                .map(|abs_path| DocumentDiagnosticsUpdate {
12849                    diagnostics: DocumentDiagnostics {
12850                        diagnostics: Vec::new(),
12851                        document_abs_path: abs_path,
12852                        version: None,
12853                    },
12854                    result_id: None,
12855                    registration_id: Some(cleared_registration_id.clone()),
12856                    server_id,
12857                    disk_based_sources: Cow::Borrowed(&[]),
12858                })
12859                .collect();
12860
12861        let merge_registration_id = cleared_registration_id.clone();
12862        self.merge_diagnostic_entries(
12863            clears,
12864            move |_, diagnostic, _| {
12865                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
12866                    diagnostic.registration_id != Some(merge_registration_id.clone())
12867                } else {
12868                    true
12869                }
12870            },
12871            cx,
12872        )?;
12873
12874        Ok(())
12875    }
12876
12877    async fn deduplicate_range_based_lsp_requests<T>(
12878        lsp_store: &Entity<Self>,
12879        server_id: Option<LanguageServerId>,
12880        lsp_request_id: LspRequestId,
12881        proto_request: &T::ProtoRequest,
12882        range: Range<Anchor>,
12883        cx: &mut AsyncApp,
12884    ) -> Result<()>
12885    where
12886        T: LspCommand,
12887        T::ProtoRequest: proto::LspRequestMessage,
12888    {
12889        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12890        let version = deserialize_version(proto_request.buffer_version());
12891        let buffer = lsp_store.update(cx, |this, cx| {
12892            this.buffer_store.read(cx).get_existing(buffer_id)
12893        })?;
12894        buffer
12895            .update(cx, |buffer, _| buffer.wait_for_version(version))
12896            .await?;
12897        lsp_store.update(cx, |lsp_store, cx| {
12898            let buffer_snapshot = buffer.read(cx).snapshot();
12899            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12900            let chunks_queried_for = lsp_data
12901                .inlay_hints
12902                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
12903                .collect::<Vec<_>>();
12904            match chunks_queried_for.as_slice() {
12905                &[chunk] => {
12906                    let key = LspKey {
12907                        request_type: TypeId::of::<T>(),
12908                        server_queried: server_id,
12909                    };
12910                    let previous_request = lsp_data
12911                        .chunk_lsp_requests
12912                        .entry(key)
12913                        .or_default()
12914                        .insert(chunk, lsp_request_id);
12915                    if let Some((previous_request, running_requests)) =
12916                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12917                    {
12918                        running_requests.remove(&previous_request);
12919                    }
12920                }
12921                _ambiguous_chunks => {
12922                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12923                    // there, a buffer version-based check will be performed and outdated requests discarded.
12924                }
12925            }
12926            anyhow::Ok(())
12927        })?;
12928
12929        Ok(())
12930    }
12931
12932    async fn query_lsp_locally<T>(
12933        lsp_store: Entity<Self>,
12934        for_server_id: Option<LanguageServerId>,
12935        sender_id: proto::PeerId,
12936        lsp_request_id: LspRequestId,
12937        proto_request: T::ProtoRequest,
12938        position: Option<Anchor>,
12939        cx: &mut AsyncApp,
12940    ) -> Result<()>
12941    where
12942        T: LspCommand + Clone,
12943        T::ProtoRequest: proto::LspRequestMessage,
12944        <T::ProtoRequest as proto::RequestMessage>::Response:
12945            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12946    {
12947        let (buffer_version, buffer) =
12948            Self::wait_for_buffer_version::<T>(&lsp_store, &proto_request, cx).await?;
12949        let request =
12950            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12951        let key = LspKey {
12952            request_type: TypeId::of::<T>(),
12953            server_queried: for_server_id,
12954        };
12955        lsp_store.update(cx, |lsp_store, cx| {
12956            let request_task = match for_server_id {
12957                Some(server_id) => {
12958                    let server_task = lsp_store.request_lsp(
12959                        buffer.clone(),
12960                        LanguageServerToQuery::Other(server_id),
12961                        request.clone(),
12962                        cx,
12963                    );
12964                    cx.background_spawn(async move {
12965                        let mut responses = Vec::new();
12966                        match server_task.await {
12967                            Ok(response) => responses.push((server_id, response)),
12968                            // rust-analyzer likes to error with this when its still loading up
12969                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
12970                            Err(e) => log::error!(
12971                                "Error handling response for request {request:?}: {e:#}"
12972                            ),
12973                        }
12974                        responses
12975                    })
12976                }
12977                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12978            };
12979            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12980            if T::ProtoRequest::stop_previous_requests() {
12981                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12982                    lsp_requests.clear();
12983                }
12984            }
12985            lsp_data.lsp_requests.entry(key).or_default().insert(
12986                lsp_request_id,
12987                cx.spawn(async move |lsp_store, cx| {
12988                    let response = request_task.await;
12989                    lsp_store
12990                        .update(cx, |lsp_store, cx| {
12991                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12992                            {
12993                                let response = response
12994                                    .into_iter()
12995                                    .map(|(server_id, response)| {
12996                                        (
12997                                            server_id.to_proto(),
12998                                            T::response_to_proto(
12999                                                response,
13000                                                lsp_store,
13001                                                sender_id,
13002                                                &buffer_version,
13003                                                cx,
13004                                            )
13005                                            .into(),
13006                                        )
13007                                    })
13008                                    .collect::<HashMap<_, _>>();
13009                                match client.send_lsp_response::<T::ProtoRequest>(
13010                                    project_id,
13011                                    lsp_request_id,
13012                                    response,
13013                                ) {
13014                                    Ok(()) => {}
13015                                    Err(e) => {
13016                                        log::error!("Failed to send LSP response: {e:#}",)
13017                                    }
13018                                }
13019                            }
13020                        })
13021                        .ok();
13022                }),
13023            );
13024        });
13025        Ok(())
13026    }
13027
13028    async fn wait_for_buffer_version<T>(
13029        lsp_store: &Entity<Self>,
13030        proto_request: &T::ProtoRequest,
13031        cx: &mut AsyncApp,
13032    ) -> Result<(Global, Entity<Buffer>)>
13033    where
13034        T: LspCommand,
13035        T::ProtoRequest: proto::LspRequestMessage,
13036    {
13037        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13038        let version = deserialize_version(proto_request.buffer_version());
13039        let buffer = lsp_store.update(cx, |this, cx| {
13040            this.buffer_store.read(cx).get_existing(buffer_id)
13041        })?;
13042        buffer
13043            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13044            .await?;
13045        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13046        Ok((buffer_version, buffer))
13047    }
13048
13049    fn take_text_document_sync_options(
13050        capabilities: &mut lsp::ServerCapabilities,
13051    ) -> lsp::TextDocumentSyncOptions {
13052        match capabilities.text_document_sync.take() {
13053            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13054            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13055                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13056                sync_options.change = Some(sync_kind);
13057                sync_options
13058            }
13059            None => lsp::TextDocumentSyncOptions::default(),
13060        }
13061    }
13062
13063    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13064        self.downstream_client.clone()
13065    }
13066
13067    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13068        self.worktree_store.clone()
13069    }
13070
13071    /// Gets what's stored in the LSP data for the given buffer.
13072    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13073        self.lsp_data.get_mut(&buffer_id)
13074    }
13075
13076    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13077    /// new [`BufferLspData`] will be created to replace the previous state.
13078    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13079        let (buffer_id, buffer_version) =
13080            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13081        let lsp_data = self
13082            .lsp_data
13083            .entry(buffer_id)
13084            .or_insert_with(|| BufferLspData::new(buffer, cx));
13085        if buffer_version.changed_since(&lsp_data.buffer_version) {
13086            // To send delta requests for semantic tokens, the previous tokens
13087            // need to be kept between buffer changes.
13088            let semantic_tokens = lsp_data.semantic_tokens.take();
13089            *lsp_data = BufferLspData::new(buffer, cx);
13090            lsp_data.semantic_tokens = semantic_tokens;
13091        }
13092        lsp_data
13093    }
13094}
13095
13096// Registration with registerOptions as null, should fallback to true.
13097// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13098fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13099    reg: lsp::Registration,
13100) -> Result<OneOf<bool, T>> {
13101    Ok(match reg.register_options {
13102        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13103        None => OneOf::Left(true),
13104    })
13105}
13106
13107fn subscribe_to_binary_statuses(
13108    languages: &Arc<LanguageRegistry>,
13109    cx: &mut Context<'_, LspStore>,
13110) -> Task<()> {
13111    let mut server_statuses = languages.language_server_binary_statuses();
13112    cx.spawn(async move |lsp_store, cx| {
13113        while let Some((server_name, binary_status)) = server_statuses.next().await {
13114            if lsp_store
13115                .update(cx, |_, cx| {
13116                    let mut message = None;
13117                    let binary_status = match binary_status {
13118                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13119                        BinaryStatus::CheckingForUpdate => {
13120                            proto::ServerBinaryStatus::CheckingForUpdate
13121                        }
13122                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13123                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13124                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13125                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13126                        BinaryStatus::Failed { error } => {
13127                            message = Some(error);
13128                            proto::ServerBinaryStatus::Failed
13129                        }
13130                    };
13131                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13132                        // Binary updates are about the binary that might not have any language server id at that point.
13133                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13134                        language_server_id: LanguageServerId(0),
13135                        name: Some(server_name),
13136                        message: proto::update_language_server::Variant::StatusUpdate(
13137                            proto::StatusUpdate {
13138                                message,
13139                                status: Some(proto::status_update::Status::Binary(
13140                                    binary_status as i32,
13141                                )),
13142                            },
13143                        ),
13144                    });
13145                })
13146                .is_err()
13147            {
13148                break;
13149            }
13150        }
13151    })
13152}
13153
13154fn lsp_workspace_diagnostics_refresh(
13155    registration_id: Option<String>,
13156    options: DiagnosticServerCapabilities,
13157    server: Arc<LanguageServer>,
13158    cx: &mut Context<'_, LspStore>,
13159) -> Option<WorkspaceRefreshTask> {
13160    let identifier = workspace_diagnostic_identifier(&options)?;
13161    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13162
13163    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13164    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13165    refresh_tx.try_send(()).ok();
13166
13167    let request_timeout = ProjectSettings::get_global(cx)
13168        .global_lsp_settings
13169        .get_request_timeout();
13170
13171    // 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.
13172    // This allows users to increase the duration if need be
13173    let timeout = if request_timeout != Duration::ZERO {
13174        request_timeout.max(DEFAULT_LSP_REQUEST_TIMEOUT)
13175    } else {
13176        request_timeout
13177    };
13178
13179    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13180        let mut attempts = 0;
13181        let max_attempts = 50;
13182        let mut requests = 0;
13183
13184        loop {
13185            let Some(()) = refresh_rx.recv().await else {
13186                return;
13187            };
13188
13189            'request: loop {
13190                requests += 1;
13191                if attempts > max_attempts {
13192                    log::error!(
13193                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13194                    );
13195                    return;
13196                }
13197                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13198                cx.background_executor()
13199                    .timer(Duration::from_millis(backoff_millis))
13200                    .await;
13201                attempts += 1;
13202
13203                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13204                    lsp_store
13205                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13206                        .into_iter()
13207                        .filter_map(|(abs_path, result_id)| {
13208                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13209                            Some(lsp::PreviousResultId {
13210                                uri,
13211                                value: result_id.to_string(),
13212                            })
13213                        })
13214                        .collect()
13215                }) else {
13216                    return;
13217                };
13218
13219                let token = if let Some(registration_id) = &registration_id {
13220                    format!(
13221                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13222                        server.server_id(),
13223                    )
13224                } else {
13225                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13226                };
13227
13228                progress_rx.try_recv().ok();
13229                let timer = server.request_timer(timeout).fuse();
13230                let progress = pin!(progress_rx.recv().fuse());
13231                let response_result = server
13232                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13233                        lsp::WorkspaceDiagnosticParams {
13234                            previous_result_ids,
13235                            identifier: identifier.clone(),
13236                            work_done_progress_params: Default::default(),
13237                            partial_result_params: lsp::PartialResultParams {
13238                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13239                            },
13240                        },
13241                        select(timer, progress).then(|either| match either {
13242                            Either::Left((message, ..)) => ready(message).left_future(),
13243                            Either::Right(..) => pending::<String>().right_future(),
13244                        }),
13245                    )
13246                    .await;
13247
13248                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13249                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13250                match response_result {
13251                    ConnectionResult::Timeout => {
13252                        log::error!("Timeout during workspace diagnostics pull");
13253                        continue 'request;
13254                    }
13255                    ConnectionResult::ConnectionReset => {
13256                        log::error!("Server closed a workspace diagnostics pull request");
13257                        continue 'request;
13258                    }
13259                    ConnectionResult::Result(Err(e)) => {
13260                        log::error!("Error during workspace diagnostics pull: {e:#}");
13261                        break 'request;
13262                    }
13263                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13264                        attempts = 0;
13265                        if lsp_store
13266                            .update(cx, |lsp_store, cx| {
13267                                lsp_store.apply_workspace_diagnostic_report(
13268                                    server.server_id(),
13269                                    pulled_diagnostics,
13270                                    registration_id_shared.clone(),
13271                                    cx,
13272                                )
13273                            })
13274                            .is_err()
13275                        {
13276                            return;
13277                        }
13278                        break 'request;
13279                    }
13280                }
13281            }
13282        }
13283    });
13284
13285    Some(WorkspaceRefreshTask {
13286        refresh_tx,
13287        progress_tx,
13288        task: workspace_query_language_server,
13289    })
13290}
13291
13292fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<SharedString> {
13293    match &options {
13294        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => diagnostic_options
13295            .identifier
13296            .as_deref()
13297            .map(SharedString::new),
13298        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13299            let diagnostic_options = &registration_options.diagnostic_options;
13300            diagnostic_options
13301                .identifier
13302                .as_deref()
13303                .map(SharedString::new)
13304        }
13305    }
13306}
13307
13308fn workspace_diagnostic_identifier(
13309    options: &DiagnosticServerCapabilities,
13310) -> Option<Option<String>> {
13311    match &options {
13312        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13313            if !diagnostic_options.workspace_diagnostics {
13314                return None;
13315            }
13316            Some(diagnostic_options.identifier.clone())
13317        }
13318        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13319            let diagnostic_options = &registration_options.diagnostic_options;
13320            if !diagnostic_options.workspace_diagnostics {
13321                return None;
13322            }
13323            Some(diagnostic_options.identifier.clone())
13324        }
13325    }
13326}
13327
13328fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13329    let CompletionSource::BufferWord {
13330        word_range,
13331        resolved,
13332    } = &mut completion.source
13333    else {
13334        return;
13335    };
13336    if *resolved {
13337        return;
13338    }
13339
13340    if completion.new_text
13341        != snapshot
13342            .text_for_range(word_range.clone())
13343            .collect::<String>()
13344    {
13345        return;
13346    }
13347
13348    let mut offset = 0;
13349    for chunk in snapshot.chunks(word_range.clone(), true) {
13350        let end_offset = offset + chunk.text.len();
13351        if let Some(highlight_id) = chunk.syntax_highlight_id {
13352            completion
13353                .label
13354                .runs
13355                .push((offset..end_offset, highlight_id));
13356        }
13357        offset = end_offset;
13358    }
13359    *resolved = true;
13360}
13361
13362impl EventEmitter<LspStoreEvent> for LspStore {}
13363
13364fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13365    hover
13366        .contents
13367        .retain(|hover_block| !hover_block.text.trim().is_empty());
13368    if hover.contents.is_empty() {
13369        None
13370    } else {
13371        Some(hover)
13372    }
13373}
13374
13375async fn populate_labels_for_completions(
13376    new_completions: Vec<CoreCompletion>,
13377    language: Option<Arc<Language>>,
13378    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13379) -> Vec<Completion> {
13380    let lsp_completions = new_completions
13381        .iter()
13382        .filter_map(|new_completion| {
13383            new_completion
13384                .source
13385                .lsp_completion(true)
13386                .map(|lsp_completion| lsp_completion.into_owned())
13387        })
13388        .collect::<Vec<_>>();
13389
13390    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13391        lsp_adapter
13392            .labels_for_completions(&lsp_completions, language)
13393            .await
13394            .log_err()
13395            .unwrap_or_default()
13396    } else {
13397        Vec::new()
13398    }
13399    .into_iter()
13400    .fuse();
13401
13402    let mut completions = Vec::new();
13403    for completion in new_completions {
13404        match completion.source.lsp_completion(true) {
13405            Some(lsp_completion) => {
13406                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13407
13408                let mut label = labels.next().flatten().unwrap_or_else(|| {
13409                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13410                });
13411                ensure_uniform_list_compatible_label(&mut label);
13412                completions.push(Completion {
13413                    label,
13414                    documentation,
13415                    replace_range: completion.replace_range,
13416                    new_text: completion.new_text,
13417                    insert_text_mode: lsp_completion.insert_text_mode,
13418                    source: completion.source,
13419                    icon_path: None,
13420                    confirm: None,
13421                    match_start: None,
13422                    snippet_deduplication_key: None,
13423                });
13424            }
13425            None => {
13426                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13427                ensure_uniform_list_compatible_label(&mut label);
13428                completions.push(Completion {
13429                    label,
13430                    documentation: None,
13431                    replace_range: completion.replace_range,
13432                    new_text: completion.new_text,
13433                    source: completion.source,
13434                    insert_text_mode: None,
13435                    icon_path: None,
13436                    confirm: None,
13437                    match_start: None,
13438                    snippet_deduplication_key: None,
13439                });
13440            }
13441        }
13442    }
13443    completions
13444}
13445
13446#[derive(Debug)]
13447pub enum LanguageServerToQuery {
13448    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13449    FirstCapable,
13450    /// Query a specific language server.
13451    Other(LanguageServerId),
13452}
13453
13454#[derive(Default)]
13455struct RenamePathsWatchedForServer {
13456    did_rename: Vec<RenameActionPredicate>,
13457    will_rename: Vec<RenameActionPredicate>,
13458}
13459
13460impl RenamePathsWatchedForServer {
13461    fn with_did_rename_patterns(
13462        mut self,
13463        did_rename: Option<&FileOperationRegistrationOptions>,
13464    ) -> Self {
13465        if let Some(did_rename) = did_rename {
13466            self.did_rename = did_rename
13467                .filters
13468                .iter()
13469                .filter_map(|filter| filter.try_into().log_err())
13470                .collect();
13471        }
13472        self
13473    }
13474    fn with_will_rename_patterns(
13475        mut self,
13476        will_rename: Option<&FileOperationRegistrationOptions>,
13477    ) -> Self {
13478        if let Some(will_rename) = will_rename {
13479            self.will_rename = will_rename
13480                .filters
13481                .iter()
13482                .filter_map(|filter| filter.try_into().log_err())
13483                .collect();
13484        }
13485        self
13486    }
13487
13488    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13489        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13490    }
13491    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13492        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13493    }
13494}
13495
13496impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13497    type Error = globset::Error;
13498    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13499        Ok(Self {
13500            kind: ops.pattern.matches.clone(),
13501            glob: GlobBuilder::new(&ops.pattern.glob)
13502                .case_insensitive(
13503                    ops.pattern
13504                        .options
13505                        .as_ref()
13506                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13507                )
13508                .build()?
13509                .compile_matcher(),
13510        })
13511    }
13512}
13513struct RenameActionPredicate {
13514    glob: GlobMatcher,
13515    kind: Option<FileOperationPatternKind>,
13516}
13517
13518impl RenameActionPredicate {
13519    // Returns true if language server should be notified
13520    fn eval(&self, path: &str, is_dir: bool) -> bool {
13521        self.kind.as_ref().is_none_or(|kind| {
13522            let expected_kind = if is_dir {
13523                FileOperationPatternKind::Folder
13524            } else {
13525                FileOperationPatternKind::File
13526            };
13527            kind == &expected_kind
13528        }) && self.glob.is_match(path)
13529    }
13530}
13531
13532#[derive(Default)]
13533struct LanguageServerWatchedPaths {
13534    worktree_paths: HashMap<WorktreeId, GlobSet>,
13535    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13536}
13537
13538#[derive(Default)]
13539struct LanguageServerWatchedPathsBuilder {
13540    worktree_paths: HashMap<WorktreeId, GlobSet>,
13541    abs_paths: HashMap<Arc<Path>, GlobSet>,
13542}
13543
13544impl LanguageServerWatchedPathsBuilder {
13545    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13546        self.worktree_paths.insert(worktree_id, glob_set);
13547    }
13548    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13549        self.abs_paths.insert(path, glob_set);
13550    }
13551    fn build(
13552        self,
13553        fs: Arc<dyn Fs>,
13554        language_server_id: LanguageServerId,
13555        cx: &mut Context<LspStore>,
13556    ) -> LanguageServerWatchedPaths {
13557        let lsp_store = cx.weak_entity();
13558
13559        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13560        let abs_paths = self
13561            .abs_paths
13562            .into_iter()
13563            .map(|(abs_path, globset)| {
13564                let task = cx.spawn({
13565                    let abs_path = abs_path.clone();
13566                    let fs = fs.clone();
13567
13568                    let lsp_store = lsp_store.clone();
13569                    async move |_, cx| {
13570                        maybe!(async move {
13571                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13572                            while let Some(update) = push_updates.0.next().await {
13573                                let action = lsp_store
13574                                    .update(cx, |this, _| {
13575                                        let Some(local) = this.as_local() else {
13576                                            return ControlFlow::Break(());
13577                                        };
13578                                        let Some(watcher) = local
13579                                            .language_server_watched_paths
13580                                            .get(&language_server_id)
13581                                        else {
13582                                            return ControlFlow::Break(());
13583                                        };
13584                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13585                                            "Watched abs path is not registered with a watcher",
13586                                        );
13587                                        let matching_entries = update
13588                                            .into_iter()
13589                                            .filter(|event| globs.is_match(&event.path))
13590                                            .collect::<Vec<_>>();
13591                                        this.lsp_notify_abs_paths_changed(
13592                                            language_server_id,
13593                                            matching_entries,
13594                                        );
13595                                        ControlFlow::Continue(())
13596                                    })
13597                                    .ok()?;
13598
13599                                if action.is_break() {
13600                                    break;
13601                                }
13602                            }
13603                            Some(())
13604                        })
13605                        .await;
13606                    }
13607                });
13608                (abs_path, (globset, task))
13609            })
13610            .collect();
13611        LanguageServerWatchedPaths {
13612            worktree_paths: self.worktree_paths,
13613            abs_paths,
13614        }
13615    }
13616}
13617
13618struct LspBufferSnapshot {
13619    version: i32,
13620    snapshot: TextBufferSnapshot,
13621}
13622
13623/// A prompt requested by LSP server.
13624#[derive(Clone, Debug)]
13625pub struct LanguageServerPromptRequest {
13626    pub id: usize,
13627    pub level: PromptLevel,
13628    pub message: String,
13629    pub actions: Vec<MessageActionItem>,
13630    pub lsp_name: String,
13631    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13632}
13633
13634impl LanguageServerPromptRequest {
13635    pub fn new(
13636        level: PromptLevel,
13637        message: String,
13638        actions: Vec<MessageActionItem>,
13639        lsp_name: String,
13640        response_channel: smol::channel::Sender<MessageActionItem>,
13641    ) -> Self {
13642        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13643        LanguageServerPromptRequest {
13644            id,
13645            level,
13646            message,
13647            actions,
13648            lsp_name,
13649            response_channel,
13650        }
13651    }
13652    pub async fn respond(self, index: usize) -> Option<()> {
13653        if let Some(response) = self.actions.into_iter().nth(index) {
13654            self.response_channel.send(response).await.ok()
13655        } else {
13656            None
13657        }
13658    }
13659
13660    #[cfg(any(test, feature = "test-support"))]
13661    pub fn test(
13662        level: PromptLevel,
13663        message: String,
13664        actions: Vec<MessageActionItem>,
13665        lsp_name: String,
13666    ) -> Self {
13667        let (tx, _rx) = smol::channel::unbounded();
13668        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13669    }
13670}
13671impl PartialEq for LanguageServerPromptRequest {
13672    fn eq(&self, other: &Self) -> bool {
13673        self.message == other.message && self.actions == other.actions
13674    }
13675}
13676
13677#[derive(Clone, Debug, PartialEq)]
13678pub enum LanguageServerLogType {
13679    Log(MessageType),
13680    Trace { verbose_info: Option<String> },
13681    Rpc { received: bool },
13682}
13683
13684impl LanguageServerLogType {
13685    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13686        match self {
13687            Self::Log(log_type) => {
13688                use proto::log_message::LogLevel;
13689                let level = match *log_type {
13690                    MessageType::ERROR => LogLevel::Error,
13691                    MessageType::WARNING => LogLevel::Warning,
13692                    MessageType::INFO => LogLevel::Info,
13693                    MessageType::LOG => LogLevel::Log,
13694                    other => {
13695                        log::warn!("Unknown lsp log message type: {other:?}");
13696                        LogLevel::Log
13697                    }
13698                };
13699                proto::language_server_log::LogType::Log(proto::LogMessage {
13700                    level: level as i32,
13701                })
13702            }
13703            Self::Trace { verbose_info } => {
13704                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13705                    verbose_info: verbose_info.to_owned(),
13706                })
13707            }
13708            Self::Rpc { received } => {
13709                let kind = if *received {
13710                    proto::rpc_message::Kind::Received
13711                } else {
13712                    proto::rpc_message::Kind::Sent
13713                };
13714                let kind = kind as i32;
13715                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13716            }
13717        }
13718    }
13719
13720    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13721        use proto::log_message::LogLevel;
13722        use proto::rpc_message;
13723        match log_type {
13724            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13725                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13726                    LogLevel::Error => MessageType::ERROR,
13727                    LogLevel::Warning => MessageType::WARNING,
13728                    LogLevel::Info => MessageType::INFO,
13729                    LogLevel::Log => MessageType::LOG,
13730                },
13731            ),
13732            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13733                verbose_info: trace_message.verbose_info,
13734            },
13735            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13736                received: match rpc_message::Kind::from_i32(message.kind)
13737                    .unwrap_or(rpc_message::Kind::Received)
13738                {
13739                    rpc_message::Kind::Received => true,
13740                    rpc_message::Kind::Sent => false,
13741                },
13742            },
13743        }
13744    }
13745}
13746
13747pub struct WorkspaceRefreshTask {
13748    refresh_tx: mpsc::Sender<()>,
13749    progress_tx: mpsc::Sender<()>,
13750    #[allow(dead_code)]
13751    task: Task<()>,
13752}
13753
13754pub enum LanguageServerState {
13755    Starting {
13756        startup: Task<Option<Arc<LanguageServer>>>,
13757        /// List of language servers that will be added to the workspace once it's initialization completes.
13758        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13759    },
13760
13761    Running {
13762        adapter: Arc<CachedLspAdapter>,
13763        server: Arc<LanguageServer>,
13764        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13765        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13766    },
13767}
13768
13769impl LanguageServerState {
13770    fn add_workspace_folder(&self, uri: Uri) {
13771        match self {
13772            LanguageServerState::Starting {
13773                pending_workspace_folders,
13774                ..
13775            } => {
13776                pending_workspace_folders.lock().insert(uri);
13777            }
13778            LanguageServerState::Running { server, .. } => {
13779                server.add_workspace_folder(uri);
13780            }
13781        }
13782    }
13783    fn _remove_workspace_folder(&self, uri: Uri) {
13784        match self {
13785            LanguageServerState::Starting {
13786                pending_workspace_folders,
13787                ..
13788            } => {
13789                pending_workspace_folders.lock().remove(&uri);
13790            }
13791            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13792        }
13793    }
13794}
13795
13796impl std::fmt::Debug for LanguageServerState {
13797    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13798        match self {
13799            LanguageServerState::Starting { .. } => {
13800                f.debug_struct("LanguageServerState::Starting").finish()
13801            }
13802            LanguageServerState::Running { .. } => {
13803                f.debug_struct("LanguageServerState::Running").finish()
13804            }
13805        }
13806    }
13807}
13808
13809#[derive(Clone, Debug, Serialize)]
13810pub struct LanguageServerProgress {
13811    pub is_disk_based_diagnostics_progress: bool,
13812    pub is_cancellable: bool,
13813    pub title: Option<String>,
13814    pub message: Option<String>,
13815    pub percentage: Option<usize>,
13816    #[serde(skip_serializing)]
13817    pub last_update_at: Instant,
13818}
13819
13820#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13821pub struct DiagnosticSummary {
13822    pub error_count: usize,
13823    pub warning_count: usize,
13824}
13825
13826impl DiagnosticSummary {
13827    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13828        let mut this = Self {
13829            error_count: 0,
13830            warning_count: 0,
13831        };
13832
13833        for entry in diagnostics {
13834            if entry.diagnostic.is_primary {
13835                match entry.diagnostic.severity {
13836                    DiagnosticSeverity::ERROR => this.error_count += 1,
13837                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13838                    _ => {}
13839                }
13840            }
13841        }
13842
13843        this
13844    }
13845
13846    pub fn is_empty(&self) -> bool {
13847        self.error_count == 0 && self.warning_count == 0
13848    }
13849
13850    pub fn to_proto(
13851        self,
13852        language_server_id: LanguageServerId,
13853        path: &RelPath,
13854    ) -> proto::DiagnosticSummary {
13855        proto::DiagnosticSummary {
13856            path: path.to_proto(),
13857            language_server_id: language_server_id.0 as u64,
13858            error_count: self.error_count as u32,
13859            warning_count: self.warning_count as u32,
13860        }
13861    }
13862}
13863
13864#[derive(Clone, Debug)]
13865pub enum CompletionDocumentation {
13866    /// There is no documentation for this completion.
13867    Undocumented,
13868    /// A single line of documentation.
13869    SingleLine(SharedString),
13870    /// Multiple lines of plain text documentation.
13871    MultiLinePlainText(SharedString),
13872    /// Markdown documentation.
13873    MultiLineMarkdown(SharedString),
13874    /// Both single line and multiple lines of plain text documentation.
13875    SingleLineAndMultiLinePlainText {
13876        single_line: SharedString,
13877        plain_text: Option<SharedString>,
13878    },
13879}
13880
13881impl CompletionDocumentation {
13882    #[cfg(any(test, feature = "test-support"))]
13883    pub fn text(&self) -> SharedString {
13884        match self {
13885            CompletionDocumentation::Undocumented => "".into(),
13886            CompletionDocumentation::SingleLine(s) => s.clone(),
13887            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13888            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13889            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13890                single_line.clone()
13891            }
13892        }
13893    }
13894}
13895
13896impl From<lsp::Documentation> for CompletionDocumentation {
13897    fn from(docs: lsp::Documentation) -> Self {
13898        match docs {
13899            lsp::Documentation::String(text) => {
13900                if text.lines().count() <= 1 {
13901                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
13902                } else {
13903                    CompletionDocumentation::MultiLinePlainText(text.into())
13904                }
13905            }
13906
13907            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13908                lsp::MarkupKind::PlainText => {
13909                    if value.lines().count() <= 1 {
13910                        CompletionDocumentation::SingleLine(value.into())
13911                    } else {
13912                        CompletionDocumentation::MultiLinePlainText(value.into())
13913                    }
13914                }
13915
13916                lsp::MarkupKind::Markdown => {
13917                    CompletionDocumentation::MultiLineMarkdown(value.into())
13918                }
13919            },
13920        }
13921    }
13922}
13923
13924pub enum ResolvedHint {
13925    Resolved(InlayHint),
13926    Resolving(Shared<Task<()>>),
13927}
13928
13929pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
13930    glob.components()
13931        .take_while(|component| match component {
13932            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13933            _ => true,
13934        })
13935        .collect()
13936}
13937
13938pub struct SshLspAdapter {
13939    name: LanguageServerName,
13940    binary: LanguageServerBinary,
13941    initialization_options: Option<String>,
13942    code_action_kinds: Option<Vec<CodeActionKind>>,
13943}
13944
13945impl SshLspAdapter {
13946    pub fn new(
13947        name: LanguageServerName,
13948        binary: LanguageServerBinary,
13949        initialization_options: Option<String>,
13950        code_action_kinds: Option<String>,
13951    ) -> Self {
13952        Self {
13953            name,
13954            binary,
13955            initialization_options,
13956            code_action_kinds: code_action_kinds
13957                .as_ref()
13958                .and_then(|c| serde_json::from_str(c).ok()),
13959        }
13960    }
13961}
13962
13963impl LspInstaller for SshLspAdapter {
13964    type BinaryVersion = ();
13965    async fn check_if_user_installed(
13966        &self,
13967        _: &dyn LspAdapterDelegate,
13968        _: Option<Toolchain>,
13969        _: &AsyncApp,
13970    ) -> Option<LanguageServerBinary> {
13971        Some(self.binary.clone())
13972    }
13973
13974    async fn cached_server_binary(
13975        &self,
13976        _: PathBuf,
13977        _: &dyn LspAdapterDelegate,
13978    ) -> Option<LanguageServerBinary> {
13979        None
13980    }
13981
13982    async fn fetch_latest_server_version(
13983        &self,
13984        _: &dyn LspAdapterDelegate,
13985        _: bool,
13986        _: &mut AsyncApp,
13987    ) -> Result<()> {
13988        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13989    }
13990
13991    async fn fetch_server_binary(
13992        &self,
13993        _: (),
13994        _: PathBuf,
13995        _: &dyn LspAdapterDelegate,
13996    ) -> Result<LanguageServerBinary> {
13997        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13998    }
13999}
14000
14001#[async_trait(?Send)]
14002impl LspAdapter for SshLspAdapter {
14003    fn name(&self) -> LanguageServerName {
14004        self.name.clone()
14005    }
14006
14007    async fn initialization_options(
14008        self: Arc<Self>,
14009        _: &Arc<dyn LspAdapterDelegate>,
14010        _: &mut AsyncApp,
14011    ) -> Result<Option<serde_json::Value>> {
14012        let Some(options) = &self.initialization_options else {
14013            return Ok(None);
14014        };
14015        let result = serde_json::from_str(options)?;
14016        Ok(result)
14017    }
14018
14019    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14020        self.code_action_kinds.clone()
14021    }
14022}
14023
14024pub fn language_server_settings<'a>(
14025    delegate: &'a dyn LspAdapterDelegate,
14026    language: &LanguageServerName,
14027    cx: &'a App,
14028) -> Option<&'a LspSettings> {
14029    language_server_settings_for(
14030        SettingsLocation {
14031            worktree_id: delegate.worktree_id(),
14032            path: RelPath::empty(),
14033        },
14034        language,
14035        cx,
14036    )
14037}
14038
14039pub fn language_server_settings_for<'a>(
14040    location: SettingsLocation<'a>,
14041    language: &LanguageServerName,
14042    cx: &'a App,
14043) -> Option<&'a LspSettings> {
14044    ProjectSettings::get(Some(location), cx).lsp.get(language)
14045}
14046
14047pub struct LocalLspAdapterDelegate {
14048    lsp_store: WeakEntity<LspStore>,
14049    worktree: worktree::Snapshot,
14050    fs: Arc<dyn Fs>,
14051    http_client: Arc<dyn HttpClient>,
14052    language_registry: Arc<LanguageRegistry>,
14053    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14054}
14055
14056impl LocalLspAdapterDelegate {
14057    pub fn new(
14058        language_registry: Arc<LanguageRegistry>,
14059        environment: &Entity<ProjectEnvironment>,
14060        lsp_store: WeakEntity<LspStore>,
14061        worktree: &Entity<Worktree>,
14062        http_client: Arc<dyn HttpClient>,
14063        fs: Arc<dyn Fs>,
14064        cx: &mut App,
14065    ) -> Arc<Self> {
14066        let load_shell_env_task =
14067            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14068
14069        Arc::new(Self {
14070            lsp_store,
14071            worktree: worktree.read(cx).snapshot(),
14072            fs,
14073            http_client,
14074            language_registry,
14075            load_shell_env_task,
14076        })
14077    }
14078
14079    pub fn from_local_lsp(
14080        local: &LocalLspStore,
14081        worktree: &Entity<Worktree>,
14082        cx: &mut App,
14083    ) -> Arc<Self> {
14084        Self::new(
14085            local.languages.clone(),
14086            &local.environment,
14087            local.weak.clone(),
14088            worktree,
14089            local.http_client.clone(),
14090            local.fs.clone(),
14091            cx,
14092        )
14093    }
14094}
14095
14096#[async_trait]
14097impl LspAdapterDelegate for LocalLspAdapterDelegate {
14098    fn show_notification(&self, message: &str, cx: &mut App) {
14099        self.lsp_store
14100            .update(cx, |_, cx| {
14101                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14102            })
14103            .ok();
14104    }
14105
14106    fn http_client(&self) -> Arc<dyn HttpClient> {
14107        self.http_client.clone()
14108    }
14109
14110    fn worktree_id(&self) -> WorktreeId {
14111        self.worktree.id()
14112    }
14113
14114    fn worktree_root_path(&self) -> &Path {
14115        self.worktree.abs_path().as_ref()
14116    }
14117
14118    fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
14119        self.worktree.resolve_relative_path(path)
14120    }
14121
14122    async fn shell_env(&self) -> HashMap<String, String> {
14123        let task = self.load_shell_env_task.clone();
14124        task.await.unwrap_or_default()
14125    }
14126
14127    async fn npm_package_installed_version(
14128        &self,
14129        package_name: &str,
14130    ) -> Result<Option<(PathBuf, Version)>> {
14131        let local_package_directory = self.worktree_root_path();
14132        let node_modules_directory = local_package_directory.join("node_modules");
14133
14134        if let Some(version) =
14135            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14136        {
14137            return Ok(Some((node_modules_directory, version)));
14138        }
14139        let Some(npm) = self.which("npm".as_ref()).await else {
14140            log::warn!(
14141                "Failed to find npm executable for {:?}",
14142                local_package_directory
14143            );
14144            return Ok(None);
14145        };
14146
14147        let env = self.shell_env().await;
14148        let output = util::command::new_command(&npm)
14149            .args(["root", "-g"])
14150            .envs(env)
14151            .current_dir(local_package_directory)
14152            .output()
14153            .await?;
14154        let global_node_modules =
14155            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14156
14157        if let Some(version) =
14158            read_package_installed_version(global_node_modules.clone(), package_name).await?
14159        {
14160            return Ok(Some((global_node_modules, version)));
14161        }
14162        return Ok(None);
14163    }
14164
14165    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14166        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14167        if self.fs.is_file(&worktree_abs_path).await {
14168            worktree_abs_path.pop();
14169        }
14170
14171        let env = self.shell_env().await;
14172
14173        let shell_path = env.get("PATH").cloned();
14174
14175        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14176    }
14177
14178    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14179        let mut working_dir = self.worktree_root_path().to_path_buf();
14180        if self.fs.is_file(&working_dir).await {
14181            working_dir.pop();
14182        }
14183        let output = util::command::new_command(&command.path)
14184            .args(command.arguments)
14185            .envs(command.env.clone().unwrap_or_default())
14186            .current_dir(working_dir)
14187            .output()
14188            .await?;
14189
14190        anyhow::ensure!(
14191            output.status.success(),
14192            "{}, stdout: {:?}, stderr: {:?}",
14193            output.status,
14194            String::from_utf8_lossy(&output.stdout),
14195            String::from_utf8_lossy(&output.stderr)
14196        );
14197        Ok(())
14198    }
14199
14200    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14201        self.language_registry
14202            .update_lsp_binary_status(server_name, status);
14203    }
14204
14205    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14206        self.language_registry
14207            .all_lsp_adapters()
14208            .into_iter()
14209            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14210            .collect()
14211    }
14212
14213    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14214        let dir = self.language_registry.language_server_download_dir(name)?;
14215
14216        if !dir.exists() {
14217            smol::fs::create_dir_all(&dir)
14218                .await
14219                .context("failed to create container directory")
14220                .log_err()?;
14221        }
14222
14223        Some(dir)
14224    }
14225
14226    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14227        let entry = self
14228            .worktree
14229            .entry_for_path(path)
14230            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14231        let abs_path = self.worktree.absolutize(&entry.path);
14232        self.fs.load(&abs_path).await
14233    }
14234}
14235
14236async fn populate_labels_for_symbols(
14237    symbols: Vec<CoreSymbol>,
14238    language_registry: &Arc<LanguageRegistry>,
14239    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14240    output: &mut Vec<Symbol>,
14241) {
14242    #[allow(clippy::mutable_key_type)]
14243    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14244
14245    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14246    for symbol in symbols {
14247        let Some(file_name) = symbol.path.file_name() else {
14248            continue;
14249        };
14250        let language = language_registry
14251            .load_language_for_file_path(Path::new(file_name))
14252            .await
14253            .ok()
14254            .or_else(|| {
14255                unknown_paths.insert(file_name.into());
14256                None
14257            });
14258        symbols_by_language
14259            .entry(language)
14260            .or_default()
14261            .push(symbol);
14262    }
14263
14264    for unknown_path in unknown_paths {
14265        log::info!("no language found for symbol in file {unknown_path:?}");
14266    }
14267
14268    let mut label_params = Vec::new();
14269    for (language, mut symbols) in symbols_by_language {
14270        label_params.clear();
14271        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14272            name: mem::take(&mut symbol.name),
14273            kind: symbol.kind,
14274            container_name: symbol.container_name.take(),
14275        }));
14276
14277        let mut labels = Vec::new();
14278        if let Some(language) = language {
14279            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14280                language_registry
14281                    .lsp_adapters(&language.name())
14282                    .first()
14283                    .cloned()
14284            });
14285            if let Some(lsp_adapter) = lsp_adapter {
14286                labels = lsp_adapter
14287                    .labels_for_symbols(&label_params, &language)
14288                    .await
14289                    .log_err()
14290                    .unwrap_or_default();
14291            }
14292        }
14293
14294        for (
14295            (
14296                symbol,
14297                language::Symbol {
14298                    name,
14299                    container_name,
14300                    ..
14301                },
14302            ),
14303            label,
14304        ) in symbols
14305            .into_iter()
14306            .zip(label_params.drain(..))
14307            .zip(labels.into_iter().chain(iter::repeat(None)))
14308        {
14309            output.push(Symbol {
14310                language_server_name: symbol.language_server_name,
14311                source_worktree_id: symbol.source_worktree_id,
14312                source_language_server_id: symbol.source_language_server_id,
14313                path: symbol.path,
14314                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14315                name,
14316                kind: symbol.kind,
14317                range: symbol.range,
14318                container_name,
14319            });
14320        }
14321    }
14322}
14323
14324pub(crate) fn collapse_newlines(text: &str, separator: &str) -> String {
14325    text.lines()
14326        .map(|line| line.trim())
14327        .filter(|line| !line.is_empty())
14328        .join(separator)
14329}
14330
14331fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14332    match server.capabilities().text_document_sync.as_ref()? {
14333        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14334            // Server wants didSave but didn't specify includeText.
14335            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14336            // Server doesn't want didSave at all.
14337            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14338            // Server provided SaveOptions.
14339            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14340                Some(save_options.include_text.unwrap_or(false))
14341            }
14342        },
14343        // We do not have any save info. Kind affects didChange only.
14344        lsp::TextDocumentSyncCapability::Kind(_) => None,
14345    }
14346}
14347
14348/// Completion items are displayed in a `UniformList`.
14349/// Usually, those items are single-line strings, but in LSP responses,
14350/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14351/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14352/// 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,
14353/// breaking the completions menu presentation.
14354///
14355/// 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.
14356pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14357    let mut new_text = String::with_capacity(label.text.len());
14358    let mut offset_map = vec![0; label.text.len() + 1];
14359    let mut last_char_was_space = false;
14360    let mut new_idx = 0;
14361    let chars = label.text.char_indices().fuse();
14362    let mut newlines_removed = false;
14363
14364    for (idx, c) in chars {
14365        offset_map[idx] = new_idx;
14366
14367        match c {
14368            '\n' if last_char_was_space => {
14369                newlines_removed = true;
14370            }
14371            '\t' | ' ' if last_char_was_space => {}
14372            '\n' if !last_char_was_space => {
14373                new_text.push(' ');
14374                new_idx += 1;
14375                last_char_was_space = true;
14376                newlines_removed = true;
14377            }
14378            ' ' | '\t' => {
14379                new_text.push(' ');
14380                new_idx += 1;
14381                last_char_was_space = true;
14382            }
14383            _ => {
14384                new_text.push(c);
14385                new_idx += c.len_utf8();
14386                last_char_was_space = false;
14387            }
14388        }
14389    }
14390    offset_map[label.text.len()] = new_idx;
14391
14392    // Only modify the label if newlines were removed.
14393    if !newlines_removed {
14394        return;
14395    }
14396
14397    let last_index = new_idx;
14398    let mut run_ranges_errors = Vec::new();
14399    label.runs.retain_mut(|(range, _)| {
14400        match offset_map.get(range.start) {
14401            Some(&start) => range.start = start,
14402            None => {
14403                run_ranges_errors.push(range.clone());
14404                return false;
14405            }
14406        }
14407
14408        match offset_map.get(range.end) {
14409            Some(&end) => range.end = end,
14410            None => {
14411                run_ranges_errors.push(range.clone());
14412                range.end = last_index;
14413            }
14414        }
14415        true
14416    });
14417    if !run_ranges_errors.is_empty() {
14418        log::error!(
14419            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14420            label.text
14421        );
14422    }
14423
14424    let mut wrong_filter_range = None;
14425    if label.filter_range == (0..label.text.len()) {
14426        label.filter_range = 0..new_text.len();
14427    } else {
14428        let mut original_filter_range = Some(label.filter_range.clone());
14429        match offset_map.get(label.filter_range.start) {
14430            Some(&start) => label.filter_range.start = start,
14431            None => {
14432                wrong_filter_range = original_filter_range.take();
14433                label.filter_range.start = last_index;
14434            }
14435        }
14436
14437        match offset_map.get(label.filter_range.end) {
14438            Some(&end) => label.filter_range.end = end,
14439            None => {
14440                wrong_filter_range = original_filter_range.take();
14441                label.filter_range.end = last_index;
14442            }
14443        }
14444    }
14445    if let Some(wrong_filter_range) = wrong_filter_range {
14446        log::error!(
14447            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14448            label.text
14449        );
14450    }
14451
14452    label.text = new_text;
14453}