lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13mod code_lens;
   14mod document_colors;
   15mod document_symbols;
   16mod folding_ranges;
   17mod inlay_hints;
   18pub mod json_language_server_ext;
   19pub mod log_store;
   20pub mod lsp_ext_command;
   21pub mod rust_analyzer_ext;
   22mod semantic_tokens;
   23pub mod vue_language_server_ext;
   24
   25use self::code_lens::CodeLensData;
   26use self::document_colors::DocumentColorData;
   27use self::document_symbols::DocumentSymbolsData;
   28use self::inlay_hints::BufferInlayHints;
   29use crate::{
   30    CodeAction, Completion, CompletionDisplayOptions, CompletionResponse, CompletionSource,
   31    CoreCompletion, Hover, InlayHint, InlayId, LocationLink, LspAction, LspPullDiagnostics,
   32    ManifestProvidersStore, Project, ProjectItem, ProjectPath, ProjectTransaction,
   33    PulledDiagnostics, ResolveState, Symbol,
   34    buffer_store::{BufferStore, BufferStoreEvent},
   35    environment::ProjectEnvironment,
   36    lsp_command::{self, *},
   37    lsp_store::{
   38        self,
   39        folding_ranges::FoldingRangeData,
   40        log_store::{GlobalLogStore, LanguageServerKind},
   41        semantic_tokens::{SemanticTokenConfig, SemanticTokensData},
   42    },
   43    manifest_tree::{
   44        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   45        ManifestTree,
   46    },
   47    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   48    project_settings::{BinarySettings, LspSettings, ProjectSettings},
   49    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   50    trusted_worktrees::{PathTrust, TrustedWorktrees, TrustedWorktreesEvent},
   51    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   52    yarn::YarnPathStore,
   53};
   54use anyhow::{Context as _, Result, anyhow};
   55use async_trait::async_trait;
   56use client::{TypedEnvelope, proto};
   57use clock::Global;
   58use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   59use futures::{
   60    AsyncWriteExt, Future, FutureExt, StreamExt,
   61    future::{Either, Shared, join_all, pending, select},
   62    select, select_biased,
   63    stream::FuturesUnordered,
   64};
   65use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   66use gpui::{
   67    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString,
   68    Subscription, Task, WeakEntity,
   69};
   70use http_client::HttpClient;
   71use itertools::Itertools as _;
   72use language::{
   73    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, Capability, CodeLabel,
   74    Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language,
   75    LanguageName, LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller,
   76    ManifestDelegate, ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16,
   77    Toolchain, Transaction, Unclipped,
   78    language_settings::{
   79        AllLanguageSettings, FormatOnSave, Formatter, LanguageSettings, all_language_settings,
   80        language_settings,
   81    },
   82    point_to_lsp,
   83    proto::{
   84        deserialize_anchor, deserialize_anchor_range, deserialize_version, serialize_anchor,
   85        serialize_anchor_range, serialize_version,
   86    },
   87    range_from_lsp, range_to_lsp,
   88    row_chunk::RowChunk,
   89};
   90use lsp::{
   91    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   92    DEFAULT_LSP_REQUEST_TIMEOUT, DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   93    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   94    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LanguageServer,
   95    LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId, LanguageServerName,
   96    LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType, OneOf,
   97    RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles,
   98    WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   99};
  100use node_runtime::read_package_installed_version;
  101use parking_lot::Mutex;
  102use postage::{mpsc, sink::Sink, stream::Stream, watch};
  103use rand::prelude::*;
  104use rpc::{
  105    AnyProtoClient, ErrorCode, ErrorExt as _,
  106    proto::{LspRequestId, LspRequestMessage as _},
  107};
  108use semver::Version;
  109use serde::Serialize;
  110use serde_json::Value;
  111use settings::{Settings, SettingsLocation, SettingsStore};
  112use sha2::{Digest, Sha256};
  113use snippet::Snippet;
  114use std::{
  115    any::TypeId,
  116    borrow::Cow,
  117    cell::RefCell,
  118    cmp::{Ordering, Reverse},
  119    collections::{VecDeque, hash_map},
  120    convert::TryInto,
  121    ffi::OsStr,
  122    future::ready,
  123    iter, mem,
  124    ops::{ControlFlow, Range},
  125    path::{self, Path, PathBuf},
  126    pin::pin,
  127    rc::Rc,
  128    sync::{
  129        Arc,
  130        atomic::{self, AtomicUsize},
  131    },
  132    time::{Duration, Instant},
  133    vec,
  134};
  135use sum_tree::Dimensions;
  136use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  137
  138use util::{
  139    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  140    paths::{PathStyle, SanitizedPath, UrlExt},
  141    post_inc,
  142    redact::redact_command,
  143    rel_path::RelPath,
  144};
  145
  146pub use document_colors::DocumentColors;
  147pub use folding_ranges::LspFoldingRange;
  148pub use fs::*;
  149pub use language::Location;
  150pub use lsp_store::inlay_hints::{CacheInlayHints, InvalidationStrategy};
  151#[cfg(any(test, feature = "test-support"))]
  152pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  153pub use semantic_tokens::{
  154    BufferSemanticToken, BufferSemanticTokens, RefreshForServer, SemanticTokenStylizer, TokenType,
  155};
  156
  157pub use worktree::{
  158    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  159    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  160};
  161
  162const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  163pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  164const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  165const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  166static NEXT_PROMPT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
  167
  168#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  169pub enum ProgressToken {
  170    Number(i32),
  171    String(SharedString),
  172}
  173
  174impl std::fmt::Display for ProgressToken {
  175    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  176        match self {
  177            Self::Number(number) => write!(f, "{number}"),
  178            Self::String(string) => write!(f, "{string}"),
  179        }
  180    }
  181}
  182
  183impl ProgressToken {
  184    fn from_lsp(value: lsp::NumberOrString) -> Self {
  185        match value {
  186            lsp::NumberOrString::Number(number) => Self::Number(number),
  187            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  188        }
  189    }
  190
  191    fn to_lsp(&self) -> lsp::NumberOrString {
  192        match self {
  193            Self::Number(number) => lsp::NumberOrString::Number(*number),
  194            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  195        }
  196    }
  197
  198    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  199        Some(match value.value? {
  200            proto::progress_token::Value::Number(number) => Self::Number(number),
  201            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  202        })
  203    }
  204
  205    fn to_proto(&self) -> proto::ProgressToken {
  206        proto::ProgressToken {
  207            value: Some(match self {
  208                Self::Number(number) => proto::progress_token::Value::Number(*number),
  209                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  210            }),
  211        }
  212    }
  213}
  214
  215#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  216pub enum FormatTrigger {
  217    Save,
  218    Manual,
  219}
  220
  221pub enum LspFormatTarget {
  222    Buffers,
  223    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  224}
  225
  226#[derive(Debug, Clone, PartialEq, Eq, Hash)]
  227pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  228
  229struct OpenLspBuffer(Entity<Buffer>);
  230
  231impl FormatTrigger {
  232    fn from_proto(value: i32) -> FormatTrigger {
  233        match value {
  234            0 => FormatTrigger::Save,
  235            1 => FormatTrigger::Manual,
  236            _ => FormatTrigger::Save,
  237        }
  238    }
  239}
  240
  241#[derive(Clone)]
  242struct UnifiedLanguageServer {
  243    id: LanguageServerId,
  244    project_roots: HashSet<Arc<RelPath>>,
  245}
  246
  247/// Settings that affect language server identity.
  248///
  249/// Dynamic settings (`LspSettings::settings`) are excluded because they can be
  250/// updated via `workspace/didChangeConfiguration` without restarting the server.
  251#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  252struct LanguageServerSeedSettings {
  253    binary: Option<BinarySettings>,
  254    initialization_options: Option<serde_json::Value>,
  255}
  256
  257#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  258struct LanguageServerSeed {
  259    worktree_id: WorktreeId,
  260    name: LanguageServerName,
  261    toolchain: Option<Toolchain>,
  262    settings: LanguageServerSeedSettings,
  263}
  264
  265#[derive(Debug)]
  266pub struct DocumentDiagnosticsUpdate<'a, D> {
  267    pub diagnostics: D,
  268    pub result_id: Option<SharedString>,
  269    pub registration_id: Option<SharedString>,
  270    pub server_id: LanguageServerId,
  271    pub disk_based_sources: Cow<'a, [String]>,
  272}
  273
  274pub struct DocumentDiagnostics {
  275    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  276    document_abs_path: PathBuf,
  277    version: Option<i32>,
  278}
  279
  280#[derive(Default, Debug)]
  281struct DynamicRegistrations {
  282    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  283    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  284}
  285
  286pub struct LocalLspStore {
  287    weak: WeakEntity<LspStore>,
  288    pub worktree_store: Entity<WorktreeStore>,
  289    toolchain_store: Entity<LocalToolchainStore>,
  290    http_client: Arc<dyn HttpClient>,
  291    environment: Entity<ProjectEnvironment>,
  292    fs: Arc<dyn Fs>,
  293    languages: Arc<LanguageRegistry>,
  294    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  295    yarn: Entity<YarnPathStore>,
  296    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  297    buffers_being_formatted: HashSet<BufferId>,
  298    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  299    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  300    watched_manifest_filenames: HashSet<ManifestName>,
  301    language_server_paths_watched_for_rename:
  302        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  303    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  304    supplementary_language_servers:
  305        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  306    prettier_store: Entity<PrettierStore>,
  307    next_diagnostic_group_id: usize,
  308    diagnostics: HashMap<
  309        WorktreeId,
  310        HashMap<
  311            Arc<RelPath>,
  312            Vec<(
  313                LanguageServerId,
  314                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  315            )>,
  316        >,
  317    >,
  318    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  319    _subscription: gpui::Subscription,
  320    lsp_tree: LanguageServerTree,
  321    registered_buffers: HashMap<BufferId, usize>,
  322    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  323    buffer_pull_diagnostics_result_ids: HashMap<
  324        LanguageServerId,
  325        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  326    >,
  327    workspace_pull_diagnostics_result_ids: HashMap<
  328        LanguageServerId,
  329        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  330    >,
  331    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  332
  333    buffers_to_refresh_hash_set: HashSet<BufferId>,
  334    buffers_to_refresh_queue: VecDeque<BufferId>,
  335    _background_diagnostics_worker: Shared<Task<()>>,
  336}
  337
  338impl LocalLspStore {
  339    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  340    pub fn running_language_server_for_id(
  341        &self,
  342        id: LanguageServerId,
  343    ) -> Option<&Arc<LanguageServer>> {
  344        let language_server_state = self.language_servers.get(&id)?;
  345
  346        match language_server_state {
  347            LanguageServerState::Running { server, .. } => Some(server),
  348            LanguageServerState::Starting { .. } => None,
  349        }
  350    }
  351
  352    fn get_or_insert_language_server(
  353        &mut self,
  354        worktree_handle: &Entity<Worktree>,
  355        delegate: Arc<LocalLspAdapterDelegate>,
  356        disposition: &Arc<LaunchDisposition>,
  357        language_name: &LanguageName,
  358        cx: &mut App,
  359    ) -> LanguageServerId {
  360        let key = LanguageServerSeed {
  361            worktree_id: worktree_handle.read(cx).id(),
  362            name: disposition.server_name.clone(),
  363            settings: LanguageServerSeedSettings {
  364                binary: disposition.settings.binary.clone(),
  365                initialization_options: disposition.settings.initialization_options.clone(),
  366            },
  367            toolchain: disposition.toolchain.clone(),
  368        };
  369        if let Some(state) = self.language_server_ids.get_mut(&key) {
  370            state.project_roots.insert(disposition.path.path.clone());
  371            state.id
  372        } else {
  373            let adapter = self
  374                .languages
  375                .lsp_adapters(language_name)
  376                .into_iter()
  377                .find(|adapter| adapter.name() == disposition.server_name)
  378                .expect("To find LSP adapter");
  379            let new_language_server_id = self.start_language_server(
  380                worktree_handle,
  381                delegate,
  382                adapter,
  383                disposition.settings.clone(),
  384                key.clone(),
  385                language_name.clone(),
  386                cx,
  387            );
  388            if let Some(state) = self.language_server_ids.get_mut(&key) {
  389                state.project_roots.insert(disposition.path.path.clone());
  390            } else {
  391                debug_assert!(
  392                    false,
  393                    "Expected `start_language_server` to ensure that `key` exists in a map"
  394                );
  395            }
  396            new_language_server_id
  397        }
  398    }
  399
  400    fn start_language_server(
  401        &mut self,
  402        worktree_handle: &Entity<Worktree>,
  403        delegate: Arc<LocalLspAdapterDelegate>,
  404        adapter: Arc<CachedLspAdapter>,
  405        settings: Arc<LspSettings>,
  406        key: LanguageServerSeed,
  407        language_name: LanguageName,
  408        cx: &mut App,
  409    ) -> LanguageServerId {
  410        let worktree = worktree_handle.read(cx);
  411
  412        let worktree_id = worktree.id();
  413        let worktree_abs_path = worktree.abs_path();
  414        let toolchain = key.toolchain.clone();
  415        let override_options = settings.initialization_options.clone();
  416
  417        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  418
  419        let server_id = self.languages.next_language_server_id();
  420        log::trace!(
  421            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  422            adapter.name.0
  423        );
  424
  425        let wait_until_worktree_trust =
  426            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  427                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  428                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  429                });
  430                if can_trust {
  431                    self.restricted_worktrees_tasks.remove(&worktree_id);
  432                    None
  433                } else {
  434                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  435                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  436                        hash_map::Entry::Vacant(v) => {
  437                            let (mut tx, rx) = watch::channel::<bool>();
  438                            let lsp_store = self.weak.clone();
  439                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  440                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  441                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  442                                        tx.blocking_send(true).ok();
  443                                        lsp_store
  444                                            .update(cx, |lsp_store, _| {
  445                                                if let Some(local_lsp_store) =
  446                                                    lsp_store.as_local_mut()
  447                                                {
  448                                                    local_lsp_store
  449                                                        .restricted_worktrees_tasks
  450                                                        .remove(&worktree_id);
  451                                                }
  452                                            })
  453                                            .ok();
  454                                    }
  455                                }
  456                            });
  457                            v.insert((subscription, rx.clone()));
  458                            Some(rx)
  459                        }
  460                    }
  461                }
  462            });
  463        let update_binary_status = wait_until_worktree_trust.is_none();
  464
  465        let binary = self.get_language_server_binary(
  466            worktree_abs_path.clone(),
  467            adapter.clone(),
  468            settings,
  469            toolchain.clone(),
  470            delegate.clone(),
  471            true,
  472            wait_until_worktree_trust,
  473            cx,
  474        );
  475        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  476
  477        let pending_server = cx.spawn({
  478            let adapter = adapter.clone();
  479            let server_name = adapter.name.clone();
  480            let stderr_capture = stderr_capture.clone();
  481            #[cfg(any(test, feature = "test-support"))]
  482            let lsp_store = self.weak.clone();
  483            let pending_workspace_folders = pending_workspace_folders.clone();
  484            async move |cx| {
  485                let binary = binary.await?;
  486                #[cfg(any(test, feature = "test-support"))]
  487                if let Some(server) = lsp_store
  488                    .update(&mut cx.clone(), |this, cx| {
  489                        this.languages.create_fake_language_server(
  490                            server_id,
  491                            &server_name,
  492                            binary.clone(),
  493                            &mut cx.to_async(),
  494                        )
  495                    })
  496                    .ok()
  497                    .flatten()
  498                {
  499                    return Ok(server);
  500                }
  501
  502                let code_action_kinds = adapter.code_action_kinds();
  503                lsp::LanguageServer::new(
  504                    stderr_capture,
  505                    server_id,
  506                    server_name,
  507                    binary,
  508                    &worktree_abs_path,
  509                    code_action_kinds,
  510                    Some(pending_workspace_folders),
  511                    cx,
  512                )
  513            }
  514        });
  515
  516        let startup = {
  517            let server_name = adapter.name.0.clone();
  518            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  519            let key = key.clone();
  520            let adapter = adapter.clone();
  521            let lsp_store = self.weak.clone();
  522            let pending_workspace_folders = pending_workspace_folders.clone();
  523            let pull_diagnostics = ProjectSettings::get_global(cx)
  524                .diagnostics
  525                .lsp_pull_diagnostics
  526                .enabled;
  527            let settings_location = SettingsLocation {
  528                worktree_id,
  529                path: RelPath::empty(),
  530            };
  531            let augments_syntax_tokens = AllLanguageSettings::get(Some(settings_location), cx)
  532                .language(Some(settings_location), Some(&language_name), cx)
  533                .semantic_tokens
  534                .use_tree_sitter();
  535            cx.spawn(async move |cx| {
  536                let result = async {
  537                    let language_server = pending_server.await?;
  538
  539                    let workspace_config = Self::workspace_configuration_for_adapter(
  540                        adapter.adapter.clone(),
  541                        &delegate,
  542                        toolchain,
  543                        None,
  544                        cx,
  545                    )
  546                    .await?;
  547
  548                    let mut initialization_options = Self::initialization_options_for_adapter(
  549                        adapter.adapter.clone(),
  550                        &delegate,
  551                        cx,
  552                    )
  553                    .await?;
  554
  555                    match (&mut initialization_options, override_options) {
  556                        (Some(initialization_options), Some(override_options)) => {
  557                            merge_json_value_into(override_options, initialization_options);
  558                        }
  559                        (None, override_options) => initialization_options = override_options,
  560                        _ => {}
  561                    }
  562
  563                    let initialization_params = cx.update(|cx| {
  564                        let mut params = language_server.default_initialize_params(
  565                            pull_diagnostics,
  566                            augments_syntax_tokens,
  567                            cx,
  568                        );
  569                        params.initialization_options = initialization_options;
  570                        adapter.adapter.prepare_initialize_params(params, cx)
  571                    })?;
  572
  573                    Self::setup_lsp_messages(
  574                        lsp_store.clone(),
  575                        &language_server,
  576                        delegate.clone(),
  577                        adapter.clone(),
  578                    );
  579
  580                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  581                        settings: workspace_config,
  582                    };
  583                    let language_server = cx
  584                        .update(|cx| {
  585                            let request_timeout = ProjectSettings::get_global(cx)
  586                                .global_lsp_settings
  587                                .get_request_timeout();
  588
  589                            language_server.initialize(
  590                                initialization_params,
  591                                Arc::new(did_change_configuration_params.clone()),
  592                                request_timeout,
  593                                cx,
  594                            )
  595                        })
  596                        .await
  597                        .inspect_err(|_| {
  598                            if let Some(lsp_store) = lsp_store.upgrade() {
  599                                lsp_store.update(cx, |lsp_store, cx| {
  600                                    lsp_store.cleanup_lsp_data(server_id);
  601                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  602                                });
  603                            }
  604                        })?;
  605
  606                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  607                        did_change_configuration_params,
  608                    )?;
  609
  610                    anyhow::Ok(language_server)
  611                }
  612                .await;
  613
  614                match result {
  615                    Ok(server) => {
  616                        lsp_store
  617                            .update(cx, |lsp_store, cx| {
  618                                lsp_store.insert_newly_running_language_server(
  619                                    adapter,
  620                                    server.clone(),
  621                                    server_id,
  622                                    key,
  623                                    pending_workspace_folders,
  624                                    cx,
  625                                );
  626                            })
  627                            .ok();
  628                        stderr_capture.lock().take();
  629                        Some(server)
  630                    }
  631
  632                    Err(err) => {
  633                        let log = stderr_capture.lock().take().unwrap_or_default();
  634                        delegate.update_status(
  635                            adapter.name(),
  636                            BinaryStatus::Failed {
  637                                error: if log.is_empty() {
  638                                    format!("{err:#}")
  639                                } else {
  640                                    format!("{err:#}\n-- stderr --\n{log}")
  641                                },
  642                            },
  643                        );
  644                        log::error!(
  645                            "Failed to start language server {server_name:?}: {}",
  646                            redact_command(&format!("{err:?}"))
  647                        );
  648                        if !log.is_empty() {
  649                            log::error!("server stderr: {}", redact_command(&log));
  650                        }
  651                        None
  652                    }
  653                }
  654            })
  655        };
  656        let state = LanguageServerState::Starting {
  657            startup,
  658            pending_workspace_folders,
  659        };
  660
  661        if update_binary_status {
  662            self.languages
  663                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  664        }
  665
  666        self.language_servers.insert(server_id, state);
  667        self.language_server_ids
  668            .entry(key)
  669            .or_insert(UnifiedLanguageServer {
  670                id: server_id,
  671                project_roots: Default::default(),
  672            });
  673        server_id
  674    }
  675
  676    fn get_language_server_binary(
  677        &self,
  678        worktree_abs_path: Arc<Path>,
  679        adapter: Arc<CachedLspAdapter>,
  680        settings: Arc<LspSettings>,
  681        toolchain: Option<Toolchain>,
  682        delegate: Arc<dyn LspAdapterDelegate>,
  683        allow_binary_download: bool,
  684        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  685        cx: &mut App,
  686    ) -> Task<Result<LanguageServerBinary>> {
  687        if let Some(settings) = &settings.binary
  688            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  689        {
  690            let settings = settings.clone();
  691            let languages = self.languages.clone();
  692            return cx.background_spawn(async move {
  693                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  694                    let already_trusted =  *wait_until_worktree_trust.borrow();
  695                    if !already_trusted {
  696                        log::info!(
  697                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  698                            adapter.name(),
  699                        );
  700                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  701                            if worktree_trusted {
  702                                break;
  703                            }
  704                        }
  705                        log::info!(
  706                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  707                            adapter.name(),
  708                        );
  709                    }
  710                    languages
  711                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  712                }
  713                let mut env = delegate.shell_env().await;
  714                env.extend(settings.env.unwrap_or_default());
  715
  716                Ok(LanguageServerBinary {
  717                    path: delegate.resolve_relative_path(path),
  718                    env: Some(env),
  719                    arguments: settings
  720                        .arguments
  721                        .unwrap_or_default()
  722                        .iter()
  723                        .map(Into::into)
  724                        .collect(),
  725                })
  726            });
  727        }
  728        let lsp_binary_options = LanguageServerBinaryOptions {
  729            allow_path_lookup: !settings
  730                .binary
  731                .as_ref()
  732                .and_then(|b| b.ignore_system_version)
  733                .unwrap_or_default(),
  734            allow_binary_download,
  735            pre_release: settings
  736                .fetch
  737                .as_ref()
  738                .and_then(|f| f.pre_release)
  739                .unwrap_or(false),
  740        };
  741
  742        cx.spawn(async move |cx| {
  743            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  744                let already_trusted =  *wait_until_worktree_trust.borrow();
  745                if !already_trusted {
  746                    log::info!(
  747                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  748                        adapter.name(),
  749                    );
  750                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  751                        if worktree_trusted {
  752                            break;
  753                        }
  754                    }
  755                    log::info!(
  756                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  757                            adapter.name(),
  758                    );
  759                }
  760            }
  761
  762            let (existing_binary, maybe_download_binary) = adapter
  763                .clone()
  764                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  765                .await
  766                .await;
  767
  768            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  769
  770            let mut binary = match (existing_binary, maybe_download_binary) {
  771                (binary, None) => binary?,
  772                (Err(_), Some(downloader)) => downloader.await?,
  773                (Ok(existing_binary), Some(downloader)) => {
  774                    let mut download_timeout = cx
  775                        .background_executor()
  776                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  777                        .fuse();
  778                    let mut downloader = downloader.fuse();
  779                    futures::select! {
  780                        _ = download_timeout => {
  781                            // Return existing binary and kick the existing work to the background.
  782                            cx.spawn(async move |_| downloader.await).detach();
  783                            Ok(existing_binary)
  784                        },
  785                        downloaded_or_existing_binary = downloader => {
  786                            // If download fails, this results in the existing binary.
  787                            downloaded_or_existing_binary
  788                        }
  789                    }?
  790                }
  791            };
  792            let mut shell_env = delegate.shell_env().await;
  793
  794            shell_env.extend(binary.env.unwrap_or_default());
  795
  796            if let Some(settings) = settings.binary.as_ref() {
  797                if let Some(arguments) = &settings.arguments {
  798                    binary.arguments = arguments.iter().map(Into::into).collect();
  799                }
  800                if let Some(env) = &settings.env {
  801                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  802                }
  803            }
  804
  805            binary.env = Some(shell_env);
  806            Ok(binary)
  807        })
  808    }
  809
  810    fn setup_lsp_messages(
  811        lsp_store: WeakEntity<LspStore>,
  812        language_server: &LanguageServer,
  813        delegate: Arc<dyn LspAdapterDelegate>,
  814        adapter: Arc<CachedLspAdapter>,
  815    ) {
  816        let name = language_server.name();
  817        let server_id = language_server.server_id();
  818        language_server
  819            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  820                let adapter = adapter.clone();
  821                let this = lsp_store.clone();
  822                move |mut params, cx| {
  823                    let adapter = adapter.clone();
  824                    if let Some(this) = this.upgrade() {
  825                        this.update(cx, |this, cx| {
  826                            {
  827                                let buffer = params
  828                                    .uri
  829                                    .to_file_path()
  830                                    .map(|file_path| this.get_buffer(&file_path, cx))
  831                                    .ok()
  832                                    .flatten();
  833                                adapter.process_diagnostics(&mut params, server_id, buffer);
  834                            }
  835
  836                            this.merge_lsp_diagnostics(
  837                                DiagnosticSourceKind::Pushed,
  838                                vec![DocumentDiagnosticsUpdate {
  839                                    server_id,
  840                                    diagnostics: params,
  841                                    result_id: None,
  842                                    disk_based_sources: Cow::Borrowed(
  843                                        &adapter.disk_based_diagnostic_sources,
  844                                    ),
  845                                    registration_id: None,
  846                                }],
  847                                |_, diagnostic, cx| match diagnostic.source_kind {
  848                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  849                                        adapter.retain_old_diagnostic(diagnostic, cx)
  850                                    }
  851                                    DiagnosticSourceKind::Pulled => true,
  852                                },
  853                                cx,
  854                            )
  855                            .log_err();
  856                        });
  857                    }
  858                }
  859            })
  860            .detach();
  861        language_server
  862            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  863                let adapter = adapter.adapter.clone();
  864                let delegate = delegate.clone();
  865                let this = lsp_store.clone();
  866                move |params, cx| {
  867                    let adapter = adapter.clone();
  868                    let delegate = delegate.clone();
  869                    let this = this.clone();
  870                    let mut cx = cx.clone();
  871                    async move {
  872                        let toolchain_for_id = this
  873                            .update(&mut cx, |this, _| {
  874                                this.as_local()?.language_server_ids.iter().find_map(
  875                                    |(seed, value)| {
  876                                        (value.id == server_id).then(|| seed.toolchain.clone())
  877                                    },
  878                                )
  879                            })?
  880                            .context("Expected the LSP store to be in a local mode")?;
  881
  882                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  883                        for item in &params.items {
  884                            let scope_uri = item.scope_uri.clone();
  885                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  886                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  887                            else {
  888                                // We've already queried workspace configuration of this URI.
  889                                continue;
  890                            };
  891                            let workspace_config = Self::workspace_configuration_for_adapter(
  892                                adapter.clone(),
  893                                &delegate,
  894                                toolchain_for_id.clone(),
  895                                scope_uri,
  896                                &mut cx,
  897                            )
  898                            .await?;
  899                            new_scope_uri.insert(workspace_config);
  900                        }
  901
  902                        Ok(params
  903                            .items
  904                            .into_iter()
  905                            .filter_map(|item| {
  906                                let workspace_config =
  907                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  908                                if let Some(section) = &item.section {
  909                                    Some(
  910                                        workspace_config
  911                                            .get(section)
  912                                            .cloned()
  913                                            .unwrap_or(serde_json::Value::Null),
  914                                    )
  915                                } else {
  916                                    Some(workspace_config.clone())
  917                                }
  918                            })
  919                            .collect())
  920                    }
  921                }
  922            })
  923            .detach();
  924
  925        language_server
  926            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  927                let this = lsp_store.clone();
  928                move |_, cx| {
  929                    let this = this.clone();
  930                    let cx = cx.clone();
  931                    async move {
  932                        let Some(server) =
  933                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  934                        else {
  935                            return Ok(None);
  936                        };
  937                        let root = server.workspace_folders();
  938                        Ok(Some(
  939                            root.into_iter()
  940                                .map(|uri| WorkspaceFolder {
  941                                    uri,
  942                                    name: Default::default(),
  943                                })
  944                                .collect(),
  945                        ))
  946                    }
  947                }
  948            })
  949            .detach();
  950        // Even though we don't have handling for these requests, respond to them to
  951        // avoid stalling any language server like `gopls` which waits for a response
  952        // to these requests when initializing.
  953        language_server
  954            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  955                let this = lsp_store.clone();
  956                move |params, cx| {
  957                    let this = this.clone();
  958                    let mut cx = cx.clone();
  959                    async move {
  960                        this.update(&mut cx, |this, _| {
  961                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  962                            {
  963                                status
  964                                    .progress_tokens
  965                                    .insert(ProgressToken::from_lsp(params.token));
  966                            }
  967                        })?;
  968
  969                        Ok(())
  970                    }
  971                }
  972            })
  973            .detach();
  974
  975        language_server
  976            .on_request::<lsp::request::RegisterCapability, _, _>({
  977                let lsp_store = lsp_store.clone();
  978                move |params, cx| {
  979                    let lsp_store = lsp_store.clone();
  980                    let mut cx = cx.clone();
  981                    async move {
  982                        lsp_store
  983                            .update(&mut cx, |lsp_store, cx| {
  984                                if lsp_store.as_local().is_some() {
  985                                    match lsp_store
  986                                        .register_server_capabilities(server_id, params, cx)
  987                                    {
  988                                        Ok(()) => {}
  989                                        Err(e) => {
  990                                            log::error!(
  991                                                "Failed to register server capabilities: {e:#}"
  992                                            );
  993                                        }
  994                                    };
  995                                }
  996                            })
  997                            .ok();
  998                        Ok(())
  999                    }
 1000                }
 1001            })
 1002            .detach();
 1003
 1004        language_server
 1005            .on_request::<lsp::request::UnregisterCapability, _, _>({
 1006                let lsp_store = lsp_store.clone();
 1007                move |params, cx| {
 1008                    let lsp_store = lsp_store.clone();
 1009                    let mut cx = cx.clone();
 1010                    async move {
 1011                        lsp_store
 1012                            .update(&mut cx, |lsp_store, cx| {
 1013                                if lsp_store.as_local().is_some() {
 1014                                    match lsp_store
 1015                                        .unregister_server_capabilities(server_id, params, cx)
 1016                                    {
 1017                                        Ok(()) => {}
 1018                                        Err(e) => {
 1019                                            log::error!(
 1020                                                "Failed to unregister server capabilities: {e:#}"
 1021                                            );
 1022                                        }
 1023                                    }
 1024                                }
 1025                            })
 1026                            .ok();
 1027                        Ok(())
 1028                    }
 1029                }
 1030            })
 1031            .detach();
 1032
 1033        language_server
 1034            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
 1035                let this = lsp_store.clone();
 1036                move |params, cx| {
 1037                    let mut cx = cx.clone();
 1038                    let this = this.clone();
 1039                    async move {
 1040                        LocalLspStore::on_lsp_workspace_edit(
 1041                            this.clone(),
 1042                            params,
 1043                            server_id,
 1044                            &mut cx,
 1045                        )
 1046                        .await
 1047                    }
 1048                }
 1049            })
 1050            .detach();
 1051
 1052        language_server
 1053            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1054                let lsp_store = lsp_store.clone();
 1055                let request_id = Arc::new(AtomicUsize::new(0));
 1056                move |(), cx| {
 1057                    let lsp_store = lsp_store.clone();
 1058                    let request_id = request_id.clone();
 1059                    let mut cx = cx.clone();
 1060                    async move {
 1061                        lsp_store
 1062                            .update(&mut cx, |lsp_store, cx| {
 1063                                let request_id =
 1064                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1065                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1066                                    server_id,
 1067                                    request_id,
 1068                                });
 1069                                lsp_store
 1070                                    .downstream_client
 1071                                    .as_ref()
 1072                                    .map(|(client, project_id)| {
 1073                                        client.send(proto::RefreshInlayHints {
 1074                                            project_id: *project_id,
 1075                                            server_id: server_id.to_proto(),
 1076                                            request_id: request_id.map(|id| id as u64),
 1077                                        })
 1078                                    })
 1079                            })?
 1080                            .transpose()?;
 1081                        Ok(())
 1082                    }
 1083                }
 1084            })
 1085            .detach();
 1086
 1087        language_server
 1088            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1089                let this = lsp_store.clone();
 1090                move |(), cx| {
 1091                    let this = this.clone();
 1092                    let mut cx = cx.clone();
 1093                    async move {
 1094                        this.update(&mut cx, |this, cx| {
 1095                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1096                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1097                                client.send(proto::RefreshCodeLens {
 1098                                    project_id: *project_id,
 1099                                })
 1100                            })
 1101                        })?
 1102                        .transpose()?;
 1103                        Ok(())
 1104                    }
 1105                }
 1106            })
 1107            .detach();
 1108
 1109        language_server
 1110            .on_request::<lsp::request::SemanticTokensRefresh, _, _>({
 1111                let lsp_store = lsp_store.clone();
 1112                let request_id = Arc::new(AtomicUsize::new(0));
 1113                move |(), cx| {
 1114                    let lsp_store = lsp_store.clone();
 1115                    let request_id = request_id.clone();
 1116                    let mut cx = cx.clone();
 1117                    async move {
 1118                        lsp_store
 1119                            .update(&mut cx, |lsp_store, cx| {
 1120                                let request_id =
 1121                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1122                                cx.emit(LspStoreEvent::RefreshSemanticTokens {
 1123                                    server_id,
 1124                                    request_id,
 1125                                });
 1126                                lsp_store
 1127                                    .downstream_client
 1128                                    .as_ref()
 1129                                    .map(|(client, project_id)| {
 1130                                        client.send(proto::RefreshSemanticTokens {
 1131                                            project_id: *project_id,
 1132                                            server_id: server_id.to_proto(),
 1133                                            request_id: request_id.map(|id| id as u64),
 1134                                        })
 1135                                    })
 1136                            })?
 1137                            .transpose()?;
 1138                        Ok(())
 1139                    }
 1140                }
 1141            })
 1142            .detach();
 1143
 1144        language_server
 1145            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1146                let this = lsp_store.clone();
 1147                move |(), cx| {
 1148                    let this = this.clone();
 1149                    let mut cx = cx.clone();
 1150                    async move {
 1151                        this.update(&mut cx, |lsp_store, cx| {
 1152                            lsp_store.pull_workspace_diagnostics(server_id);
 1153                            lsp_store
 1154                                .downstream_client
 1155                                .as_ref()
 1156                                .map(|(client, project_id)| {
 1157                                    client.send(proto::PullWorkspaceDiagnostics {
 1158                                        project_id: *project_id,
 1159                                        server_id: server_id.to_proto(),
 1160                                    })
 1161                                })
 1162                                .transpose()?;
 1163                            anyhow::Ok(
 1164                                lsp_store.pull_document_diagnostics_for_server(server_id, None, cx),
 1165                            )
 1166                        })??
 1167                        .await;
 1168                        Ok(())
 1169                    }
 1170                }
 1171            })
 1172            .detach();
 1173
 1174        language_server
 1175            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1176                let this = lsp_store.clone();
 1177                let name = name.to_string();
 1178                let adapter = adapter.clone();
 1179                move |params, cx| {
 1180                    let this = this.clone();
 1181                    let name = name.to_string();
 1182                    let adapter = adapter.clone();
 1183                    let mut cx = cx.clone();
 1184                    async move {
 1185                        let actions = params.actions.unwrap_or_default();
 1186                        let message = params.message.clone();
 1187                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1188                        let level = match params.typ {
 1189                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1190                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1191                            _ => PromptLevel::Info,
 1192                        };
 1193                        let request = LanguageServerPromptRequest::new(
 1194                            level,
 1195                            params.message,
 1196                            actions,
 1197                            name.clone(),
 1198                            tx,
 1199                        );
 1200
 1201                        let did_update = this
 1202                            .update(&mut cx, |_, cx| {
 1203                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1204                            })
 1205                            .is_ok();
 1206                        if did_update {
 1207                            let response = rx.recv().await.ok();
 1208                            if let Some(ref selected_action) = response {
 1209                                let context = language::PromptResponseContext {
 1210                                    message,
 1211                                    selected_action: selected_action.clone(),
 1212                                };
 1213                                adapter.process_prompt_response(&context, &mut cx)
 1214                            }
 1215
 1216                            Ok(response)
 1217                        } else {
 1218                            Ok(None)
 1219                        }
 1220                    }
 1221                }
 1222            })
 1223            .detach();
 1224        language_server
 1225            .on_notification::<lsp::notification::ShowMessage, _>({
 1226                let this = lsp_store.clone();
 1227                let name = name.to_string();
 1228                move |params, cx| {
 1229                    let this = this.clone();
 1230                    let name = name.to_string();
 1231                    let mut cx = cx.clone();
 1232
 1233                    let (tx, _) = smol::channel::bounded(1);
 1234                    let level = match params.typ {
 1235                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1236                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1237                        _ => PromptLevel::Info,
 1238                    };
 1239                    let request =
 1240                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1241
 1242                    let _ = this.update(&mut cx, |_, cx| {
 1243                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1244                    });
 1245                }
 1246            })
 1247            .detach();
 1248
 1249        let disk_based_diagnostics_progress_token =
 1250            adapter.disk_based_diagnostics_progress_token.clone();
 1251
 1252        language_server
 1253            .on_notification::<lsp::notification::Progress, _>({
 1254                let this = lsp_store.clone();
 1255                move |params, cx| {
 1256                    if let Some(this) = this.upgrade() {
 1257                        this.update(cx, |this, cx| {
 1258                            this.on_lsp_progress(
 1259                                params,
 1260                                server_id,
 1261                                disk_based_diagnostics_progress_token.clone(),
 1262                                cx,
 1263                            );
 1264                        });
 1265                    }
 1266                }
 1267            })
 1268            .detach();
 1269
 1270        language_server
 1271            .on_notification::<lsp::notification::LogMessage, _>({
 1272                let this = lsp_store.clone();
 1273                move |params, cx| {
 1274                    if let Some(this) = this.upgrade() {
 1275                        this.update(cx, |_, cx| {
 1276                            cx.emit(LspStoreEvent::LanguageServerLog(
 1277                                server_id,
 1278                                LanguageServerLogType::Log(params.typ),
 1279                                params.message,
 1280                            ));
 1281                        });
 1282                    }
 1283                }
 1284            })
 1285            .detach();
 1286
 1287        language_server
 1288            .on_notification::<lsp::notification::LogTrace, _>({
 1289                let this = lsp_store.clone();
 1290                move |params, cx| {
 1291                    let mut cx = cx.clone();
 1292                    if let Some(this) = this.upgrade() {
 1293                        this.update(&mut cx, |_, cx| {
 1294                            cx.emit(LspStoreEvent::LanguageServerLog(
 1295                                server_id,
 1296                                LanguageServerLogType::Trace {
 1297                                    verbose_info: params.verbose,
 1298                                },
 1299                                params.message,
 1300                            ));
 1301                        });
 1302                    }
 1303                }
 1304            })
 1305            .detach();
 1306
 1307        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1308        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1309        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1310        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1311    }
 1312
 1313    fn shutdown_language_servers_on_quit(&mut self) -> impl Future<Output = ()> + use<> {
 1314        let shutdown_futures = self
 1315            .language_servers
 1316            .drain()
 1317            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1318            .collect::<Vec<_>>();
 1319
 1320        async move {
 1321            join_all(shutdown_futures).await;
 1322        }
 1323    }
 1324
 1325    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1326        match server_state {
 1327            LanguageServerState::Running { server, .. } => {
 1328                if let Some(shutdown) = server.shutdown() {
 1329                    shutdown.await;
 1330                }
 1331            }
 1332            LanguageServerState::Starting { startup, .. } => {
 1333                if let Some(server) = startup.await
 1334                    && let Some(shutdown) = server.shutdown()
 1335                {
 1336                    shutdown.await;
 1337                }
 1338            }
 1339        }
 1340        Ok(())
 1341    }
 1342
 1343    fn language_servers_for_worktree(
 1344        &self,
 1345        worktree_id: WorktreeId,
 1346    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1347        self.language_server_ids
 1348            .iter()
 1349            .filter_map(move |(seed, state)| {
 1350                if seed.worktree_id != worktree_id {
 1351                    return None;
 1352                }
 1353
 1354                if let Some(LanguageServerState::Running { server, .. }) =
 1355                    self.language_servers.get(&state.id)
 1356                {
 1357                    Some(server)
 1358                } else {
 1359                    None
 1360                }
 1361            })
 1362    }
 1363
 1364    fn language_server_ids_for_project_path(
 1365        &self,
 1366        project_path: ProjectPath,
 1367        language: &Language,
 1368        cx: &mut App,
 1369    ) -> Vec<LanguageServerId> {
 1370        let Some(worktree) = self
 1371            .worktree_store
 1372            .read(cx)
 1373            .worktree_for_id(project_path.worktree_id, cx)
 1374        else {
 1375            return Vec::new();
 1376        };
 1377        let delegate: Arc<dyn ManifestDelegate> =
 1378            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1379
 1380        self.lsp_tree
 1381            .get(
 1382                project_path,
 1383                language.name(),
 1384                language.manifest(),
 1385                &delegate,
 1386                cx,
 1387            )
 1388            .collect::<Vec<_>>()
 1389    }
 1390
 1391    fn language_server_ids_for_buffer(
 1392        &self,
 1393        buffer: &Buffer,
 1394        cx: &mut App,
 1395    ) -> Vec<LanguageServerId> {
 1396        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1397            let worktree_id = file.worktree_id(cx);
 1398
 1399            let path: Arc<RelPath> = file
 1400                .path()
 1401                .parent()
 1402                .map(Arc::from)
 1403                .unwrap_or_else(|| file.path().clone());
 1404            let worktree_path = ProjectPath { worktree_id, path };
 1405            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1406        } else {
 1407            Vec::new()
 1408        }
 1409    }
 1410
 1411    fn language_servers_for_buffer<'a>(
 1412        &'a self,
 1413        buffer: &'a Buffer,
 1414        cx: &'a mut App,
 1415    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1416        self.language_server_ids_for_buffer(buffer, cx)
 1417            .into_iter()
 1418            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1419                LanguageServerState::Running {
 1420                    adapter, server, ..
 1421                } => Some((adapter, server)),
 1422                _ => None,
 1423            })
 1424    }
 1425
 1426    async fn execute_code_action_kind_locally(
 1427        lsp_store: WeakEntity<LspStore>,
 1428        mut buffers: Vec<Entity<Buffer>>,
 1429        kind: CodeActionKind,
 1430        push_to_history: bool,
 1431        cx: &mut AsyncApp,
 1432    ) -> anyhow::Result<ProjectTransaction> {
 1433        // Do not allow multiple concurrent code actions requests for the
 1434        // same buffer.
 1435        lsp_store.update(cx, |this, cx| {
 1436            let this = this.as_local_mut().unwrap();
 1437            buffers.retain(|buffer| {
 1438                this.buffers_being_formatted
 1439                    .insert(buffer.read(cx).remote_id())
 1440            });
 1441        })?;
 1442        let _cleanup = defer({
 1443            let this = lsp_store.clone();
 1444            let mut cx = cx.clone();
 1445            let buffers = &buffers;
 1446            move || {
 1447                this.update(&mut cx, |this, cx| {
 1448                    let this = this.as_local_mut().unwrap();
 1449                    for buffer in buffers {
 1450                        this.buffers_being_formatted
 1451                            .remove(&buffer.read(cx).remote_id());
 1452                    }
 1453                })
 1454                .ok();
 1455            }
 1456        });
 1457        let mut project_transaction = ProjectTransaction::default();
 1458
 1459        for buffer in &buffers {
 1460            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1461                buffer.update(cx, |buffer, cx| {
 1462                    lsp_store
 1463                        .as_local()
 1464                        .unwrap()
 1465                        .language_servers_for_buffer(buffer, cx)
 1466                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1467                        .collect::<Vec<_>>()
 1468                })
 1469            })?;
 1470            for (_, language_server) in adapters_and_servers.iter() {
 1471                let actions = Self::get_server_code_actions_from_action_kinds(
 1472                    &lsp_store,
 1473                    language_server.server_id(),
 1474                    vec![kind.clone()],
 1475                    buffer,
 1476                    cx,
 1477                )
 1478                .await?;
 1479                Self::execute_code_actions_on_server(
 1480                    &lsp_store,
 1481                    language_server,
 1482                    actions,
 1483                    push_to_history,
 1484                    &mut project_transaction,
 1485                    cx,
 1486                )
 1487                .await?;
 1488            }
 1489        }
 1490        Ok(project_transaction)
 1491    }
 1492
 1493    async fn format_locally(
 1494        lsp_store: WeakEntity<LspStore>,
 1495        mut buffers: Vec<FormattableBuffer>,
 1496        push_to_history: bool,
 1497        trigger: FormatTrigger,
 1498        logger: zlog::Logger,
 1499        cx: &mut AsyncApp,
 1500    ) -> anyhow::Result<ProjectTransaction> {
 1501        // Do not allow multiple concurrent formatting requests for the
 1502        // same buffer.
 1503        lsp_store.update(cx, |this, cx| {
 1504            let this = this.as_local_mut().unwrap();
 1505            buffers.retain(|buffer| {
 1506                this.buffers_being_formatted
 1507                    .insert(buffer.handle.read(cx).remote_id())
 1508            });
 1509        })?;
 1510
 1511        let _cleanup = defer({
 1512            let this = lsp_store.clone();
 1513            let mut cx = cx.clone();
 1514            let buffers = &buffers;
 1515            move || {
 1516                this.update(&mut cx, |this, cx| {
 1517                    let this = this.as_local_mut().unwrap();
 1518                    for buffer in buffers {
 1519                        this.buffers_being_formatted
 1520                            .remove(&buffer.handle.read(cx).remote_id());
 1521                    }
 1522                })
 1523                .ok();
 1524            }
 1525        });
 1526
 1527        let mut project_transaction = ProjectTransaction::default();
 1528
 1529        for buffer in &buffers {
 1530            zlog::debug!(
 1531                logger =>
 1532                "formatting buffer '{:?}'",
 1533                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1534            );
 1535            // Create an empty transaction to hold all of the formatting edits.
 1536            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1537                // ensure no transactions created while formatting are
 1538                // grouped with the previous transaction in the history
 1539                // based on the transaction group interval
 1540                buffer.finalize_last_transaction();
 1541                buffer
 1542                    .start_transaction()
 1543                    .context("transaction already open")?;
 1544                buffer.end_transaction(cx);
 1545                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1546                buffer.finalize_last_transaction();
 1547                anyhow::Ok(transaction_id)
 1548            })?;
 1549
 1550            let result = Self::format_buffer_locally(
 1551                lsp_store.clone(),
 1552                buffer,
 1553                formatting_transaction_id,
 1554                trigger,
 1555                logger,
 1556                cx,
 1557            )
 1558            .await;
 1559
 1560            buffer.handle.update(cx, |buffer, cx| {
 1561                let Some(formatting_transaction) =
 1562                    buffer.get_transaction(formatting_transaction_id).cloned()
 1563                else {
 1564                    zlog::warn!(logger => "no formatting transaction");
 1565                    return;
 1566                };
 1567                if formatting_transaction.edit_ids.is_empty() {
 1568                    zlog::debug!(logger => "no changes made while formatting");
 1569                    buffer.forget_transaction(formatting_transaction_id);
 1570                    return;
 1571                }
 1572                if !push_to_history {
 1573                    zlog::trace!(logger => "forgetting format transaction");
 1574                    buffer.forget_transaction(formatting_transaction.id);
 1575                }
 1576                project_transaction
 1577                    .0
 1578                    .insert(cx.entity(), formatting_transaction);
 1579            });
 1580
 1581            result?;
 1582        }
 1583
 1584        Ok(project_transaction)
 1585    }
 1586
 1587    async fn format_buffer_locally(
 1588        lsp_store: WeakEntity<LspStore>,
 1589        buffer: &FormattableBuffer,
 1590        formatting_transaction_id: clock::Lamport,
 1591        trigger: FormatTrigger,
 1592        logger: zlog::Logger,
 1593        cx: &mut AsyncApp,
 1594    ) -> Result<()> {
 1595        let (adapters_and_servers, settings, request_timeout) =
 1596            lsp_store.update(cx, |lsp_store, cx| {
 1597                buffer.handle.update(cx, |buffer, cx| {
 1598                    let adapters_and_servers = lsp_store
 1599                        .as_local()
 1600                        .unwrap()
 1601                        .language_servers_for_buffer(buffer, cx)
 1602                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1603                        .collect::<Vec<_>>();
 1604                    let settings =
 1605                        language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1606                            .into_owned();
 1607                    let request_timeout = ProjectSettings::get_global(cx)
 1608                        .global_lsp_settings
 1609                        .get_request_timeout();
 1610                    (adapters_and_servers, settings, request_timeout)
 1611                })
 1612            })?;
 1613
 1614        /// Apply edits to the buffer that will become part of the formatting transaction.
 1615        /// Fails if the buffer has been edited since the start of that transaction.
 1616        fn extend_formatting_transaction(
 1617            buffer: &FormattableBuffer,
 1618            formatting_transaction_id: text::TransactionId,
 1619            cx: &mut AsyncApp,
 1620            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1621        ) -> anyhow::Result<()> {
 1622            buffer.handle.update(cx, |buffer, cx| {
 1623                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1624                if last_transaction_id != Some(formatting_transaction_id) {
 1625                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1626                }
 1627                buffer.start_transaction();
 1628                operation(buffer, cx);
 1629                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1630                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1631                }
 1632                Ok(())
 1633            })
 1634        }
 1635
 1636        // handle whitespace formatting
 1637        if settings.remove_trailing_whitespace_on_save {
 1638            zlog::trace!(logger => "removing trailing whitespace");
 1639            let diff = buffer
 1640                .handle
 1641                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1642                .await;
 1643            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1644                buffer.apply_diff(diff, cx);
 1645            })?;
 1646        }
 1647
 1648        if settings.ensure_final_newline_on_save {
 1649            zlog::trace!(logger => "ensuring final newline");
 1650            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1651                buffer.ensure_final_newline(cx);
 1652            })?;
 1653        }
 1654
 1655        // Formatter for `code_actions_on_format` that runs before
 1656        // the rest of the formatters
 1657        let mut code_actions_on_format_formatters = None;
 1658        let should_run_code_actions_on_format = !matches!(
 1659            (trigger, &settings.format_on_save),
 1660            (FormatTrigger::Save, &FormatOnSave::Off)
 1661        );
 1662        if should_run_code_actions_on_format {
 1663            let have_code_actions_to_run_on_format = settings
 1664                .code_actions_on_format
 1665                .values()
 1666                .any(|enabled| *enabled);
 1667            if have_code_actions_to_run_on_format {
 1668                zlog::trace!(logger => "going to run code actions on format");
 1669                code_actions_on_format_formatters = Some(
 1670                    settings
 1671                        .code_actions_on_format
 1672                        .iter()
 1673                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1674                        .cloned()
 1675                        .map(Formatter::CodeAction)
 1676                        .collect::<Vec<_>>(),
 1677                );
 1678            }
 1679        }
 1680
 1681        let formatters = match (trigger, &settings.format_on_save) {
 1682            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1683            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1684                settings.formatter.as_ref()
 1685            }
 1686        };
 1687
 1688        let formatters = code_actions_on_format_formatters
 1689            .iter()
 1690            .flatten()
 1691            .chain(formatters);
 1692
 1693        for formatter in formatters {
 1694            let formatter = if formatter == &Formatter::Auto {
 1695                if settings.prettier.allowed {
 1696                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1697                    &Formatter::Prettier
 1698                } else {
 1699                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1700                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1701                }
 1702            } else {
 1703                formatter
 1704            };
 1705            match formatter {
 1706                Formatter::None => {
 1707                    zlog::trace!(logger => "skipping formatter 'none'");
 1708                    continue;
 1709                }
 1710                Formatter::Auto => unreachable!("Auto resolved above"),
 1711                Formatter::Prettier => {
 1712                    let logger = zlog::scoped!(logger => "prettier");
 1713                    zlog::trace!(logger => "formatting");
 1714                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1715
 1716                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1717                        lsp_store.prettier_store().unwrap().downgrade()
 1718                    })?;
 1719                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1720                        .await
 1721                        .transpose()?;
 1722                    let Some(diff) = diff else {
 1723                        zlog::trace!(logger => "No changes");
 1724                        continue;
 1725                    };
 1726
 1727                    extend_formatting_transaction(
 1728                        buffer,
 1729                        formatting_transaction_id,
 1730                        cx,
 1731                        |buffer, cx| {
 1732                            buffer.apply_diff(diff, cx);
 1733                        },
 1734                    )?;
 1735                }
 1736                Formatter::External { command, arguments } => {
 1737                    let logger = zlog::scoped!(logger => "command");
 1738                    zlog::trace!(logger => "formatting");
 1739                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1740
 1741                    let diff = Self::format_via_external_command(
 1742                        buffer,
 1743                        &command,
 1744                        arguments.as_deref(),
 1745                        cx,
 1746                    )
 1747                    .await
 1748                    .with_context(|| {
 1749                        format!("Failed to format buffer via external command: {}", command)
 1750                    })?;
 1751                    let Some(diff) = diff else {
 1752                        zlog::trace!(logger => "No changes");
 1753                        continue;
 1754                    };
 1755
 1756                    extend_formatting_transaction(
 1757                        buffer,
 1758                        formatting_transaction_id,
 1759                        cx,
 1760                        |buffer, cx| {
 1761                            buffer.apply_diff(diff, cx);
 1762                        },
 1763                    )?;
 1764                }
 1765                Formatter::LanguageServer(specifier) => {
 1766                    let logger = zlog::scoped!(logger => "language-server");
 1767                    zlog::trace!(logger => "formatting");
 1768                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1769
 1770                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1771                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1772                        continue;
 1773                    };
 1774
 1775                    let language_server = match specifier {
 1776                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1777                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1778                                if adapter.name.0.as_ref() == name {
 1779                                    Some(server.clone())
 1780                                } else {
 1781                                    None
 1782                                }
 1783                            })
 1784                        }
 1785                        settings::LanguageServerFormatterSpecifier::Current => adapters_and_servers
 1786                            .iter()
 1787                            .find(|(_, server)| Self::server_supports_formatting(server))
 1788                            .map(|(_, server)| server.clone()),
 1789                    };
 1790
 1791                    let Some(language_server) = language_server else {
 1792                        log::debug!(
 1793                            "No language server found to format buffer '{:?}'. Skipping",
 1794                            buffer_path_abs.as_path().to_string_lossy()
 1795                        );
 1796                        continue;
 1797                    };
 1798
 1799                    zlog::trace!(
 1800                        logger =>
 1801                        "Formatting buffer '{:?}' using language server '{:?}'",
 1802                        buffer_path_abs.as_path().to_string_lossy(),
 1803                        language_server.name()
 1804                    );
 1805
 1806                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1807                        zlog::trace!(logger => "formatting ranges");
 1808                        Self::format_ranges_via_lsp(
 1809                            &lsp_store,
 1810                            &buffer.handle,
 1811                            ranges,
 1812                            buffer_path_abs,
 1813                            &language_server,
 1814                            &settings,
 1815                            cx,
 1816                        )
 1817                        .await
 1818                        .context("Failed to format ranges via language server")?
 1819                    } else {
 1820                        zlog::trace!(logger => "formatting full");
 1821                        Self::format_via_lsp(
 1822                            &lsp_store,
 1823                            &buffer.handle,
 1824                            buffer_path_abs,
 1825                            &language_server,
 1826                            &settings,
 1827                            cx,
 1828                        )
 1829                        .await
 1830                        .context("failed to format via language server")?
 1831                    };
 1832
 1833                    if edits.is_empty() {
 1834                        zlog::trace!(logger => "No changes");
 1835                        continue;
 1836                    }
 1837                    extend_formatting_transaction(
 1838                        buffer,
 1839                        formatting_transaction_id,
 1840                        cx,
 1841                        |buffer, cx| {
 1842                            buffer.edit(edits, None, cx);
 1843                        },
 1844                    )?;
 1845                }
 1846                Formatter::CodeAction(code_action_name) => {
 1847                    let logger = zlog::scoped!(logger => "code-actions");
 1848                    zlog::trace!(logger => "formatting");
 1849                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1850
 1851                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1852                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1853                        continue;
 1854                    };
 1855
 1856                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1857                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1858
 1859                    let mut actions_and_servers = Vec::new();
 1860
 1861                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1862                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1863                            &lsp_store,
 1864                            language_server.server_id(),
 1865                            vec![code_action_kind.clone()],
 1866                            &buffer.handle,
 1867                            cx,
 1868                        )
 1869                        .await
 1870                        .with_context(|| {
 1871                            format!(
 1872                                "Failed to resolve code action {:?} with language server {}",
 1873                                code_action_kind,
 1874                                language_server.name()
 1875                            )
 1876                        });
 1877                        let Ok(actions) = actions_result else {
 1878                            // note: it may be better to set result to the error and break formatters here
 1879                            // but for now we try to execute the actions that we can resolve and skip the rest
 1880                            zlog::error!(
 1881                                logger =>
 1882                                "Failed to resolve code action {:?} with language server {}",
 1883                                code_action_kind,
 1884                                language_server.name()
 1885                            );
 1886                            continue;
 1887                        };
 1888                        for action in actions {
 1889                            actions_and_servers.push((action, index));
 1890                        }
 1891                    }
 1892
 1893                    if actions_and_servers.is_empty() {
 1894                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1895                        continue;
 1896                    }
 1897
 1898                    'actions: for (mut action, server_index) in actions_and_servers {
 1899                        let server = &adapters_and_servers[server_index].1;
 1900
 1901                        let describe_code_action = |action: &CodeAction| {
 1902                            format!(
 1903                                "code action '{}' with title \"{}\" on server {}",
 1904                                action
 1905                                    .lsp_action
 1906                                    .action_kind()
 1907                                    .unwrap_or("unknown".into())
 1908                                    .as_str(),
 1909                                action.lsp_action.title(),
 1910                                server.name(),
 1911                            )
 1912                        };
 1913
 1914                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1915
 1916                        if let Err(err) =
 1917                            Self::try_resolve_code_action(server, &mut action, request_timeout)
 1918                                .await
 1919                        {
 1920                            zlog::error!(
 1921                                logger =>
 1922                                "Failed to resolve {}. Error: {}",
 1923                                describe_code_action(&action),
 1924                                err
 1925                            );
 1926                            continue;
 1927                        }
 1928
 1929                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1930                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1931                            // but filters out and logs warnings for code actions that require unreasonably
 1932                            // difficult handling on our part, such as:
 1933                            // - applying edits that call commands
 1934                            //   which can result in arbitrary workspace edits being sent from the server that
 1935                            //   have no way of being tied back to the command that initiated them (i.e. we
 1936                            //   can't know which edits are part of the format request, or if the server is done sending
 1937                            //   actions in response to the command)
 1938                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1939                            //   as we then would need to handle such changes correctly in the local history as well
 1940                            //   as the remote history through the ProjectTransaction
 1941                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1942                            // Supporting these actions is not impossible, but not supported as of yet.
 1943                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1944                                zlog::trace!(
 1945                                    logger =>
 1946                                    "No changes for code action. Skipping {}",
 1947                                    describe_code_action(&action),
 1948                                );
 1949                                continue;
 1950                            }
 1951
 1952                            let mut operations = Vec::new();
 1953                            if let Some(document_changes) = edit.document_changes {
 1954                                match document_changes {
 1955                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1956                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1957                                    ),
 1958                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1959                                }
 1960                            } else if let Some(changes) = edit.changes {
 1961                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1962                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1963                                        text_document:
 1964                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1965                                                uri,
 1966                                                version: None,
 1967                                            },
 1968                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1969                                    })
 1970                                }));
 1971                            }
 1972
 1973                            let mut edits = Vec::with_capacity(operations.len());
 1974
 1975                            if operations.is_empty() {
 1976                                zlog::trace!(
 1977                                    logger =>
 1978                                    "No changes for code action. Skipping {}",
 1979                                    describe_code_action(&action),
 1980                                );
 1981                                continue;
 1982                            }
 1983                            for operation in operations {
 1984                                let op = match operation {
 1985                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1986                                    lsp::DocumentChangeOperation::Op(_) => {
 1987                                        zlog::warn!(
 1988                                            logger =>
 1989                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1990                                            describe_code_action(&action),
 1991                                        );
 1992                                        continue 'actions;
 1993                                    }
 1994                                };
 1995                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1996                                    zlog::warn!(
 1997                                        logger =>
 1998                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1999                                        &op.text_document.uri,
 2000                                        describe_code_action(&action),
 2001                                    );
 2002                                    continue 'actions;
 2003                                };
 2004                                if &file_path != buffer_path_abs {
 2005                                    zlog::warn!(
 2006                                        logger =>
 2007                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 2008                                        file_path,
 2009                                        buffer_path_abs,
 2010                                        describe_code_action(&action),
 2011                                    );
 2012                                    continue 'actions;
 2013                                }
 2014
 2015                                let mut lsp_edits = Vec::new();
 2016                                for edit in op.edits {
 2017                                    match edit {
 2018                                        Edit::Plain(edit) => {
 2019                                            if !lsp_edits.contains(&edit) {
 2020                                                lsp_edits.push(edit);
 2021                                            }
 2022                                        }
 2023                                        Edit::Annotated(edit) => {
 2024                                            if !lsp_edits.contains(&edit.text_edit) {
 2025                                                lsp_edits.push(edit.text_edit);
 2026                                            }
 2027                                        }
 2028                                        Edit::Snippet(_) => {
 2029                                            zlog::warn!(
 2030                                                logger =>
 2031                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 2032                                                describe_code_action(&action),
 2033                                            );
 2034                                            continue 'actions;
 2035                                        }
 2036                                    }
 2037                                }
 2038                                let edits_result = lsp_store
 2039                                    .update(cx, |lsp_store, cx| {
 2040                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 2041                                            &buffer.handle,
 2042                                            lsp_edits,
 2043                                            server.server_id(),
 2044                                            op.text_document.version,
 2045                                            cx,
 2046                                        )
 2047                                    })?
 2048                                    .await;
 2049                                let Ok(resolved_edits) = edits_result else {
 2050                                    zlog::warn!(
 2051                                        logger =>
 2052                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 2053                                        buffer_path_abs.as_path(),
 2054                                        describe_code_action(&action),
 2055                                    );
 2056                                    continue 'actions;
 2057                                };
 2058                                edits.extend(resolved_edits);
 2059                            }
 2060
 2061                            if edits.is_empty() {
 2062                                zlog::warn!(logger => "No edits resolved from LSP");
 2063                                continue;
 2064                            }
 2065
 2066                            extend_formatting_transaction(
 2067                                buffer,
 2068                                formatting_transaction_id,
 2069                                cx,
 2070                                |buffer, cx| {
 2071                                    zlog::info!(
 2072                                        "Applying edits {edits:?}. Content: {:?}",
 2073                                        buffer.text()
 2074                                    );
 2075                                    buffer.edit(edits, None, cx);
 2076                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 2077                                },
 2078                            )?;
 2079                        }
 2080
 2081                        // bail early if command is invalid
 2082                        let Some(command) = action.lsp_action.command() else {
 2083                            continue;
 2084                        };
 2085
 2086                        zlog::warn!(
 2087                            logger =>
 2088                            "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 2089                            &command.command,
 2090                        );
 2091
 2092                        let server_capabilities = server.capabilities();
 2093                        let available_commands = server_capabilities
 2094                            .execute_command_provider
 2095                            .as_ref()
 2096                            .map(|options| options.commands.as_slice())
 2097                            .unwrap_or_default();
 2098                        if !available_commands.contains(&command.command) {
 2099                            zlog::warn!(
 2100                                logger =>
 2101                                "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2102                                command.command,
 2103                                server.name(),
 2104                            );
 2105                            continue;
 2106                        }
 2107
 2108                        // noop so we just ensure buffer hasn't been edited since resolving code actions
 2109                        extend_formatting_transaction(
 2110                            buffer,
 2111                            formatting_transaction_id,
 2112                            cx,
 2113                            |_, _| {},
 2114                        )?;
 2115                        zlog::info!(logger => "Executing command {}", &command.command);
 2116
 2117                        lsp_store.update(cx, |this, _| {
 2118                            this.as_local_mut()
 2119                                .unwrap()
 2120                                .last_workspace_edits_by_language_server
 2121                                .remove(&server.server_id());
 2122                        })?;
 2123
 2124                        let execute_command_result = server
 2125                            .request::<lsp::request::ExecuteCommand>(
 2126                                lsp::ExecuteCommandParams {
 2127                                    command: command.command.clone(),
 2128                                    arguments: command.arguments.clone().unwrap_or_default(),
 2129                                    ..Default::default()
 2130                                },
 2131                                request_timeout,
 2132                            )
 2133                            .await
 2134                            .into_response();
 2135
 2136                        if execute_command_result.is_err() {
 2137                            zlog::error!(
 2138                                logger =>
 2139                                "Failed to execute command '{}' as part of {}",
 2140                                &command.command,
 2141                                describe_code_action(&action),
 2142                            );
 2143                            continue 'actions;
 2144                        }
 2145
 2146                        let mut project_transaction_command = lsp_store.update(cx, |this, _| {
 2147                            this.as_local_mut()
 2148                                .unwrap()
 2149                                .last_workspace_edits_by_language_server
 2150                                .remove(&server.server_id())
 2151                                .unwrap_or_default()
 2152                        })?;
 2153
 2154                        if let Some(transaction) =
 2155                            project_transaction_command.0.remove(&buffer.handle)
 2156                        {
 2157                            zlog::trace!(
 2158                                logger =>
 2159                                "Successfully captured {} edits that resulted from command {}",
 2160                                transaction.edit_ids.len(),
 2161                                &command.command,
 2162                            );
 2163                            let transaction_id_project_transaction = transaction.id;
 2164                            buffer.handle.update(cx, |buffer, _| {
 2165                                // it may have been removed from history if push_to_history was
 2166                                // false in deserialize_workspace_edit. If so push it so we
 2167                                // can merge it with the format transaction
 2168                                // and pop the combined transaction off the history stack
 2169                                // later if push_to_history is false
 2170                                if buffer.get_transaction(transaction.id).is_none() {
 2171                                    buffer.push_transaction(transaction, Instant::now());
 2172                                }
 2173                                buffer.merge_transactions(
 2174                                    transaction_id_project_transaction,
 2175                                    formatting_transaction_id,
 2176                                );
 2177                            });
 2178                        }
 2179
 2180                        if project_transaction_command.0.is_empty() {
 2181                            continue;
 2182                        }
 2183
 2184                        let mut extra_buffers = String::new();
 2185                        for buffer in project_transaction_command.0.keys() {
 2186                            buffer.read_with(cx, |b, cx| {
 2187                                let Some(path) = b.project_path(cx) else {
 2188                                    return;
 2189                                };
 2190
 2191                                if !extra_buffers.is_empty() {
 2192                                    extra_buffers.push_str(", ");
 2193                                }
 2194                                extra_buffers.push_str(path.path.as_unix_str());
 2195                            });
 2196                        }
 2197                        zlog::warn!(
 2198                            logger =>
 2199                            "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2200                            &command.command,
 2201                            extra_buffers,
 2202                        );
 2203                        // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2204                        // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2205                        // add it so it's included, and merge it into the format transaction when its created later
 2206                    }
 2207                }
 2208            }
 2209        }
 2210
 2211        Ok(())
 2212    }
 2213
 2214    pub async fn format_ranges_via_lsp(
 2215        this: &WeakEntity<LspStore>,
 2216        buffer_handle: &Entity<Buffer>,
 2217        ranges: &[Range<Anchor>],
 2218        abs_path: &Path,
 2219        language_server: &Arc<LanguageServer>,
 2220        settings: &LanguageSettings,
 2221        cx: &mut AsyncApp,
 2222    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2223        let capabilities = &language_server.capabilities();
 2224        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2225        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2226            anyhow::bail!(
 2227                "{} language server does not support range formatting",
 2228                language_server.name()
 2229            );
 2230        }
 2231
 2232        let uri = file_path_to_lsp_url(abs_path)?;
 2233        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2234
 2235        let request_timeout = cx.update(|app| {
 2236            ProjectSettings::get_global(app)
 2237                .global_lsp_settings
 2238                .get_request_timeout()
 2239        });
 2240        let lsp_edits = {
 2241            let mut lsp_ranges = Vec::new();
 2242            this.update(cx, |_this, cx| {
 2243                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2244                // not have been sent to the language server. This seems like a fairly systemic
 2245                // issue, though, the resolution probably is not specific to formatting.
 2246                //
 2247                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2248                // LSP.
 2249                let snapshot = buffer_handle.read(cx).snapshot();
 2250                for range in ranges {
 2251                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2252                }
 2253                anyhow::Ok(())
 2254            })??;
 2255
 2256            let mut edits = None;
 2257            for range in lsp_ranges {
 2258                if let Some(mut edit) = language_server
 2259                    .request::<lsp::request::RangeFormatting>(
 2260                        lsp::DocumentRangeFormattingParams {
 2261                            text_document: text_document.clone(),
 2262                            range,
 2263                            options: lsp_command::lsp_formatting_options(settings),
 2264                            work_done_progress_params: Default::default(),
 2265                        },
 2266                        request_timeout,
 2267                    )
 2268                    .await
 2269                    .into_response()?
 2270                {
 2271                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2272                }
 2273            }
 2274            edits
 2275        };
 2276
 2277        if let Some(lsp_edits) = lsp_edits {
 2278            this.update(cx, |this, cx| {
 2279                this.as_local_mut().unwrap().edits_from_lsp(
 2280                    buffer_handle,
 2281                    lsp_edits,
 2282                    language_server.server_id(),
 2283                    None,
 2284                    cx,
 2285                )
 2286            })?
 2287            .await
 2288        } else {
 2289            Ok(Vec::with_capacity(0))
 2290        }
 2291    }
 2292
 2293    fn server_supports_formatting(server: &Arc<LanguageServer>) -> bool {
 2294        let capabilities = server.capabilities();
 2295        let formatting = capabilities.document_formatting_provider.as_ref();
 2296        let range_formatting = capabilities.document_range_formatting_provider.as_ref();
 2297        matches!(formatting, Some(p) if *p != OneOf::Left(false))
 2298            || matches!(range_formatting, Some(p) if *p != OneOf::Left(false))
 2299    }
 2300
 2301    async fn format_via_lsp(
 2302        this: &WeakEntity<LspStore>,
 2303        buffer: &Entity<Buffer>,
 2304        abs_path: &Path,
 2305        language_server: &Arc<LanguageServer>,
 2306        settings: &LanguageSettings,
 2307        cx: &mut AsyncApp,
 2308    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2309        let logger = zlog::scoped!("lsp_format");
 2310        zlog::debug!(logger => "Formatting via LSP");
 2311
 2312        let uri = file_path_to_lsp_url(abs_path)?;
 2313        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2314        let capabilities = &language_server.capabilities();
 2315
 2316        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2317        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2318
 2319        let request_timeout = cx.update(|app| {
 2320            ProjectSettings::get_global(app)
 2321                .global_lsp_settings
 2322                .get_request_timeout()
 2323        });
 2324
 2325        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2326            let _timer = zlog::time!(logger => "format-full");
 2327            language_server
 2328                .request::<lsp::request::Formatting>(
 2329                    lsp::DocumentFormattingParams {
 2330                        text_document,
 2331                        options: lsp_command::lsp_formatting_options(settings),
 2332                        work_done_progress_params: Default::default(),
 2333                    },
 2334                    request_timeout,
 2335                )
 2336                .await
 2337                .into_response()?
 2338        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2339            let _timer = zlog::time!(logger => "format-range");
 2340            let buffer_start = lsp::Position::new(0, 0);
 2341            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2342            language_server
 2343                .request::<lsp::request::RangeFormatting>(
 2344                    lsp::DocumentRangeFormattingParams {
 2345                        text_document: text_document.clone(),
 2346                        range: lsp::Range::new(buffer_start, buffer_end),
 2347                        options: lsp_command::lsp_formatting_options(settings),
 2348                        work_done_progress_params: Default::default(),
 2349                    },
 2350                    request_timeout,
 2351                )
 2352                .await
 2353                .into_response()?
 2354        } else {
 2355            None
 2356        };
 2357
 2358        if let Some(lsp_edits) = lsp_edits {
 2359            this.update(cx, |this, cx| {
 2360                this.as_local_mut().unwrap().edits_from_lsp(
 2361                    buffer,
 2362                    lsp_edits,
 2363                    language_server.server_id(),
 2364                    None,
 2365                    cx,
 2366                )
 2367            })?
 2368            .await
 2369        } else {
 2370            Ok(Vec::with_capacity(0))
 2371        }
 2372    }
 2373
 2374    async fn format_via_external_command(
 2375        buffer: &FormattableBuffer,
 2376        command: &str,
 2377        arguments: Option<&[String]>,
 2378        cx: &mut AsyncApp,
 2379    ) -> Result<Option<Diff>> {
 2380        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2381            let file = File::from_dyn(buffer.file())?;
 2382            let worktree = file.worktree.read(cx);
 2383            let mut worktree_path = worktree.abs_path().to_path_buf();
 2384            if worktree.root_entry()?.is_file() {
 2385                worktree_path.pop();
 2386            }
 2387            Some(worktree_path)
 2388        });
 2389
 2390        use util::command::Stdio;
 2391        let mut child = util::command::new_command(command);
 2392
 2393        if let Some(buffer_env) = buffer.env.as_ref() {
 2394            child.envs(buffer_env);
 2395        }
 2396
 2397        if let Some(working_dir_path) = working_dir_path {
 2398            child.current_dir(working_dir_path);
 2399        }
 2400
 2401        if let Some(arguments) = arguments {
 2402            child.args(arguments.iter().map(|arg| {
 2403                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2404                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2405                } else {
 2406                    arg.replace("{buffer_path}", "Untitled")
 2407                }
 2408            }));
 2409        }
 2410
 2411        let mut child = child
 2412            .stdin(Stdio::piped())
 2413            .stdout(Stdio::piped())
 2414            .stderr(Stdio::piped())
 2415            .spawn()?;
 2416
 2417        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2418        let text = buffer
 2419            .handle
 2420            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2421        for chunk in text.chunks() {
 2422            stdin.write_all(chunk.as_bytes()).await?;
 2423        }
 2424        stdin.flush().await?;
 2425
 2426        let output = child.output().await?;
 2427        anyhow::ensure!(
 2428            output.status.success(),
 2429            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2430            output.status.code(),
 2431            String::from_utf8_lossy(&output.stdout),
 2432            String::from_utf8_lossy(&output.stderr),
 2433        );
 2434
 2435        let stdout = String::from_utf8(output.stdout)?;
 2436        Ok(Some(
 2437            buffer
 2438                .handle
 2439                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2440                .await,
 2441        ))
 2442    }
 2443
 2444    async fn try_resolve_code_action(
 2445        lang_server: &LanguageServer,
 2446        action: &mut CodeAction,
 2447        request_timeout: Duration,
 2448    ) -> anyhow::Result<()> {
 2449        match &mut action.lsp_action {
 2450            LspAction::Action(lsp_action) => {
 2451                if !action.resolved
 2452                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2453                    && lsp_action.data.is_some()
 2454                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2455                {
 2456                    **lsp_action = lang_server
 2457                        .request::<lsp::request::CodeActionResolveRequest>(
 2458                            *lsp_action.clone(),
 2459                            request_timeout,
 2460                        )
 2461                        .await
 2462                        .into_response()?;
 2463                }
 2464            }
 2465            LspAction::CodeLens(lens) => {
 2466                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2467                    *lens = lang_server
 2468                        .request::<lsp::request::CodeLensResolve>(lens.clone(), request_timeout)
 2469                        .await
 2470                        .into_response()?;
 2471                }
 2472            }
 2473            LspAction::Command(_) => {}
 2474        }
 2475
 2476        action.resolved = true;
 2477        anyhow::Ok(())
 2478    }
 2479
 2480    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2481        let buffer = buffer_handle.read(cx);
 2482
 2483        let file = buffer.file().cloned();
 2484
 2485        let Some(file) = File::from_dyn(file.as_ref()) else {
 2486            return;
 2487        };
 2488        if !file.is_local() {
 2489            return;
 2490        }
 2491        let path = ProjectPath::from_file(file, cx);
 2492        let worktree_id = file.worktree_id(cx);
 2493        let language = buffer.language().cloned();
 2494
 2495        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2496            for (server_id, diagnostics) in
 2497                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2498            {
 2499                self.update_buffer_diagnostics(
 2500                    buffer_handle,
 2501                    server_id,
 2502                    None,
 2503                    None,
 2504                    None,
 2505                    Vec::new(),
 2506                    diagnostics,
 2507                    cx,
 2508                )
 2509                .log_err();
 2510            }
 2511        }
 2512        let Some(language) = language else {
 2513            return;
 2514        };
 2515        let Some(snapshot) = self
 2516            .worktree_store
 2517            .read(cx)
 2518            .worktree_for_id(worktree_id, cx)
 2519            .map(|worktree| worktree.read(cx).snapshot())
 2520        else {
 2521            return;
 2522        };
 2523        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2524
 2525        for server_id in
 2526            self.lsp_tree
 2527                .get(path, language.name(), language.manifest(), &delegate, cx)
 2528        {
 2529            let server = self
 2530                .language_servers
 2531                .get(&server_id)
 2532                .and_then(|server_state| {
 2533                    if let LanguageServerState::Running { server, .. } = server_state {
 2534                        Some(server.clone())
 2535                    } else {
 2536                        None
 2537                    }
 2538                });
 2539            let server = match server {
 2540                Some(server) => server,
 2541                None => continue,
 2542            };
 2543
 2544            buffer_handle.update(cx, |buffer, cx| {
 2545                buffer.set_completion_triggers(
 2546                    server.server_id(),
 2547                    server
 2548                        .capabilities()
 2549                        .completion_provider
 2550                        .as_ref()
 2551                        .and_then(|provider| {
 2552                            provider
 2553                                .trigger_characters
 2554                                .as_ref()
 2555                                .map(|characters| characters.iter().cloned().collect())
 2556                        })
 2557                        .unwrap_or_default(),
 2558                    cx,
 2559                );
 2560            });
 2561        }
 2562    }
 2563
 2564    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2565        buffer.update(cx, |buffer, cx| {
 2566            let Some(language) = buffer.language() else {
 2567                return;
 2568            };
 2569            let path = ProjectPath {
 2570                worktree_id: old_file.worktree_id(cx),
 2571                path: old_file.path.clone(),
 2572            };
 2573            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2574                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2575                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2576            }
 2577        });
 2578    }
 2579
 2580    fn update_buffer_diagnostics(
 2581        &mut self,
 2582        buffer: &Entity<Buffer>,
 2583        server_id: LanguageServerId,
 2584        registration_id: Option<Option<SharedString>>,
 2585        result_id: Option<SharedString>,
 2586        version: Option<i32>,
 2587        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2588        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2589        cx: &mut Context<LspStore>,
 2590    ) -> Result<()> {
 2591        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2592            Ordering::Equal
 2593                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2594                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2595                .then_with(|| a.severity.cmp(&b.severity))
 2596                .then_with(|| a.message.cmp(&b.message))
 2597        }
 2598
 2599        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2600        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2601        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2602
 2603        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2604            Ordering::Equal
 2605                .then_with(|| a.range.start.cmp(&b.range.start))
 2606                .then_with(|| b.range.end.cmp(&a.range.end))
 2607                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2608        });
 2609
 2610        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2611
 2612        let edits_since_save = std::cell::LazyCell::new(|| {
 2613            let saved_version = buffer.read(cx).saved_version();
 2614            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2615        });
 2616
 2617        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2618
 2619        for (new_diagnostic, entry) in diagnostics {
 2620            let start;
 2621            let end;
 2622            if new_diagnostic && entry.diagnostic.is_disk_based {
 2623                // Some diagnostics are based on files on disk instead of buffers'
 2624                // current contents. Adjust these diagnostics' ranges to reflect
 2625                // any unsaved edits.
 2626                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2627                // and were properly adjusted on reuse.
 2628                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2629                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2630            } else {
 2631                start = entry.range.start;
 2632                end = entry.range.end;
 2633            }
 2634
 2635            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2636                ..snapshot.clip_point_utf16(end, Bias::Right);
 2637
 2638            // Expand empty ranges by one codepoint
 2639            if range.start == range.end {
 2640                // This will be go to the next boundary when being clipped
 2641                range.end.column += 1;
 2642                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2643                if range.start == range.end && range.end.column > 0 {
 2644                    range.start.column -= 1;
 2645                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2646                }
 2647            }
 2648
 2649            sanitized_diagnostics.push(DiagnosticEntry {
 2650                range,
 2651                diagnostic: entry.diagnostic,
 2652            });
 2653        }
 2654        drop(edits_since_save);
 2655
 2656        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2657        buffer.update(cx, |buffer, cx| {
 2658            if let Some(registration_id) = registration_id {
 2659                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2660                    self.buffer_pull_diagnostics_result_ids
 2661                        .entry(server_id)
 2662                        .or_default()
 2663                        .entry(registration_id)
 2664                        .or_default()
 2665                        .insert(abs_path, result_id);
 2666                }
 2667            }
 2668
 2669            buffer.update_diagnostics(server_id, set, cx)
 2670        });
 2671
 2672        Ok(())
 2673    }
 2674
 2675    fn register_language_server_for_invisible_worktree(
 2676        &mut self,
 2677        worktree: &Entity<Worktree>,
 2678        language_server_id: LanguageServerId,
 2679        cx: &mut App,
 2680    ) {
 2681        let worktree = worktree.read(cx);
 2682        let worktree_id = worktree.id();
 2683        debug_assert!(!worktree.is_visible());
 2684        let Some(mut origin_seed) = self
 2685            .language_server_ids
 2686            .iter()
 2687            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2688        else {
 2689            return;
 2690        };
 2691        origin_seed.worktree_id = worktree_id;
 2692        self.language_server_ids
 2693            .entry(origin_seed)
 2694            .or_insert_with(|| UnifiedLanguageServer {
 2695                id: language_server_id,
 2696                project_roots: Default::default(),
 2697            });
 2698    }
 2699
 2700    fn register_buffer_with_language_servers(
 2701        &mut self,
 2702        buffer_handle: &Entity<Buffer>,
 2703        only_register_servers: HashSet<LanguageServerSelector>,
 2704        cx: &mut Context<LspStore>,
 2705    ) {
 2706        let buffer = buffer_handle.read(cx);
 2707        let buffer_id = buffer.remote_id();
 2708
 2709        let Some(file) = File::from_dyn(buffer.file()) else {
 2710            return;
 2711        };
 2712        if !file.is_local() {
 2713            return;
 2714        }
 2715
 2716        let abs_path = file.abs_path(cx);
 2717        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2718            return;
 2719        };
 2720        let initial_snapshot = buffer.text_snapshot();
 2721        let worktree_id = file.worktree_id(cx);
 2722
 2723        let Some(language) = buffer.language().cloned() else {
 2724            return;
 2725        };
 2726        let path: Arc<RelPath> = file
 2727            .path()
 2728            .parent()
 2729            .map(Arc::from)
 2730            .unwrap_or_else(|| file.path().clone());
 2731        let Some(worktree) = self
 2732            .worktree_store
 2733            .read(cx)
 2734            .worktree_for_id(worktree_id, cx)
 2735        else {
 2736            return;
 2737        };
 2738        let language_name = language.name();
 2739        let (reused, delegate, servers) = self
 2740            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2741            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2742            .unwrap_or_else(|| {
 2743                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2744                let delegate: Arc<dyn ManifestDelegate> =
 2745                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2746
 2747                let servers = self
 2748                    .lsp_tree
 2749                    .walk(
 2750                        ProjectPath { worktree_id, path },
 2751                        language.name(),
 2752                        language.manifest(),
 2753                        &delegate,
 2754                        cx,
 2755                    )
 2756                    .collect::<Vec<_>>();
 2757                (false, lsp_delegate, servers)
 2758            });
 2759        let servers_and_adapters = servers
 2760            .into_iter()
 2761            .filter_map(|server_node| {
 2762                if reused && server_node.server_id().is_none() {
 2763                    return None;
 2764                }
 2765                if !only_register_servers.is_empty() {
 2766                    if let Some(server_id) = server_node.server_id()
 2767                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2768                    {
 2769                        return None;
 2770                    }
 2771                    if let Some(name) = server_node.name()
 2772                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2773                    {
 2774                        return None;
 2775                    }
 2776                }
 2777
 2778                let server_id = server_node.server_id_or_init(|disposition| {
 2779                    let path = &disposition.path;
 2780
 2781                    {
 2782                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2783
 2784                        let server_id = self.get_or_insert_language_server(
 2785                            &worktree,
 2786                            delegate.clone(),
 2787                            disposition,
 2788                            &language_name,
 2789                            cx,
 2790                        );
 2791
 2792                        if let Some(state) = self.language_servers.get(&server_id)
 2793                            && let Ok(uri) = uri
 2794                        {
 2795                            state.add_workspace_folder(uri);
 2796                        };
 2797                        server_id
 2798                    }
 2799                })?;
 2800                let server_state = self.language_servers.get(&server_id)?;
 2801                if let LanguageServerState::Running {
 2802                    server, adapter, ..
 2803                } = server_state
 2804                {
 2805                    Some((server.clone(), adapter.clone()))
 2806                } else {
 2807                    None
 2808                }
 2809            })
 2810            .collect::<Vec<_>>();
 2811        for (server, adapter) in servers_and_adapters {
 2812            buffer_handle.update(cx, |buffer, cx| {
 2813                buffer.set_completion_triggers(
 2814                    server.server_id(),
 2815                    server
 2816                        .capabilities()
 2817                        .completion_provider
 2818                        .as_ref()
 2819                        .and_then(|provider| {
 2820                            provider
 2821                                .trigger_characters
 2822                                .as_ref()
 2823                                .map(|characters| characters.iter().cloned().collect())
 2824                        })
 2825                        .unwrap_or_default(),
 2826                    cx,
 2827                );
 2828            });
 2829
 2830            let snapshot = LspBufferSnapshot {
 2831                version: 0,
 2832                snapshot: initial_snapshot.clone(),
 2833            };
 2834
 2835            let mut registered = false;
 2836            self.buffer_snapshots
 2837                .entry(buffer_id)
 2838                .or_default()
 2839                .entry(server.server_id())
 2840                .or_insert_with(|| {
 2841                    registered = true;
 2842                    server.register_buffer(
 2843                        uri.clone(),
 2844                        adapter.language_id(&language.name()),
 2845                        0,
 2846                        initial_snapshot.text(),
 2847                    );
 2848
 2849                    vec![snapshot]
 2850                });
 2851
 2852            self.buffers_opened_in_servers
 2853                .entry(buffer_id)
 2854                .or_default()
 2855                .insert(server.server_id());
 2856            if registered {
 2857                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2858                    language_server_id: server.server_id(),
 2859                    name: None,
 2860                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2861                        proto::RegisteredForBuffer {
 2862                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2863                            buffer_id: buffer_id.to_proto(),
 2864                        },
 2865                    ),
 2866                });
 2867            }
 2868        }
 2869    }
 2870
 2871    fn reuse_existing_language_server<'lang_name>(
 2872        &self,
 2873        server_tree: &LanguageServerTree,
 2874        worktree: &Entity<Worktree>,
 2875        language_name: &'lang_name LanguageName,
 2876        cx: &mut App,
 2877    ) -> Option<(
 2878        Arc<LocalLspAdapterDelegate>,
 2879        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2880    )> {
 2881        if worktree.read(cx).is_visible() {
 2882            return None;
 2883        }
 2884
 2885        let worktree_store = self.worktree_store.read(cx);
 2886        let servers = server_tree
 2887            .instances
 2888            .iter()
 2889            .filter(|(worktree_id, _)| {
 2890                worktree_store
 2891                    .worktree_for_id(**worktree_id, cx)
 2892                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2893            })
 2894            .flat_map(|(worktree_id, servers)| {
 2895                servers
 2896                    .roots
 2897                    .iter()
 2898                    .flat_map(|(_, language_servers)| language_servers)
 2899                    .map(move |(_, (server_node, server_languages))| {
 2900                        (worktree_id, server_node, server_languages)
 2901                    })
 2902                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2903                    .map(|(worktree_id, server_node, _)| {
 2904                        (
 2905                            *worktree_id,
 2906                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2907                        )
 2908                    })
 2909            })
 2910            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2911                acc.entry(worktree_id)
 2912                    .or_insert_with(Vec::new)
 2913                    .push(server_node);
 2914                acc
 2915            })
 2916            .into_values()
 2917            .max_by_key(|servers| servers.len())?;
 2918
 2919        let worktree_id = worktree.read(cx).id();
 2920        let apply = move |tree: &mut LanguageServerTree| {
 2921            for server_node in &servers {
 2922                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2923            }
 2924            servers
 2925        };
 2926
 2927        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2928        Some((delegate, apply))
 2929    }
 2930
 2931    pub(crate) fn unregister_old_buffer_from_language_servers(
 2932        &mut self,
 2933        buffer: &Entity<Buffer>,
 2934        old_file: &File,
 2935        cx: &mut App,
 2936    ) {
 2937        let old_path = match old_file.as_local() {
 2938            Some(local) => local.abs_path(cx),
 2939            None => return,
 2940        };
 2941
 2942        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2943            debug_panic!("{old_path:?} is not parseable as an URI");
 2944            return;
 2945        };
 2946        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2947    }
 2948
 2949    pub(crate) fn unregister_buffer_from_language_servers(
 2950        &mut self,
 2951        buffer: &Entity<Buffer>,
 2952        file_url: &lsp::Uri,
 2953        cx: &mut App,
 2954    ) {
 2955        buffer.update(cx, |buffer, cx| {
 2956            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2957
 2958            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2959                if snapshots
 2960                    .as_mut()
 2961                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2962                {
 2963                    language_server.unregister_buffer(file_url.clone());
 2964                }
 2965            }
 2966        });
 2967    }
 2968
 2969    fn buffer_snapshot_for_lsp_version(
 2970        &mut self,
 2971        buffer: &Entity<Buffer>,
 2972        server_id: LanguageServerId,
 2973        version: Option<i32>,
 2974        cx: &App,
 2975    ) -> Result<TextBufferSnapshot> {
 2976        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2977
 2978        if let Some(version) = version {
 2979            let buffer_id = buffer.read(cx).remote_id();
 2980            let snapshots = if let Some(snapshots) = self
 2981                .buffer_snapshots
 2982                .get_mut(&buffer_id)
 2983                .and_then(|m| m.get_mut(&server_id))
 2984            {
 2985                snapshots
 2986            } else if version == 0 {
 2987                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2988                // We detect this case and treat it as if the version was `None`.
 2989                return Ok(buffer.read(cx).text_snapshot());
 2990            } else {
 2991                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2992            };
 2993
 2994            let found_snapshot = snapshots
 2995                    .binary_search_by_key(&version, |e| e.version)
 2996                    .map(|ix| snapshots[ix].snapshot.clone())
 2997                    .map_err(|_| {
 2998                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2999                    })?;
 3000
 3001            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 3002            Ok(found_snapshot)
 3003        } else {
 3004            Ok((buffer.read(cx)).text_snapshot())
 3005        }
 3006    }
 3007
 3008    async fn get_server_code_actions_from_action_kinds(
 3009        lsp_store: &WeakEntity<LspStore>,
 3010        language_server_id: LanguageServerId,
 3011        code_action_kinds: Vec<lsp::CodeActionKind>,
 3012        buffer: &Entity<Buffer>,
 3013        cx: &mut AsyncApp,
 3014    ) -> Result<Vec<CodeAction>> {
 3015        let actions = lsp_store
 3016            .update(cx, move |this, cx| {
 3017                let request = GetCodeActions {
 3018                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 3019                    kinds: Some(code_action_kinds),
 3020                };
 3021                let server = LanguageServerToQuery::Other(language_server_id);
 3022                this.request_lsp(buffer.clone(), server, request, cx)
 3023            })?
 3024            .await?;
 3025        Ok(actions)
 3026    }
 3027
 3028    pub async fn execute_code_actions_on_server(
 3029        lsp_store: &WeakEntity<LspStore>,
 3030        language_server: &Arc<LanguageServer>,
 3031        actions: Vec<CodeAction>,
 3032        push_to_history: bool,
 3033        project_transaction: &mut ProjectTransaction,
 3034        cx: &mut AsyncApp,
 3035    ) -> anyhow::Result<()> {
 3036        let request_timeout = cx.update(|app| {
 3037            ProjectSettings::get_global(app)
 3038                .global_lsp_settings
 3039                .get_request_timeout()
 3040        });
 3041
 3042        for mut action in actions {
 3043            Self::try_resolve_code_action(language_server, &mut action, request_timeout)
 3044                .await
 3045                .context("resolving a formatting code action")?;
 3046
 3047            if let Some(edit) = action.lsp_action.edit() {
 3048                if edit.changes.is_none() && edit.document_changes.is_none() {
 3049                    continue;
 3050                }
 3051
 3052                let new = Self::deserialize_workspace_edit(
 3053                    lsp_store.upgrade().context("project dropped")?,
 3054                    edit.clone(),
 3055                    push_to_history,
 3056                    language_server.clone(),
 3057                    cx,
 3058                )
 3059                .await?;
 3060                project_transaction.0.extend(new.0);
 3061            }
 3062
 3063            let Some(command) = action.lsp_action.command() else {
 3064                continue;
 3065            };
 3066
 3067            let server_capabilities = language_server.capabilities();
 3068            let available_commands = server_capabilities
 3069                .execute_command_provider
 3070                .as_ref()
 3071                .map(|options| options.commands.as_slice())
 3072                .unwrap_or_default();
 3073            if !available_commands.contains(&command.command) {
 3074                log::warn!(
 3075                    "Cannot execute a command {} not listed in the language server capabilities",
 3076                    command.command
 3077                );
 3078                continue;
 3079            }
 3080
 3081            lsp_store.update(cx, |lsp_store, _| {
 3082                if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 3083                    mode.last_workspace_edits_by_language_server
 3084                        .remove(&language_server.server_id());
 3085                }
 3086            })?;
 3087
 3088            language_server
 3089                .request::<lsp::request::ExecuteCommand>(
 3090                    lsp::ExecuteCommandParams {
 3091                        command: command.command.clone(),
 3092                        arguments: command.arguments.clone().unwrap_or_default(),
 3093                        ..Default::default()
 3094                    },
 3095                    request_timeout,
 3096                )
 3097                .await
 3098                .into_response()
 3099                .context("execute command")?;
 3100
 3101            lsp_store.update(cx, |this, _| {
 3102                if let LspStoreMode::Local(mode) = &mut this.mode {
 3103                    project_transaction.0.extend(
 3104                        mode.last_workspace_edits_by_language_server
 3105                            .remove(&language_server.server_id())
 3106                            .unwrap_or_default()
 3107                            .0,
 3108                    )
 3109                }
 3110            })?;
 3111        }
 3112        Ok(())
 3113    }
 3114
 3115    pub async fn deserialize_text_edits(
 3116        this: Entity<LspStore>,
 3117        buffer_to_edit: Entity<Buffer>,
 3118        edits: Vec<lsp::TextEdit>,
 3119        push_to_history: bool,
 3120        _: Arc<CachedLspAdapter>,
 3121        language_server: Arc<LanguageServer>,
 3122        cx: &mut AsyncApp,
 3123    ) -> Result<Option<Transaction>> {
 3124        let edits = this
 3125            .update(cx, |this, cx| {
 3126                this.as_local_mut().unwrap().edits_from_lsp(
 3127                    &buffer_to_edit,
 3128                    edits,
 3129                    language_server.server_id(),
 3130                    None,
 3131                    cx,
 3132                )
 3133            })
 3134            .await?;
 3135
 3136        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3137            buffer.finalize_last_transaction();
 3138            buffer.start_transaction();
 3139            for (range, text) in edits {
 3140                buffer.edit([(range, text)], None, cx);
 3141            }
 3142
 3143            if buffer.end_transaction(cx).is_some() {
 3144                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3145                if !push_to_history {
 3146                    buffer.forget_transaction(transaction.id);
 3147                }
 3148                Some(transaction)
 3149            } else {
 3150                None
 3151            }
 3152        });
 3153
 3154        Ok(transaction)
 3155    }
 3156
 3157    #[allow(clippy::type_complexity)]
 3158    pub fn edits_from_lsp(
 3159        &mut self,
 3160        buffer: &Entity<Buffer>,
 3161        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3162        server_id: LanguageServerId,
 3163        version: Option<i32>,
 3164        cx: &mut Context<LspStore>,
 3165    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3166        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3167        cx.background_spawn(async move {
 3168            let snapshot = snapshot?;
 3169            let mut lsp_edits = lsp_edits
 3170                .into_iter()
 3171                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3172                .collect::<Vec<_>>();
 3173
 3174            lsp_edits.sort_unstable_by_key(|(range, _)| (range.start, range.end));
 3175
 3176            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3177            let mut edits = Vec::new();
 3178            while let Some((range, mut new_text)) = lsp_edits.next() {
 3179                // Clip invalid ranges provided by the language server.
 3180                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3181                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3182
 3183                // Combine any LSP edits that are adjacent.
 3184                //
 3185                // Also, combine LSP edits that are separated from each other by only
 3186                // a newline. This is important because for some code actions,
 3187                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3188                // are separated by unchanged newline characters.
 3189                //
 3190                // In order for the diffing logic below to work properly, any edits that
 3191                // cancel each other out must be combined into one.
 3192                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3193                    if next_range.start.0 > range.end {
 3194                        if next_range.start.0.row > range.end.row + 1
 3195                            || next_range.start.0.column > 0
 3196                            || snapshot.clip_point_utf16(
 3197                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3198                                Bias::Left,
 3199                            ) > range.end
 3200                        {
 3201                            break;
 3202                        }
 3203                        new_text.push('\n');
 3204                    }
 3205                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3206                    new_text.push_str(next_text);
 3207                    lsp_edits.next();
 3208                }
 3209
 3210                // For multiline edits, perform a diff of the old and new text so that
 3211                // we can identify the changes more precisely, preserving the locations
 3212                // of any anchors positioned in the unchanged regions.
 3213                if range.end.row > range.start.row {
 3214                    let offset = range.start.to_offset(&snapshot);
 3215                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3216                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3217                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3218                        (
 3219                            snapshot.anchor_after(offset + range.start)
 3220                                ..snapshot.anchor_before(offset + range.end),
 3221                            replacement,
 3222                        )
 3223                    }));
 3224                } else if range.end == range.start {
 3225                    let anchor = snapshot.anchor_after(range.start);
 3226                    edits.push((anchor..anchor, new_text.into()));
 3227                } else {
 3228                    let edit_start = snapshot.anchor_after(range.start);
 3229                    let edit_end = snapshot.anchor_before(range.end);
 3230                    edits.push((edit_start..edit_end, new_text.into()));
 3231                }
 3232            }
 3233
 3234            Ok(edits)
 3235        })
 3236    }
 3237
 3238    pub(crate) async fn deserialize_workspace_edit(
 3239        this: Entity<LspStore>,
 3240        edit: lsp::WorkspaceEdit,
 3241        push_to_history: bool,
 3242        language_server: Arc<LanguageServer>,
 3243        cx: &mut AsyncApp,
 3244    ) -> Result<ProjectTransaction> {
 3245        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3246
 3247        let mut operations = Vec::new();
 3248        if let Some(document_changes) = edit.document_changes {
 3249            match document_changes {
 3250                lsp::DocumentChanges::Edits(edits) => {
 3251                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3252                }
 3253                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3254            }
 3255        } else if let Some(changes) = edit.changes {
 3256            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3257                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3258                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3259                        uri,
 3260                        version: None,
 3261                    },
 3262                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3263                })
 3264            }));
 3265        }
 3266
 3267        let mut project_transaction = ProjectTransaction::default();
 3268        for operation in operations {
 3269            match operation {
 3270                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3271                    let abs_path = op
 3272                        .uri
 3273                        .to_file_path()
 3274                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3275
 3276                    if let Some(parent_path) = abs_path.parent() {
 3277                        fs.create_dir(parent_path).await?;
 3278                    }
 3279                    if abs_path.ends_with("/") {
 3280                        fs.create_dir(&abs_path).await?;
 3281                    } else {
 3282                        fs.create_file(
 3283                            &abs_path,
 3284                            op.options
 3285                                .map(|options| fs::CreateOptions {
 3286                                    overwrite: options.overwrite.unwrap_or(false),
 3287                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3288                                })
 3289                                .unwrap_or_default(),
 3290                        )
 3291                        .await?;
 3292                    }
 3293                }
 3294
 3295                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3296                    let source_abs_path = op
 3297                        .old_uri
 3298                        .to_file_path()
 3299                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3300                    let target_abs_path = op
 3301                        .new_uri
 3302                        .to_file_path()
 3303                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3304
 3305                    let options = fs::RenameOptions {
 3306                        overwrite: op
 3307                            .options
 3308                            .as_ref()
 3309                            .and_then(|options| options.overwrite)
 3310                            .unwrap_or(false),
 3311                        ignore_if_exists: op
 3312                            .options
 3313                            .as_ref()
 3314                            .and_then(|options| options.ignore_if_exists)
 3315                            .unwrap_or(false),
 3316                        create_parents: true,
 3317                    };
 3318
 3319                    fs.rename(&source_abs_path, &target_abs_path, options)
 3320                        .await?;
 3321                }
 3322
 3323                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3324                    let abs_path = op
 3325                        .uri
 3326                        .to_file_path()
 3327                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3328                    let options = op
 3329                        .options
 3330                        .map(|options| fs::RemoveOptions {
 3331                            recursive: options.recursive.unwrap_or(false),
 3332                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3333                        })
 3334                        .unwrap_or_default();
 3335                    if abs_path.ends_with("/") {
 3336                        fs.remove_dir(&abs_path, options).await?;
 3337                    } else {
 3338                        fs.remove_file(&abs_path, options).await?;
 3339                    }
 3340                }
 3341
 3342                lsp::DocumentChangeOperation::Edit(op) => {
 3343                    let buffer_to_edit = this
 3344                        .update(cx, |this, cx| {
 3345                            this.open_local_buffer_via_lsp(
 3346                                op.text_document.uri.clone(),
 3347                                language_server.server_id(),
 3348                                cx,
 3349                            )
 3350                        })
 3351                        .await?;
 3352
 3353                    let edits = this
 3354                        .update(cx, |this, cx| {
 3355                            let path = buffer_to_edit.read(cx).project_path(cx);
 3356                            let active_entry = this.active_entry;
 3357                            let is_active_entry = path.is_some_and(|project_path| {
 3358                                this.worktree_store
 3359                                    .read(cx)
 3360                                    .entry_for_path(&project_path, cx)
 3361                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3362                            });
 3363                            let local = this.as_local_mut().unwrap();
 3364
 3365                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3366                            for edit in op.edits {
 3367                                match edit {
 3368                                    Edit::Plain(edit) => {
 3369                                        if !edits.contains(&edit) {
 3370                                            edits.push(edit)
 3371                                        }
 3372                                    }
 3373                                    Edit::Annotated(edit) => {
 3374                                        if !edits.contains(&edit.text_edit) {
 3375                                            edits.push(edit.text_edit)
 3376                                        }
 3377                                    }
 3378                                    Edit::Snippet(edit) => {
 3379                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3380                                        else {
 3381                                            continue;
 3382                                        };
 3383
 3384                                        if is_active_entry {
 3385                                            snippet_edits.push((edit.range, snippet));
 3386                                        } else {
 3387                                            // Since this buffer is not focused, apply a normal edit.
 3388                                            let new_edit = TextEdit {
 3389                                                range: edit.range,
 3390                                                new_text: snippet.text,
 3391                                            };
 3392                                            if !edits.contains(&new_edit) {
 3393                                                edits.push(new_edit);
 3394                                            }
 3395                                        }
 3396                                    }
 3397                                }
 3398                            }
 3399                            if !snippet_edits.is_empty() {
 3400                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3401                                let version = if let Some(buffer_version) = op.text_document.version
 3402                                {
 3403                                    local
 3404                                        .buffer_snapshot_for_lsp_version(
 3405                                            &buffer_to_edit,
 3406                                            language_server.server_id(),
 3407                                            Some(buffer_version),
 3408                                            cx,
 3409                                        )
 3410                                        .ok()
 3411                                        .map(|snapshot| snapshot.version)
 3412                                } else {
 3413                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3414                                };
 3415
 3416                                let most_recent_edit =
 3417                                    version.and_then(|version| version.most_recent());
 3418                                // Check if the edit that triggered that edit has been made by this participant.
 3419
 3420                                if let Some(most_recent_edit) = most_recent_edit {
 3421                                    cx.emit(LspStoreEvent::SnippetEdit {
 3422                                        buffer_id,
 3423                                        edits: snippet_edits,
 3424                                        most_recent_edit,
 3425                                    });
 3426                                }
 3427                            }
 3428
 3429                            local.edits_from_lsp(
 3430                                &buffer_to_edit,
 3431                                edits,
 3432                                language_server.server_id(),
 3433                                op.text_document.version,
 3434                                cx,
 3435                            )
 3436                        })
 3437                        .await?;
 3438
 3439                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3440                        buffer.finalize_last_transaction();
 3441                        buffer.start_transaction();
 3442                        for (range, text) in edits {
 3443                            buffer.edit([(range, text)], None, cx);
 3444                        }
 3445
 3446                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3447                            if push_to_history {
 3448                                buffer.finalize_last_transaction();
 3449                                buffer.get_transaction(transaction_id).cloned()
 3450                            } else {
 3451                                buffer.forget_transaction(transaction_id)
 3452                            }
 3453                        })
 3454                    });
 3455                    if let Some(transaction) = transaction {
 3456                        project_transaction.0.insert(buffer_to_edit, transaction);
 3457                    }
 3458                }
 3459            }
 3460        }
 3461
 3462        Ok(project_transaction)
 3463    }
 3464
 3465    async fn on_lsp_workspace_edit(
 3466        this: WeakEntity<LspStore>,
 3467        params: lsp::ApplyWorkspaceEditParams,
 3468        server_id: LanguageServerId,
 3469        cx: &mut AsyncApp,
 3470    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3471        let this = this.upgrade().context("project project closed")?;
 3472        let language_server = this
 3473            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3474            .context("language server not found")?;
 3475        let transaction = Self::deserialize_workspace_edit(
 3476            this.clone(),
 3477            params.edit,
 3478            true,
 3479            language_server.clone(),
 3480            cx,
 3481        )
 3482        .await
 3483        .log_err();
 3484        this.update(cx, |this, cx| {
 3485            if let Some(transaction) = transaction {
 3486                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3487
 3488                this.as_local_mut()
 3489                    .unwrap()
 3490                    .last_workspace_edits_by_language_server
 3491                    .insert(server_id, transaction);
 3492            }
 3493        });
 3494        Ok(lsp::ApplyWorkspaceEditResponse {
 3495            applied: true,
 3496            failed_change: None,
 3497            failure_reason: None,
 3498        })
 3499    }
 3500
 3501    fn remove_worktree(
 3502        &mut self,
 3503        id_to_remove: WorktreeId,
 3504        cx: &mut Context<LspStore>,
 3505    ) -> Vec<LanguageServerId> {
 3506        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3507        self.diagnostics.remove(&id_to_remove);
 3508        self.prettier_store.update(cx, |prettier_store, cx| {
 3509            prettier_store.remove_worktree(id_to_remove, cx);
 3510        });
 3511
 3512        let mut servers_to_remove = BTreeSet::default();
 3513        let mut servers_to_preserve = HashSet::default();
 3514        for (seed, state) in &self.language_server_ids {
 3515            if seed.worktree_id == id_to_remove {
 3516                servers_to_remove.insert(state.id);
 3517            } else {
 3518                servers_to_preserve.insert(state.id);
 3519            }
 3520        }
 3521        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3522        self.language_server_ids
 3523            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3524        for server_id_to_remove in &servers_to_remove {
 3525            self.language_server_watched_paths
 3526                .remove(server_id_to_remove);
 3527            self.language_server_paths_watched_for_rename
 3528                .remove(server_id_to_remove);
 3529            self.last_workspace_edits_by_language_server
 3530                .remove(server_id_to_remove);
 3531            self.language_servers.remove(server_id_to_remove);
 3532            self.buffer_pull_diagnostics_result_ids
 3533                .remove(server_id_to_remove);
 3534            self.workspace_pull_diagnostics_result_ids
 3535                .remove(server_id_to_remove);
 3536            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3537                buffer_servers.remove(server_id_to_remove);
 3538            }
 3539            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3540        }
 3541        servers_to_remove.into_iter().collect()
 3542    }
 3543
 3544    fn rebuild_watched_paths_inner<'a>(
 3545        &'a self,
 3546        language_server_id: LanguageServerId,
 3547        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3548        cx: &mut Context<LspStore>,
 3549    ) -> LanguageServerWatchedPathsBuilder {
 3550        let worktrees = self
 3551            .worktree_store
 3552            .read(cx)
 3553            .worktrees()
 3554            .filter_map(|worktree| {
 3555                self.language_servers_for_worktree(worktree.read(cx).id())
 3556                    .find(|server| server.server_id() == language_server_id)
 3557                    .map(|_| worktree)
 3558            })
 3559            .collect::<Vec<_>>();
 3560
 3561        let mut worktree_globs = HashMap::default();
 3562        let mut abs_globs = HashMap::default();
 3563        log::trace!(
 3564            "Processing new watcher paths for language server with id {}",
 3565            language_server_id
 3566        );
 3567
 3568        for watcher in watchers {
 3569            if let Some((worktree, literal_prefix, pattern)) =
 3570                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3571            {
 3572                worktree.update(cx, |worktree, _| {
 3573                    if let Some((tree, glob)) =
 3574                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3575                    {
 3576                        tree.add_path_prefix_to_scan(literal_prefix);
 3577                        worktree_globs
 3578                            .entry(tree.id())
 3579                            .or_insert_with(GlobSetBuilder::new)
 3580                            .add(glob);
 3581                    }
 3582                });
 3583            } else {
 3584                let (path, pattern) = match &watcher.glob_pattern {
 3585                    lsp::GlobPattern::String(s) => {
 3586                        let watcher_path = SanitizedPath::new(s);
 3587                        let path = glob_literal_prefix(watcher_path.as_path());
 3588                        let pattern = watcher_path
 3589                            .as_path()
 3590                            .strip_prefix(&path)
 3591                            .map(|p| p.to_string_lossy().into_owned())
 3592                            .unwrap_or_else(|e| {
 3593                                debug_panic!(
 3594                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3595                                    s,
 3596                                    path.display(),
 3597                                    e
 3598                                );
 3599                                watcher_path.as_path().to_string_lossy().into_owned()
 3600                            });
 3601                        (path, pattern)
 3602                    }
 3603                    lsp::GlobPattern::Relative(rp) => {
 3604                        let Ok(mut base_uri) = match &rp.base_uri {
 3605                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3606                            lsp::OneOf::Right(base_uri) => base_uri,
 3607                        }
 3608                        .to_file_path() else {
 3609                            continue;
 3610                        };
 3611
 3612                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3613                        let pattern = Path::new(&rp.pattern)
 3614                            .strip_prefix(&path)
 3615                            .map(|p| p.to_string_lossy().into_owned())
 3616                            .unwrap_or_else(|e| {
 3617                                debug_panic!(
 3618                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3619                                    rp.pattern,
 3620                                    path.display(),
 3621                                    e
 3622                                );
 3623                                rp.pattern.clone()
 3624                            });
 3625                        base_uri.push(path);
 3626                        (base_uri, pattern)
 3627                    }
 3628                };
 3629
 3630                if let Some(glob) = Glob::new(&pattern).log_err() {
 3631                    if !path
 3632                        .components()
 3633                        .any(|c| matches!(c, path::Component::Normal(_)))
 3634                    {
 3635                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3636                        // rather than adding a new watcher for `/`.
 3637                        for worktree in &worktrees {
 3638                            worktree_globs
 3639                                .entry(worktree.read(cx).id())
 3640                                .or_insert_with(GlobSetBuilder::new)
 3641                                .add(glob.clone());
 3642                        }
 3643                    } else {
 3644                        abs_globs
 3645                            .entry(path.into())
 3646                            .or_insert_with(GlobSetBuilder::new)
 3647                            .add(glob);
 3648                    }
 3649                }
 3650            }
 3651        }
 3652
 3653        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3654        for (worktree_id, builder) in worktree_globs {
 3655            if let Ok(globset) = builder.build() {
 3656                watch_builder.watch_worktree(worktree_id, globset);
 3657            }
 3658        }
 3659        for (abs_path, builder) in abs_globs {
 3660            if let Ok(globset) = builder.build() {
 3661                watch_builder.watch_abs_path(abs_path, globset);
 3662            }
 3663        }
 3664        watch_builder
 3665    }
 3666
 3667    fn worktree_and_path_for_file_watcher(
 3668        worktrees: &[Entity<Worktree>],
 3669        watcher: &FileSystemWatcher,
 3670        cx: &App,
 3671    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3672        worktrees.iter().find_map(|worktree| {
 3673            let tree = worktree.read(cx);
 3674            let worktree_root_path = tree.abs_path();
 3675            let path_style = tree.path_style();
 3676            match &watcher.glob_pattern {
 3677                lsp::GlobPattern::String(s) => {
 3678                    let watcher_path = SanitizedPath::new(s);
 3679                    let relative = watcher_path
 3680                        .as_path()
 3681                        .strip_prefix(&worktree_root_path)
 3682                        .ok()?;
 3683                    let literal_prefix = glob_literal_prefix(relative);
 3684                    Some((
 3685                        worktree.clone(),
 3686                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3687                        relative.to_string_lossy().into_owned(),
 3688                    ))
 3689                }
 3690                lsp::GlobPattern::Relative(rp) => {
 3691                    let base_uri = match &rp.base_uri {
 3692                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3693                        lsp::OneOf::Right(base_uri) => base_uri,
 3694                    }
 3695                    .to_file_path()
 3696                    .ok()?;
 3697                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3698                    let mut literal_prefix = relative.to_owned();
 3699                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3700                    Some((
 3701                        worktree.clone(),
 3702                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3703                        rp.pattern.clone(),
 3704                    ))
 3705                }
 3706            }
 3707        })
 3708    }
 3709
 3710    fn rebuild_watched_paths(
 3711        &mut self,
 3712        language_server_id: LanguageServerId,
 3713        cx: &mut Context<LspStore>,
 3714    ) {
 3715        let Some(registrations) = self
 3716            .language_server_dynamic_registrations
 3717            .get(&language_server_id)
 3718        else {
 3719            return;
 3720        };
 3721
 3722        let watch_builder = self.rebuild_watched_paths_inner(
 3723            language_server_id,
 3724            registrations.did_change_watched_files.values().flatten(),
 3725            cx,
 3726        );
 3727        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3728        self.language_server_watched_paths
 3729            .insert(language_server_id, watcher);
 3730
 3731        cx.notify();
 3732    }
 3733
 3734    fn on_lsp_did_change_watched_files(
 3735        &mut self,
 3736        language_server_id: LanguageServerId,
 3737        registration_id: &str,
 3738        params: DidChangeWatchedFilesRegistrationOptions,
 3739        cx: &mut Context<LspStore>,
 3740    ) {
 3741        let registrations = self
 3742            .language_server_dynamic_registrations
 3743            .entry(language_server_id)
 3744            .or_default();
 3745
 3746        registrations
 3747            .did_change_watched_files
 3748            .insert(registration_id.to_string(), params.watchers);
 3749
 3750        self.rebuild_watched_paths(language_server_id, cx);
 3751    }
 3752
 3753    fn on_lsp_unregister_did_change_watched_files(
 3754        &mut self,
 3755        language_server_id: LanguageServerId,
 3756        registration_id: &str,
 3757        cx: &mut Context<LspStore>,
 3758    ) {
 3759        let registrations = self
 3760            .language_server_dynamic_registrations
 3761            .entry(language_server_id)
 3762            .or_default();
 3763
 3764        if registrations
 3765            .did_change_watched_files
 3766            .remove(registration_id)
 3767            .is_some()
 3768        {
 3769            log::info!(
 3770                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3771                language_server_id,
 3772                registration_id
 3773            );
 3774        } else {
 3775            log::warn!(
 3776                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3777                language_server_id,
 3778                registration_id
 3779            );
 3780        }
 3781
 3782        self.rebuild_watched_paths(language_server_id, cx);
 3783    }
 3784
 3785    async fn initialization_options_for_adapter(
 3786        adapter: Arc<dyn LspAdapter>,
 3787        delegate: &Arc<dyn LspAdapterDelegate>,
 3788        cx: &mut AsyncApp,
 3789    ) -> Result<Option<serde_json::Value>> {
 3790        let Some(mut initialization_config) =
 3791            adapter.clone().initialization_options(delegate, cx).await?
 3792        else {
 3793            return Ok(None);
 3794        };
 3795
 3796        for other_adapter in delegate.registered_lsp_adapters() {
 3797            if other_adapter.name() == adapter.name() {
 3798                continue;
 3799            }
 3800            if let Ok(Some(target_config)) = other_adapter
 3801                .clone()
 3802                .additional_initialization_options(adapter.name(), delegate)
 3803                .await
 3804            {
 3805                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3806            }
 3807        }
 3808
 3809        Ok(Some(initialization_config))
 3810    }
 3811
 3812    async fn workspace_configuration_for_adapter(
 3813        adapter: Arc<dyn LspAdapter>,
 3814        delegate: &Arc<dyn LspAdapterDelegate>,
 3815        toolchain: Option<Toolchain>,
 3816        requested_uri: Option<Uri>,
 3817        cx: &mut AsyncApp,
 3818    ) -> Result<serde_json::Value> {
 3819        let mut workspace_config = adapter
 3820            .clone()
 3821            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3822            .await?;
 3823
 3824        for other_adapter in delegate.registered_lsp_adapters() {
 3825            if other_adapter.name() == adapter.name() {
 3826                continue;
 3827            }
 3828            if let Ok(Some(target_config)) = other_adapter
 3829                .clone()
 3830                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3831                .await
 3832            {
 3833                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3834            }
 3835        }
 3836
 3837        Ok(workspace_config)
 3838    }
 3839
 3840    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3841        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3842            Some(server.clone())
 3843        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3844            Some(Arc::clone(server))
 3845        } else {
 3846            None
 3847        }
 3848    }
 3849}
 3850
 3851fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3852    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3853        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3854            language_server_id: server.server_id(),
 3855            name: Some(server.name()),
 3856            message: proto::update_language_server::Variant::MetadataUpdated(
 3857                proto::ServerMetadataUpdated {
 3858                    capabilities: Some(capabilities),
 3859                    binary: Some(proto::LanguageServerBinaryInfo {
 3860                        path: server.binary().path.to_string_lossy().into_owned(),
 3861                        arguments: server
 3862                            .binary()
 3863                            .arguments
 3864                            .iter()
 3865                            .map(|arg| arg.to_string_lossy().into_owned())
 3866                            .collect(),
 3867                    }),
 3868                    configuration: serde_json::to_string(server.configuration()).ok(),
 3869                    workspace_folders: server
 3870                        .workspace_folders()
 3871                        .iter()
 3872                        .map(|uri| uri.to_string())
 3873                        .collect(),
 3874                },
 3875            ),
 3876        });
 3877    }
 3878}
 3879
 3880#[derive(Debug)]
 3881pub struct FormattableBuffer {
 3882    handle: Entity<Buffer>,
 3883    abs_path: Option<PathBuf>,
 3884    env: Option<HashMap<String, String>>,
 3885    ranges: Option<Vec<Range<Anchor>>>,
 3886}
 3887
 3888pub struct RemoteLspStore {
 3889    upstream_client: Option<AnyProtoClient>,
 3890    upstream_project_id: u64,
 3891}
 3892
 3893pub(crate) enum LspStoreMode {
 3894    Local(LocalLspStore),   // ssh host and collab host
 3895    Remote(RemoteLspStore), // collab guest
 3896}
 3897
 3898impl LspStoreMode {
 3899    fn is_local(&self) -> bool {
 3900        matches!(self, LspStoreMode::Local(_))
 3901    }
 3902}
 3903
 3904pub struct LspStore {
 3905    mode: LspStoreMode,
 3906    last_formatting_failure: Option<String>,
 3907    downstream_client: Option<(AnyProtoClient, u64)>,
 3908    nonce: u128,
 3909    buffer_store: Entity<BufferStore>,
 3910    worktree_store: Entity<WorktreeStore>,
 3911    pub languages: Arc<LanguageRegistry>,
 3912    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3913    active_entry: Option<ProjectEntryId>,
 3914    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3915    _maintain_buffer_languages: Task<()>,
 3916    diagnostic_summaries:
 3917        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3918    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3919    semantic_token_config: SemanticTokenConfig,
 3920    lsp_data: HashMap<BufferId, BufferLspData>,
 3921    next_hint_id: Arc<AtomicUsize>,
 3922}
 3923
 3924#[derive(Debug)]
 3925pub struct BufferLspData {
 3926    buffer_version: Global,
 3927    document_colors: Option<DocumentColorData>,
 3928    code_lens: Option<CodeLensData>,
 3929    semantic_tokens: Option<SemanticTokensData>,
 3930    folding_ranges: Option<FoldingRangeData>,
 3931    document_symbols: Option<DocumentSymbolsData>,
 3932    inlay_hints: BufferInlayHints,
 3933    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3934    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3935}
 3936
 3937#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3938struct LspKey {
 3939    request_type: TypeId,
 3940    server_queried: Option<LanguageServerId>,
 3941}
 3942
 3943impl BufferLspData {
 3944    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3945        Self {
 3946            buffer_version: buffer.read(cx).version(),
 3947            document_colors: None,
 3948            code_lens: None,
 3949            semantic_tokens: None,
 3950            folding_ranges: None,
 3951            document_symbols: None,
 3952            inlay_hints: BufferInlayHints::new(buffer, cx),
 3953            lsp_requests: HashMap::default(),
 3954            chunk_lsp_requests: HashMap::default(),
 3955        }
 3956    }
 3957
 3958    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3959        if let Some(document_colors) = &mut self.document_colors {
 3960            document_colors.remove_server_data(for_server);
 3961        }
 3962
 3963        if let Some(code_lens) = &mut self.code_lens {
 3964            code_lens.remove_server_data(for_server);
 3965        }
 3966
 3967        self.inlay_hints.remove_server_data(for_server);
 3968
 3969        if let Some(semantic_tokens) = &mut self.semantic_tokens {
 3970            semantic_tokens.remove_server_data(for_server);
 3971        }
 3972
 3973        if let Some(folding_ranges) = &mut self.folding_ranges {
 3974            folding_ranges.ranges.remove(&for_server);
 3975        }
 3976
 3977        if let Some(document_symbols) = &mut self.document_symbols {
 3978            document_symbols.remove_server_data(for_server);
 3979        }
 3980    }
 3981
 3982    #[cfg(any(test, feature = "test-support"))]
 3983    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3984        &self.inlay_hints
 3985    }
 3986}
 3987
 3988#[derive(Debug)]
 3989pub enum LspStoreEvent {
 3990    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3991    LanguageServerRemoved(LanguageServerId),
 3992    LanguageServerUpdate {
 3993        language_server_id: LanguageServerId,
 3994        name: Option<LanguageServerName>,
 3995        message: proto::update_language_server::Variant,
 3996    },
 3997    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3998    LanguageServerPrompt(LanguageServerPromptRequest),
 3999    LanguageDetected {
 4000        buffer: Entity<Buffer>,
 4001        new_language: Option<Arc<Language>>,
 4002    },
 4003    Notification(String),
 4004    RefreshInlayHints {
 4005        server_id: LanguageServerId,
 4006        request_id: Option<usize>,
 4007    },
 4008    RefreshSemanticTokens {
 4009        server_id: LanguageServerId,
 4010        request_id: Option<usize>,
 4011    },
 4012    RefreshCodeLens,
 4013    DiagnosticsUpdated {
 4014        server_id: LanguageServerId,
 4015        paths: Vec<ProjectPath>,
 4016    },
 4017    DiskBasedDiagnosticsStarted {
 4018        language_server_id: LanguageServerId,
 4019    },
 4020    DiskBasedDiagnosticsFinished {
 4021        language_server_id: LanguageServerId,
 4022    },
 4023    SnippetEdit {
 4024        buffer_id: BufferId,
 4025        edits: Vec<(lsp::Range, Snippet)>,
 4026        most_recent_edit: clock::Lamport,
 4027    },
 4028    WorkspaceEditApplied(ProjectTransaction),
 4029}
 4030
 4031#[derive(Clone, Debug, Serialize)]
 4032pub struct LanguageServerStatus {
 4033    pub name: LanguageServerName,
 4034    pub server_version: Option<SharedString>,
 4035    pub server_readable_version: Option<SharedString>,
 4036    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 4037    pub has_pending_diagnostic_updates: bool,
 4038    pub progress_tokens: HashSet<ProgressToken>,
 4039    pub worktree: Option<WorktreeId>,
 4040    pub binary: Option<LanguageServerBinary>,
 4041    pub configuration: Option<Value>,
 4042    pub workspace_folders: BTreeSet<Uri>,
 4043    pub process_id: Option<u32>,
 4044}
 4045
 4046#[derive(Clone, Debug)]
 4047struct CoreSymbol {
 4048    pub language_server_name: LanguageServerName,
 4049    pub source_worktree_id: WorktreeId,
 4050    pub source_language_server_id: LanguageServerId,
 4051    pub path: SymbolLocation,
 4052    pub name: String,
 4053    pub kind: lsp::SymbolKind,
 4054    pub range: Range<Unclipped<PointUtf16>>,
 4055    pub container_name: Option<String>,
 4056}
 4057
 4058#[derive(Clone, Debug, PartialEq, Eq)]
 4059pub enum SymbolLocation {
 4060    InProject(ProjectPath),
 4061    OutsideProject {
 4062        abs_path: Arc<Path>,
 4063        signature: [u8; 32],
 4064    },
 4065}
 4066
 4067impl SymbolLocation {
 4068    fn file_name(&self) -> Option<&str> {
 4069        match self {
 4070            Self::InProject(path) => path.path.file_name(),
 4071            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 4072        }
 4073    }
 4074}
 4075
 4076impl LspStore {
 4077    pub fn init(client: &AnyProtoClient) {
 4078        client.add_entity_request_handler(Self::handle_lsp_query);
 4079        client.add_entity_message_handler(Self::handle_lsp_query_response);
 4080        client.add_entity_request_handler(Self::handle_restart_language_servers);
 4081        client.add_entity_request_handler(Self::handle_stop_language_servers);
 4082        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 4083        client.add_entity_message_handler(Self::handle_start_language_server);
 4084        client.add_entity_message_handler(Self::handle_update_language_server);
 4085        client.add_entity_message_handler(Self::handle_language_server_log);
 4086        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 4087        client.add_entity_request_handler(Self::handle_format_buffers);
 4088        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 4089        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 4090        client.add_entity_request_handler(Self::handle_apply_code_action);
 4091        client.add_entity_request_handler(Self::handle_get_project_symbols);
 4092        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 4093        client.add_entity_request_handler(Self::handle_get_color_presentation);
 4094        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 4095        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 4096        client.add_entity_request_handler(Self::handle_refresh_semantic_tokens);
 4097        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 4098        client.add_entity_request_handler(Self::handle_on_type_formatting);
 4099        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 4100        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 4101        client.add_entity_request_handler(Self::handle_rename_project_entry);
 4102        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 4103        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 4104        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 4105        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 4106        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 4107        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 4108        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 4109
 4110        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 4111        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 4112        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 4113        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 4114        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 4115        client.add_entity_request_handler(
 4116            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 4117        );
 4118        client.add_entity_request_handler(
 4119            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 4120        );
 4121        client.add_entity_request_handler(
 4122            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 4123        );
 4124    }
 4125
 4126    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 4127        match &self.mode {
 4128            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 4129            _ => None,
 4130        }
 4131    }
 4132
 4133    pub fn as_local(&self) -> Option<&LocalLspStore> {
 4134        match &self.mode {
 4135            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4136            _ => None,
 4137        }
 4138    }
 4139
 4140    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 4141        match &mut self.mode {
 4142            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4143            _ => None,
 4144        }
 4145    }
 4146
 4147    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4148        match &self.mode {
 4149            LspStoreMode::Remote(RemoteLspStore {
 4150                upstream_client: Some(upstream_client),
 4151                upstream_project_id,
 4152                ..
 4153            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4154
 4155            LspStoreMode::Remote(RemoteLspStore {
 4156                upstream_client: None,
 4157                ..
 4158            }) => None,
 4159            LspStoreMode::Local(_) => None,
 4160        }
 4161    }
 4162
 4163    pub fn new_local(
 4164        buffer_store: Entity<BufferStore>,
 4165        worktree_store: Entity<WorktreeStore>,
 4166        prettier_store: Entity<PrettierStore>,
 4167        toolchain_store: Entity<LocalToolchainStore>,
 4168        environment: Entity<ProjectEnvironment>,
 4169        manifest_tree: Entity<ManifestTree>,
 4170        languages: Arc<LanguageRegistry>,
 4171        http_client: Arc<dyn HttpClient>,
 4172        fs: Arc<dyn Fs>,
 4173        cx: &mut Context<Self>,
 4174    ) -> Self {
 4175        let yarn = YarnPathStore::new(fs.clone(), cx);
 4176        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4177            .detach();
 4178        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4179            .detach();
 4180        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4181            .detach();
 4182        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4183            .detach();
 4184        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4185            .detach();
 4186        subscribe_to_binary_statuses(&languages, cx).detach();
 4187
 4188        let _maintain_workspace_config = {
 4189            let (sender, receiver) = watch::channel();
 4190            (Self::maintain_workspace_config(receiver, cx), sender)
 4191        };
 4192
 4193        Self {
 4194            mode: LspStoreMode::Local(LocalLspStore {
 4195                weak: cx.weak_entity(),
 4196                worktree_store: worktree_store.clone(),
 4197
 4198                supplementary_language_servers: Default::default(),
 4199                languages: languages.clone(),
 4200                language_server_ids: Default::default(),
 4201                language_servers: Default::default(),
 4202                last_workspace_edits_by_language_server: Default::default(),
 4203                language_server_watched_paths: Default::default(),
 4204                language_server_paths_watched_for_rename: Default::default(),
 4205                language_server_dynamic_registrations: Default::default(),
 4206                buffers_being_formatted: Default::default(),
 4207                buffers_to_refresh_hash_set: HashSet::default(),
 4208                buffers_to_refresh_queue: VecDeque::new(),
 4209                _background_diagnostics_worker: Task::ready(()).shared(),
 4210                buffer_snapshots: Default::default(),
 4211                prettier_store,
 4212                environment,
 4213                http_client,
 4214                fs,
 4215                yarn,
 4216                next_diagnostic_group_id: Default::default(),
 4217                diagnostics: Default::default(),
 4218                _subscription: cx.on_app_quit(|this, _| {
 4219                    this.as_local_mut()
 4220                        .unwrap()
 4221                        .shutdown_language_servers_on_quit()
 4222                }),
 4223                lsp_tree: LanguageServerTree::new(
 4224                    manifest_tree,
 4225                    languages.clone(),
 4226                    toolchain_store.clone(),
 4227                ),
 4228                toolchain_store,
 4229                registered_buffers: HashMap::default(),
 4230                buffers_opened_in_servers: HashMap::default(),
 4231                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4232                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4233                restricted_worktrees_tasks: HashMap::default(),
 4234                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4235                    .manifest_file_names(),
 4236            }),
 4237            last_formatting_failure: None,
 4238            downstream_client: None,
 4239            buffer_store,
 4240            worktree_store,
 4241            languages: languages.clone(),
 4242            language_server_statuses: Default::default(),
 4243            nonce: StdRng::from_os_rng().random(),
 4244            diagnostic_summaries: HashMap::default(),
 4245            lsp_server_capabilities: HashMap::default(),
 4246            semantic_token_config: SemanticTokenConfig::new(cx),
 4247            lsp_data: HashMap::default(),
 4248            next_hint_id: Arc::default(),
 4249            active_entry: None,
 4250            _maintain_workspace_config,
 4251            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4252        }
 4253    }
 4254
 4255    fn send_lsp_proto_request<R: LspCommand>(
 4256        &self,
 4257        buffer: Entity<Buffer>,
 4258        client: AnyProtoClient,
 4259        upstream_project_id: u64,
 4260        request: R,
 4261        cx: &mut Context<LspStore>,
 4262    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4263        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4264            return Task::ready(Ok(R::Response::default()));
 4265        }
 4266        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4267        cx.spawn(async move |this, cx| {
 4268            let response = client.request(message).await?;
 4269            let this = this.upgrade().context("project dropped")?;
 4270            request
 4271                .response_from_proto(response, this, buffer, cx.clone())
 4272                .await
 4273        })
 4274    }
 4275
 4276    pub(super) fn new_remote(
 4277        buffer_store: Entity<BufferStore>,
 4278        worktree_store: Entity<WorktreeStore>,
 4279        languages: Arc<LanguageRegistry>,
 4280        upstream_client: AnyProtoClient,
 4281        project_id: u64,
 4282        cx: &mut Context<Self>,
 4283    ) -> Self {
 4284        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4285            .detach();
 4286        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4287            .detach();
 4288        subscribe_to_binary_statuses(&languages, cx).detach();
 4289        let _maintain_workspace_config = {
 4290            let (sender, receiver) = watch::channel();
 4291            (Self::maintain_workspace_config(receiver, cx), sender)
 4292        };
 4293        Self {
 4294            mode: LspStoreMode::Remote(RemoteLspStore {
 4295                upstream_client: Some(upstream_client),
 4296                upstream_project_id: project_id,
 4297            }),
 4298            downstream_client: None,
 4299            last_formatting_failure: None,
 4300            buffer_store,
 4301            worktree_store,
 4302            languages: languages.clone(),
 4303            language_server_statuses: Default::default(),
 4304            nonce: StdRng::from_os_rng().random(),
 4305            diagnostic_summaries: HashMap::default(),
 4306            lsp_server_capabilities: HashMap::default(),
 4307            semantic_token_config: SemanticTokenConfig::new(cx),
 4308            next_hint_id: Arc::default(),
 4309            lsp_data: HashMap::default(),
 4310            active_entry: None,
 4311
 4312            _maintain_workspace_config,
 4313            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4314        }
 4315    }
 4316
 4317    fn on_buffer_store_event(
 4318        &mut self,
 4319        _: Entity<BufferStore>,
 4320        event: &BufferStoreEvent,
 4321        cx: &mut Context<Self>,
 4322    ) {
 4323        match event {
 4324            BufferStoreEvent::BufferAdded(buffer) => {
 4325                self.on_buffer_added(buffer, cx).log_err();
 4326            }
 4327            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4328                let buffer_id = buffer.read(cx).remote_id();
 4329                if let Some(local) = self.as_local_mut()
 4330                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4331                {
 4332                    local.reset_buffer(buffer, old_file, cx);
 4333
 4334                    if local.registered_buffers.contains_key(&buffer_id) {
 4335                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4336                    }
 4337                }
 4338
 4339                self.detect_language_for_buffer(buffer, cx);
 4340                if let Some(local) = self.as_local_mut() {
 4341                    local.initialize_buffer(buffer, cx);
 4342                    if local.registered_buffers.contains_key(&buffer_id) {
 4343                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4344                    }
 4345                }
 4346            }
 4347            _ => {}
 4348        }
 4349    }
 4350
 4351    fn on_worktree_store_event(
 4352        &mut self,
 4353        _: Entity<WorktreeStore>,
 4354        event: &WorktreeStoreEvent,
 4355        cx: &mut Context<Self>,
 4356    ) {
 4357        match event {
 4358            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4359                if !worktree.read(cx).is_local() {
 4360                    return;
 4361                }
 4362                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4363                    worktree::Event::UpdatedEntries(changes) => {
 4364                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4365                    }
 4366                    worktree::Event::UpdatedGitRepositories(_)
 4367                    | worktree::Event::DeletedEntry(_) => {}
 4368                })
 4369                .detach()
 4370            }
 4371            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4372            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4373                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4374            }
 4375            WorktreeStoreEvent::WorktreeReleased(..)
 4376            | WorktreeStoreEvent::WorktreeOrderChanged
 4377            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4378            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4379            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4380        }
 4381    }
 4382
 4383    fn on_prettier_store_event(
 4384        &mut self,
 4385        _: Entity<PrettierStore>,
 4386        event: &PrettierStoreEvent,
 4387        cx: &mut Context<Self>,
 4388    ) {
 4389        match event {
 4390            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4391                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4392            }
 4393            PrettierStoreEvent::LanguageServerAdded {
 4394                new_server_id,
 4395                name,
 4396                prettier_server,
 4397            } => {
 4398                self.register_supplementary_language_server(
 4399                    *new_server_id,
 4400                    name.clone(),
 4401                    prettier_server.clone(),
 4402                    cx,
 4403                );
 4404            }
 4405        }
 4406    }
 4407
 4408    fn on_toolchain_store_event(
 4409        &mut self,
 4410        _: Entity<LocalToolchainStore>,
 4411        event: &ToolchainStoreEvent,
 4412        _: &mut Context<Self>,
 4413    ) {
 4414        if let ToolchainStoreEvent::ToolchainActivated = event {
 4415            self.request_workspace_config_refresh()
 4416        }
 4417    }
 4418
 4419    fn request_workspace_config_refresh(&mut self) {
 4420        *self._maintain_workspace_config.1.borrow_mut() = ();
 4421    }
 4422
 4423    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4424        self.as_local().map(|local| local.prettier_store.clone())
 4425    }
 4426
 4427    fn on_buffer_event(
 4428        &mut self,
 4429        buffer: Entity<Buffer>,
 4430        event: &language::BufferEvent,
 4431        cx: &mut Context<Self>,
 4432    ) {
 4433        match event {
 4434            language::BufferEvent::Edited { .. } => {
 4435                self.on_buffer_edited(buffer, cx);
 4436            }
 4437
 4438            language::BufferEvent::Saved => {
 4439                self.on_buffer_saved(buffer, cx);
 4440            }
 4441
 4442            _ => {}
 4443        }
 4444    }
 4445
 4446    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4447        buffer
 4448            .read(cx)
 4449            .set_language_registry(self.languages.clone());
 4450
 4451        cx.subscribe(buffer, |this, buffer, event, cx| {
 4452            this.on_buffer_event(buffer, event, cx);
 4453        })
 4454        .detach();
 4455
 4456        self.detect_language_for_buffer(buffer, cx);
 4457        if let Some(local) = self.as_local_mut() {
 4458            local.initialize_buffer(buffer, cx);
 4459        }
 4460
 4461        Ok(())
 4462    }
 4463
 4464    pub fn refresh_background_diagnostics_for_buffers(
 4465        &mut self,
 4466        buffers: HashSet<BufferId>,
 4467        cx: &mut Context<Self>,
 4468    ) -> Shared<Task<()>> {
 4469        let Some(local) = self.as_local_mut() else {
 4470            return Task::ready(()).shared();
 4471        };
 4472        for buffer in buffers {
 4473            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4474                local.buffers_to_refresh_queue.push_back(buffer);
 4475                if local.buffers_to_refresh_queue.len() == 1 {
 4476                    local._background_diagnostics_worker =
 4477                        Self::background_diagnostics_worker(cx).shared();
 4478                }
 4479            }
 4480        }
 4481
 4482        local._background_diagnostics_worker.clone()
 4483    }
 4484
 4485    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4486        let buffer_store = self.buffer_store.clone();
 4487        let local = self.as_local_mut()?;
 4488        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4489            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4490            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4491                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4492            }
 4493        }
 4494        None
 4495    }
 4496
 4497    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4498        cx.spawn(async move |this, cx| {
 4499            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4500                task.await.log_err();
 4501            }
 4502        })
 4503    }
 4504
 4505    pub(crate) fn register_buffer_with_language_servers(
 4506        &mut self,
 4507        buffer: &Entity<Buffer>,
 4508        only_register_servers: HashSet<LanguageServerSelector>,
 4509        ignore_refcounts: bool,
 4510        cx: &mut Context<Self>,
 4511    ) -> OpenLspBufferHandle {
 4512        let buffer_id = buffer.read(cx).remote_id();
 4513        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4514        if let Some(local) = self.as_local_mut() {
 4515            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4516            if !ignore_refcounts {
 4517                *refcount += 1;
 4518            }
 4519
 4520            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4521            // 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
 4522            // 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
 4523            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4524            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4525                return handle;
 4526            };
 4527            if !file.is_local() {
 4528                return handle;
 4529            }
 4530
 4531            if ignore_refcounts || *refcount == 1 {
 4532                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4533            }
 4534            if !ignore_refcounts {
 4535                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4536                    let refcount = {
 4537                        let local = lsp_store.as_local_mut().unwrap();
 4538                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4539                            debug_panic!("bad refcounting");
 4540                            return;
 4541                        };
 4542
 4543                        *refcount -= 1;
 4544                        *refcount
 4545                    };
 4546                    if refcount == 0 {
 4547                        lsp_store.lsp_data.remove(&buffer_id);
 4548                        let local = lsp_store.as_local_mut().unwrap();
 4549                        local.registered_buffers.remove(&buffer_id);
 4550
 4551                        local.buffers_opened_in_servers.remove(&buffer_id);
 4552                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4553                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4554
 4555                            let buffer_abs_path = file.abs_path(cx);
 4556                            for (_, buffer_pull_diagnostics_result_ids) in
 4557                                &mut local.buffer_pull_diagnostics_result_ids
 4558                            {
 4559                                buffer_pull_diagnostics_result_ids.retain(
 4560                                    |_, buffer_result_ids| {
 4561                                        buffer_result_ids.remove(&buffer_abs_path);
 4562                                        !buffer_result_ids.is_empty()
 4563                                    },
 4564                                );
 4565                            }
 4566
 4567                            let diagnostic_updates = local
 4568                                .language_servers
 4569                                .keys()
 4570                                .cloned()
 4571                                .map(|server_id| DocumentDiagnosticsUpdate {
 4572                                    diagnostics: DocumentDiagnostics {
 4573                                        document_abs_path: buffer_abs_path.clone(),
 4574                                        version: None,
 4575                                        diagnostics: Vec::new(),
 4576                                    },
 4577                                    result_id: None,
 4578                                    registration_id: None,
 4579                                    server_id,
 4580                                    disk_based_sources: Cow::Borrowed(&[]),
 4581                                })
 4582                                .collect::<Vec<_>>();
 4583
 4584                            lsp_store
 4585                                .merge_diagnostic_entries(
 4586                                    diagnostic_updates,
 4587                                    |_, diagnostic, _| {
 4588                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4589                                    },
 4590                                    cx,
 4591                                )
 4592                                .context("Clearing diagnostics for the closed buffer")
 4593                                .log_err();
 4594                        }
 4595                    }
 4596                })
 4597                .detach();
 4598            }
 4599        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4600            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4601            cx.background_spawn(async move {
 4602                upstream_client
 4603                    .request(proto::RegisterBufferWithLanguageServers {
 4604                        project_id: upstream_project_id,
 4605                        buffer_id,
 4606                        only_servers: only_register_servers
 4607                            .into_iter()
 4608                            .map(|selector| {
 4609                                let selector = match selector {
 4610                                    LanguageServerSelector::Id(language_server_id) => {
 4611                                        proto::language_server_selector::Selector::ServerId(
 4612                                            language_server_id.to_proto(),
 4613                                        )
 4614                                    }
 4615                                    LanguageServerSelector::Name(language_server_name) => {
 4616                                        proto::language_server_selector::Selector::Name(
 4617                                            language_server_name.to_string(),
 4618                                        )
 4619                                    }
 4620                                };
 4621                                proto::LanguageServerSelector {
 4622                                    selector: Some(selector),
 4623                                }
 4624                            })
 4625                            .collect(),
 4626                    })
 4627                    .await
 4628            })
 4629            .detach();
 4630        } else {
 4631            // Our remote connection got closed
 4632        }
 4633        handle
 4634    }
 4635
 4636    fn maintain_buffer_languages(
 4637        languages: Arc<LanguageRegistry>,
 4638        cx: &mut Context<Self>,
 4639    ) -> Task<()> {
 4640        let mut subscription = languages.subscribe();
 4641        let mut prev_reload_count = languages.reload_count();
 4642        cx.spawn(async move |this, cx| {
 4643            while let Some(()) = subscription.next().await {
 4644                if let Some(this) = this.upgrade() {
 4645                    // If the language registry has been reloaded, then remove and
 4646                    // re-assign the languages on all open buffers.
 4647                    let reload_count = languages.reload_count();
 4648                    if reload_count > prev_reload_count {
 4649                        prev_reload_count = reload_count;
 4650                        this.update(cx, |this, cx| {
 4651                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4652                                for buffer in buffer_store.buffers() {
 4653                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4654                                    {
 4655                                        buffer.update(cx, |buffer, cx| {
 4656                                            buffer.set_language_async(None, cx)
 4657                                        });
 4658                                        if let Some(local) = this.as_local_mut() {
 4659                                            local.reset_buffer(&buffer, &f, cx);
 4660
 4661                                            if local
 4662                                                .registered_buffers
 4663                                                .contains_key(&buffer.read(cx).remote_id())
 4664                                                && let Some(file_url) =
 4665                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4666                                            {
 4667                                                local.unregister_buffer_from_language_servers(
 4668                                                    &buffer, &file_url, cx,
 4669                                                );
 4670                                            }
 4671                                        }
 4672                                    }
 4673                                }
 4674                            });
 4675                        });
 4676                    }
 4677
 4678                    this.update(cx, |this, cx| {
 4679                        let mut plain_text_buffers = Vec::new();
 4680                        let mut buffers_with_unknown_injections = Vec::new();
 4681                        for handle in this.buffer_store.read(cx).buffers() {
 4682                            let buffer = handle.read(cx);
 4683                            if buffer.language().is_none()
 4684                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4685                            {
 4686                                plain_text_buffers.push(handle);
 4687                            } else if buffer.contains_unknown_injections() {
 4688                                buffers_with_unknown_injections.push(handle);
 4689                            }
 4690                        }
 4691
 4692                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4693                        // and reused later in the invisible worktrees.
 4694                        plain_text_buffers.sort_by_key(|buffer| {
 4695                            Reverse(
 4696                                File::from_dyn(buffer.read(cx).file())
 4697                                    .map(|file| file.worktree.read(cx).is_visible()),
 4698                            )
 4699                        });
 4700
 4701                        for buffer in plain_text_buffers {
 4702                            this.detect_language_for_buffer(&buffer, cx);
 4703                            if let Some(local) = this.as_local_mut() {
 4704                                local.initialize_buffer(&buffer, cx);
 4705                                if local
 4706                                    .registered_buffers
 4707                                    .contains_key(&buffer.read(cx).remote_id())
 4708                                {
 4709                                    local.register_buffer_with_language_servers(
 4710                                        &buffer,
 4711                                        HashSet::default(),
 4712                                        cx,
 4713                                    );
 4714                                }
 4715                            }
 4716                        }
 4717
 4718                        for buffer in buffers_with_unknown_injections {
 4719                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4720                        }
 4721                    });
 4722                }
 4723            }
 4724        })
 4725    }
 4726
 4727    fn detect_language_for_buffer(
 4728        &mut self,
 4729        buffer_handle: &Entity<Buffer>,
 4730        cx: &mut Context<Self>,
 4731    ) -> Option<language::AvailableLanguage> {
 4732        // If the buffer has a language, set it and start the language server if we haven't already.
 4733        let buffer = buffer_handle.read(cx);
 4734        let file = buffer.file()?;
 4735
 4736        let content = buffer.as_rope();
 4737        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4738        if let Some(available_language) = &available_language {
 4739            if let Some(Ok(Ok(new_language))) = self
 4740                .languages
 4741                .load_language(available_language)
 4742                .now_or_never()
 4743            {
 4744                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4745            }
 4746        } else {
 4747            cx.emit(LspStoreEvent::LanguageDetected {
 4748                buffer: buffer_handle.clone(),
 4749                new_language: None,
 4750            });
 4751        }
 4752
 4753        available_language
 4754    }
 4755
 4756    pub(crate) fn set_language_for_buffer(
 4757        &mut self,
 4758        buffer_entity: &Entity<Buffer>,
 4759        new_language: Arc<Language>,
 4760        cx: &mut Context<Self>,
 4761    ) {
 4762        let buffer = buffer_entity.read(cx);
 4763        let buffer_file = buffer.file().cloned();
 4764        let buffer_id = buffer.remote_id();
 4765        if let Some(local_store) = self.as_local_mut()
 4766            && local_store.registered_buffers.contains_key(&buffer_id)
 4767            && let Some(abs_path) =
 4768                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4769            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4770        {
 4771            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4772        }
 4773        buffer_entity.update(cx, |buffer, cx| {
 4774            if buffer
 4775                .language()
 4776                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4777            {
 4778                buffer.set_language_async(Some(new_language.clone()), cx);
 4779            }
 4780        });
 4781
 4782        let settings =
 4783            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4784        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4785
 4786        let worktree_id = if let Some(file) = buffer_file {
 4787            let worktree = file.worktree.clone();
 4788
 4789            if let Some(local) = self.as_local_mut()
 4790                && local.registered_buffers.contains_key(&buffer_id)
 4791            {
 4792                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4793            }
 4794            Some(worktree.read(cx).id())
 4795        } else {
 4796            None
 4797        };
 4798
 4799        if settings.prettier.allowed
 4800            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4801        {
 4802            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4803            if let Some(prettier_store) = prettier_store {
 4804                prettier_store.update(cx, |prettier_store, cx| {
 4805                    prettier_store.install_default_prettier(
 4806                        worktree_id,
 4807                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4808                        cx,
 4809                    )
 4810                })
 4811            }
 4812        }
 4813
 4814        cx.emit(LspStoreEvent::LanguageDetected {
 4815            buffer: buffer_entity.clone(),
 4816            new_language: Some(new_language),
 4817        })
 4818    }
 4819
 4820    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4821        self.buffer_store.clone()
 4822    }
 4823
 4824    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4825        self.active_entry = active_entry;
 4826    }
 4827
 4828    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4829        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4830            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4831        {
 4832            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4833                summaries
 4834                    .iter()
 4835                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4836            });
 4837            if let Some(summary) = summaries.next() {
 4838                client
 4839                    .send(proto::UpdateDiagnosticSummary {
 4840                        project_id: downstream_project_id,
 4841                        worktree_id: worktree.id().to_proto(),
 4842                        summary: Some(summary),
 4843                        more_summaries: summaries.collect(),
 4844                    })
 4845                    .log_err();
 4846            }
 4847        }
 4848    }
 4849
 4850    fn is_capable_for_proto_request<R>(
 4851        &self,
 4852        buffer: &Entity<Buffer>,
 4853        request: &R,
 4854        cx: &App,
 4855    ) -> bool
 4856    where
 4857        R: LspCommand,
 4858    {
 4859        self.check_if_capable_for_proto_request(
 4860            buffer,
 4861            |capabilities| {
 4862                request.check_capabilities(AdapterServerCapabilities {
 4863                    server_capabilities: capabilities.clone(),
 4864                    code_action_kinds: None,
 4865                })
 4866            },
 4867            cx,
 4868        )
 4869    }
 4870
 4871    fn check_if_capable_for_proto_request<F>(
 4872        &self,
 4873        buffer: &Entity<Buffer>,
 4874        check: F,
 4875        cx: &App,
 4876    ) -> bool
 4877    where
 4878        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4879    {
 4880        let Some(language) = buffer.read(cx).language().cloned() else {
 4881            return false;
 4882        };
 4883        let registered_language_servers = self
 4884            .languages
 4885            .lsp_adapters(&language.name())
 4886            .into_iter()
 4887            .map(|lsp_adapter| lsp_adapter.name())
 4888            .collect::<HashSet<_>>();
 4889        self.language_server_statuses
 4890            .iter()
 4891            .filter_map(|(server_id, server_status)| {
 4892                // Include servers that are either registered for this language OR
 4893                // available to be loaded (for SSH remote mode where adapters like
 4894                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4895                // but only loaded on the server side)
 4896                let is_relevant = registered_language_servers.contains(&server_status.name)
 4897                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4898                is_relevant.then_some(server_id)
 4899            })
 4900            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4901            .any(check)
 4902    }
 4903
 4904    fn all_capable_for_proto_request<F>(
 4905        &self,
 4906        buffer: &Entity<Buffer>,
 4907        mut check: F,
 4908        cx: &App,
 4909    ) -> Vec<(lsp::LanguageServerId, lsp::LanguageServerName)>
 4910    where
 4911        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4912    {
 4913        let Some(language) = buffer.read(cx).language().cloned() else {
 4914            return Vec::default();
 4915        };
 4916        let registered_language_servers = self
 4917            .languages
 4918            .lsp_adapters(&language.name())
 4919            .into_iter()
 4920            .map(|lsp_adapter| lsp_adapter.name())
 4921            .collect::<HashSet<_>>();
 4922        self.language_server_statuses
 4923            .iter()
 4924            .filter_map(|(server_id, server_status)| {
 4925                // Include servers that are either registered for this language OR
 4926                // available to be loaded (for SSH remote mode where adapters like
 4927                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4928                // but only loaded on the server side)
 4929                let is_relevant = registered_language_servers.contains(&server_status.name)
 4930                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4931                is_relevant.then_some((server_id, &server_status.name))
 4932            })
 4933            .filter_map(|(server_id, server_name)| {
 4934                self.lsp_server_capabilities
 4935                    .get(server_id)
 4936                    .map(|c| (server_id, server_name, c))
 4937            })
 4938            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4939            .map(|(server_id, server_name, _)| (*server_id, server_name.clone()))
 4940            .collect()
 4941    }
 4942
 4943    pub fn request_lsp<R>(
 4944        &mut self,
 4945        buffer: Entity<Buffer>,
 4946        server: LanguageServerToQuery,
 4947        request: R,
 4948        cx: &mut Context<Self>,
 4949    ) -> Task<Result<R::Response>>
 4950    where
 4951        R: LspCommand,
 4952        <R::LspRequest as lsp::request::Request>::Result: Send,
 4953        <R::LspRequest as lsp::request::Request>::Params: Send,
 4954    {
 4955        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4956            return self.send_lsp_proto_request(
 4957                buffer,
 4958                upstream_client,
 4959                upstream_project_id,
 4960                request,
 4961                cx,
 4962            );
 4963        }
 4964
 4965        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4966            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4967                local
 4968                    .language_servers_for_buffer(buffer, cx)
 4969                    .find(|(_, server)| {
 4970                        request.check_capabilities(server.adapter_server_capabilities())
 4971                    })
 4972                    .map(|(_, server)| server.clone())
 4973            }),
 4974            LanguageServerToQuery::Other(id) => self
 4975                .language_server_for_local_buffer(buffer, id, cx)
 4976                .and_then(|(_, server)| {
 4977                    request
 4978                        .check_capabilities(server.adapter_server_capabilities())
 4979                        .then(|| Arc::clone(server))
 4980                }),
 4981        }) else {
 4982            return Task::ready(Ok(Default::default()));
 4983        };
 4984
 4985        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4986
 4987        let Some(file) = file else {
 4988            return Task::ready(Ok(Default::default()));
 4989        };
 4990
 4991        let lsp_params = match request.to_lsp_params_or_response(
 4992            &file.abs_path(cx),
 4993            buffer.read(cx),
 4994            &language_server,
 4995            cx,
 4996        ) {
 4997            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4998            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4999            Err(err) => {
 5000                let message = format!(
 5001                    "{} via {} failed: {}",
 5002                    request.display_name(),
 5003                    language_server.name(),
 5004                    err
 5005                );
 5006                // rust-analyzer likes to error with this when its still loading up
 5007                if !message.ends_with("content modified") {
 5008                    log::warn!("{message}");
 5009                }
 5010                return Task::ready(Err(anyhow!(message)));
 5011            }
 5012        };
 5013
 5014        let status = request.status();
 5015        let request_timeout = ProjectSettings::get_global(cx)
 5016            .global_lsp_settings
 5017            .get_request_timeout();
 5018
 5019        cx.spawn(async move |this, cx| {
 5020            let lsp_request = language_server.request::<R::LspRequest>(lsp_params, request_timeout);
 5021
 5022            let id = lsp_request.id();
 5023            let _cleanup = if status.is_some() {
 5024                cx.update(|cx| {
 5025                    this.update(cx, |this, cx| {
 5026                        this.on_lsp_work_start(
 5027                            language_server.server_id(),
 5028                            ProgressToken::Number(id),
 5029                            LanguageServerProgress {
 5030                                is_disk_based_diagnostics_progress: false,
 5031                                is_cancellable: false,
 5032                                title: None,
 5033                                message: status.clone(),
 5034                                percentage: None,
 5035                                last_update_at: cx.background_executor().now(),
 5036                            },
 5037                            cx,
 5038                        );
 5039                    })
 5040                })
 5041                .log_err();
 5042
 5043                Some(defer(|| {
 5044                    cx.update(|cx| {
 5045                        this.update(cx, |this, cx| {
 5046                            this.on_lsp_work_end(
 5047                                language_server.server_id(),
 5048                                ProgressToken::Number(id),
 5049                                cx,
 5050                            );
 5051                        })
 5052                    })
 5053                    .log_err();
 5054                }))
 5055            } else {
 5056                None
 5057            };
 5058
 5059            let result = lsp_request.await.into_response();
 5060
 5061            let response = result.map_err(|err| {
 5062                let message = format!(
 5063                    "{} via {} failed: {}",
 5064                    request.display_name(),
 5065                    language_server.name(),
 5066                    err
 5067                );
 5068                // rust-analyzer likes to error with this when its still loading up
 5069                if !message.ends_with("content modified") {
 5070                    log::warn!("{message}");
 5071                }
 5072                anyhow::anyhow!(message)
 5073            })?;
 5074
 5075            request
 5076                .response_from_lsp(
 5077                    response,
 5078                    this.upgrade().context("no app context")?,
 5079                    buffer,
 5080                    language_server.server_id(),
 5081                    cx.clone(),
 5082                )
 5083                .await
 5084        })
 5085    }
 5086
 5087    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 5088        let mut language_formatters_to_check = Vec::new();
 5089        for buffer in self.buffer_store.read(cx).buffers() {
 5090            let buffer = buffer.read(cx);
 5091            let buffer_file = File::from_dyn(buffer.file());
 5092            let buffer_language = buffer.language();
 5093            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 5094            if buffer_language.is_some() {
 5095                language_formatters_to_check.push((
 5096                    buffer_file.map(|f| f.worktree_id(cx)),
 5097                    settings.into_owned(),
 5098                ));
 5099            }
 5100        }
 5101
 5102        self.request_workspace_config_refresh();
 5103
 5104        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 5105            prettier_store.update(cx, |prettier_store, cx| {
 5106                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 5107            })
 5108        }
 5109
 5110        let new_semantic_token_rules = crate::project_settings::ProjectSettings::get_global(cx)
 5111            .global_lsp_settings
 5112            .semantic_token_rules
 5113            .clone();
 5114        self.semantic_token_config
 5115            .update_rules(new_semantic_token_rules);
 5116        // Always clear cached stylizers so that changes to language-specific
 5117        // semantic token rules (e.g. from extension install/uninstall) are
 5118        // picked up. Stylizers are recreated lazily, so this is cheap.
 5119        self.semantic_token_config.clear_stylizers();
 5120
 5121        let new_global_semantic_tokens_mode =
 5122            all_language_settings(None, cx).defaults.semantic_tokens;
 5123        if self
 5124            .semantic_token_config
 5125            .update_global_mode(new_global_semantic_tokens_mode)
 5126        {
 5127            self.restart_all_language_servers(cx);
 5128        }
 5129
 5130        cx.notify();
 5131    }
 5132
 5133    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 5134        let buffer_store = self.buffer_store.clone();
 5135        let Some(local) = self.as_local_mut() else {
 5136            return;
 5137        };
 5138        let mut adapters = BTreeMap::default();
 5139        let get_adapter = {
 5140            let languages = local.languages.clone();
 5141            let environment = local.environment.clone();
 5142            let weak = local.weak.clone();
 5143            let worktree_store = local.worktree_store.clone();
 5144            let http_client = local.http_client.clone();
 5145            let fs = local.fs.clone();
 5146            move |worktree_id, cx: &mut App| {
 5147                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 5148                Some(LocalLspAdapterDelegate::new(
 5149                    languages.clone(),
 5150                    &environment,
 5151                    weak.clone(),
 5152                    &worktree,
 5153                    http_client.clone(),
 5154                    fs.clone(),
 5155                    cx,
 5156                ))
 5157            }
 5158        };
 5159
 5160        let mut messages_to_report = Vec::new();
 5161        let (new_tree, to_stop) = {
 5162            let mut rebase = local.lsp_tree.rebase();
 5163            let buffers = buffer_store
 5164                .read(cx)
 5165                .buffers()
 5166                .filter_map(|buffer| {
 5167                    let raw_buffer = buffer.read(cx);
 5168                    if !local
 5169                        .registered_buffers
 5170                        .contains_key(&raw_buffer.remote_id())
 5171                    {
 5172                        return None;
 5173                    }
 5174                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5175                    let language = raw_buffer.language().cloned()?;
 5176                    Some((file, language, raw_buffer.remote_id()))
 5177                })
 5178                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5179            for (file, language, buffer_id) in buffers {
 5180                let worktree_id = file.worktree_id(cx);
 5181                let Some(worktree) = local
 5182                    .worktree_store
 5183                    .read(cx)
 5184                    .worktree_for_id(worktree_id, cx)
 5185                else {
 5186                    continue;
 5187                };
 5188
 5189                if let Some((_, apply)) = local.reuse_existing_language_server(
 5190                    rebase.server_tree(),
 5191                    &worktree,
 5192                    &language.name(),
 5193                    cx,
 5194                ) {
 5195                    (apply)(rebase.server_tree());
 5196                } else if let Some(lsp_delegate) = adapters
 5197                    .entry(worktree_id)
 5198                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5199                    .clone()
 5200                {
 5201                    let delegate =
 5202                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5203                    let path = file
 5204                        .path()
 5205                        .parent()
 5206                        .map(Arc::from)
 5207                        .unwrap_or_else(|| file.path().clone());
 5208                    let worktree_path = ProjectPath { worktree_id, path };
 5209                    let abs_path = file.abs_path(cx);
 5210                    let nodes = rebase
 5211                        .walk(
 5212                            worktree_path,
 5213                            language.name(),
 5214                            language.manifest(),
 5215                            delegate.clone(),
 5216                            cx,
 5217                        )
 5218                        .collect::<Vec<_>>();
 5219                    for node in nodes {
 5220                        let server_id = node.server_id_or_init(|disposition| {
 5221                            let path = &disposition.path;
 5222                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5223                            let key = LanguageServerSeed {
 5224                                worktree_id,
 5225                                name: disposition.server_name.clone(),
 5226                                settings: LanguageServerSeedSettings {
 5227                                    binary: disposition.settings.binary.clone(),
 5228                                    initialization_options: disposition
 5229                                        .settings
 5230                                        .initialization_options
 5231                                        .clone(),
 5232                                },
 5233                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5234                                    path.worktree_id,
 5235                                    &path.path,
 5236                                    language.name(),
 5237                                ),
 5238                            };
 5239                            local.language_server_ids.remove(&key);
 5240
 5241                            let server_id = local.get_or_insert_language_server(
 5242                                &worktree,
 5243                                lsp_delegate.clone(),
 5244                                disposition,
 5245                                &language.name(),
 5246                                cx,
 5247                            );
 5248                            if let Some(state) = local.language_servers.get(&server_id)
 5249                                && let Ok(uri) = uri
 5250                            {
 5251                                state.add_workspace_folder(uri);
 5252                            };
 5253                            server_id
 5254                        });
 5255
 5256                        if let Some(language_server_id) = server_id {
 5257                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5258                                language_server_id,
 5259                                name: node.name(),
 5260                                message:
 5261                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5262                                        proto::RegisteredForBuffer {
 5263                                            buffer_abs_path: abs_path
 5264                                                .to_string_lossy()
 5265                                                .into_owned(),
 5266                                            buffer_id: buffer_id.to_proto(),
 5267                                        },
 5268                                    ),
 5269                            });
 5270                        }
 5271                    }
 5272                } else {
 5273                    continue;
 5274                }
 5275            }
 5276            rebase.finish()
 5277        };
 5278        for message in messages_to_report {
 5279            cx.emit(message);
 5280        }
 5281        local.lsp_tree = new_tree;
 5282        for (id, _) in to_stop {
 5283            self.stop_local_language_server(id, cx).detach();
 5284        }
 5285    }
 5286
 5287    pub fn apply_code_action(
 5288        &self,
 5289        buffer_handle: Entity<Buffer>,
 5290        mut action: CodeAction,
 5291        push_to_history: bool,
 5292        cx: &mut Context<Self>,
 5293    ) -> Task<Result<ProjectTransaction>> {
 5294        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5295            let request = proto::ApplyCodeAction {
 5296                project_id,
 5297                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5298                action: Some(Self::serialize_code_action(&action)),
 5299            };
 5300            let buffer_store = self.buffer_store();
 5301            cx.spawn(async move |_, cx| {
 5302                let response = upstream_client
 5303                    .request(request)
 5304                    .await?
 5305                    .transaction
 5306                    .context("missing transaction")?;
 5307
 5308                buffer_store
 5309                    .update(cx, |buffer_store, cx| {
 5310                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5311                    })
 5312                    .await
 5313            })
 5314        } else if self.mode.is_local() {
 5315            let Some((_, lang_server, request_timeout)) = buffer_handle.update(cx, |buffer, cx| {
 5316                let request_timeout = ProjectSettings::get_global(cx)
 5317                    .global_lsp_settings
 5318                    .get_request_timeout();
 5319                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5320                    .map(|(adapter, server)| (adapter.clone(), server.clone(), request_timeout))
 5321            }) else {
 5322                return Task::ready(Ok(ProjectTransaction::default()));
 5323            };
 5324
 5325            cx.spawn(async move |this, cx| {
 5326                LocalLspStore::try_resolve_code_action(&lang_server, &mut action, request_timeout)
 5327                    .await
 5328                    .context("resolving a code action")?;
 5329                if let Some(edit) = action.lsp_action.edit()
 5330                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5331                        return LocalLspStore::deserialize_workspace_edit(
 5332                            this.upgrade().context("no app present")?,
 5333                            edit.clone(),
 5334                            push_to_history,
 5335
 5336                            lang_server.clone(),
 5337                            cx,
 5338                        )
 5339                        .await;
 5340                    }
 5341
 5342                let Some(command) = action.lsp_action.command() else {
 5343                    return Ok(ProjectTransaction::default())
 5344                };
 5345
 5346                let server_capabilities = lang_server.capabilities();
 5347                let available_commands = server_capabilities
 5348                    .execute_command_provider
 5349                    .as_ref()
 5350                    .map(|options| options.commands.as_slice())
 5351                    .unwrap_or_default();
 5352
 5353                if !available_commands.contains(&command.command) {
 5354                    log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5355                    return Ok(ProjectTransaction::default())
 5356                }
 5357
 5358                let request_timeout = cx.update(|app|
 5359                    ProjectSettings::get_global(app)
 5360                    .global_lsp_settings
 5361                    .get_request_timeout()
 5362                );
 5363
 5364                this.update(cx, |this, _| {
 5365                    this.as_local_mut()
 5366                        .unwrap()
 5367                        .last_workspace_edits_by_language_server
 5368                        .remove(&lang_server.server_id());
 5369                })?;
 5370
 5371                let _result = lang_server
 5372                    .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5373                        command: command.command.clone(),
 5374                        arguments: command.arguments.clone().unwrap_or_default(),
 5375                        ..lsp::ExecuteCommandParams::default()
 5376                    }, request_timeout)
 5377                    .await.into_response()
 5378                    .context("execute command")?;
 5379
 5380                return this.update(cx, |this, _| {
 5381                    this.as_local_mut()
 5382                        .unwrap()
 5383                        .last_workspace_edits_by_language_server
 5384                        .remove(&lang_server.server_id())
 5385                        .unwrap_or_default()
 5386                });
 5387            })
 5388        } else {
 5389            Task::ready(Err(anyhow!("no upstream client and not local")))
 5390        }
 5391    }
 5392
 5393    pub fn apply_code_action_kind(
 5394        &mut self,
 5395        buffers: HashSet<Entity<Buffer>>,
 5396        kind: CodeActionKind,
 5397        push_to_history: bool,
 5398        cx: &mut Context<Self>,
 5399    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5400        if self.as_local().is_some() {
 5401            cx.spawn(async move |lsp_store, cx| {
 5402                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5403                let result = LocalLspStore::execute_code_action_kind_locally(
 5404                    lsp_store.clone(),
 5405                    buffers,
 5406                    kind,
 5407                    push_to_history,
 5408                    cx,
 5409                )
 5410                .await;
 5411                lsp_store.update(cx, |lsp_store, _| {
 5412                    lsp_store.update_last_formatting_failure(&result);
 5413                })?;
 5414                result
 5415            })
 5416        } else if let Some((client, project_id)) = self.upstream_client() {
 5417            let buffer_store = self.buffer_store();
 5418            cx.spawn(async move |lsp_store, cx| {
 5419                let result = client
 5420                    .request(proto::ApplyCodeActionKind {
 5421                        project_id,
 5422                        kind: kind.as_str().to_owned(),
 5423                        buffer_ids: buffers
 5424                            .iter()
 5425                            .map(|buffer| {
 5426                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5427                            })
 5428                            .collect(),
 5429                    })
 5430                    .await
 5431                    .and_then(|result| result.transaction.context("missing transaction"));
 5432                lsp_store.update(cx, |lsp_store, _| {
 5433                    lsp_store.update_last_formatting_failure(&result);
 5434                })?;
 5435
 5436                let transaction_response = result?;
 5437                buffer_store
 5438                    .update(cx, |buffer_store, cx| {
 5439                        buffer_store.deserialize_project_transaction(
 5440                            transaction_response,
 5441                            push_to_history,
 5442                            cx,
 5443                        )
 5444                    })
 5445                    .await
 5446            })
 5447        } else {
 5448            Task::ready(Ok(ProjectTransaction::default()))
 5449        }
 5450    }
 5451
 5452    pub fn resolved_hint(
 5453        &mut self,
 5454        buffer_id: BufferId,
 5455        id: InlayId,
 5456        cx: &mut Context<Self>,
 5457    ) -> Option<ResolvedHint> {
 5458        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5459
 5460        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5461        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5462        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5463        let (server_id, resolve_data) = match &hint.resolve_state {
 5464            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5465            ResolveState::Resolving => {
 5466                return Some(ResolvedHint::Resolving(
 5467                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5468                ));
 5469            }
 5470            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5471        };
 5472
 5473        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5474        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5475        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5476            id,
 5477            cx.spawn(async move |lsp_store, cx| {
 5478                let resolved_hint = resolve_task.await;
 5479                lsp_store
 5480                    .update(cx, |lsp_store, _| {
 5481                        if let Some(old_inlay_hint) = lsp_store
 5482                            .lsp_data
 5483                            .get_mut(&buffer_id)
 5484                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5485                        {
 5486                            match resolved_hint {
 5487                                Ok(resolved_hint) => {
 5488                                    *old_inlay_hint = resolved_hint;
 5489                                }
 5490                                Err(e) => {
 5491                                    old_inlay_hint.resolve_state =
 5492                                        ResolveState::CanResolve(server_id, resolve_data);
 5493                                    log::error!("Inlay hint resolve failed: {e:#}");
 5494                                }
 5495                            }
 5496                        }
 5497                    })
 5498                    .ok();
 5499            })
 5500            .shared(),
 5501        );
 5502        debug_assert!(
 5503            previous_task.is_none(),
 5504            "Did not change hint's resolve state after spawning its resolve"
 5505        );
 5506        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5507        None
 5508    }
 5509
 5510    pub(crate) fn linked_edits(
 5511        &mut self,
 5512        buffer: &Entity<Buffer>,
 5513        position: Anchor,
 5514        cx: &mut Context<Self>,
 5515    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5516        let snapshot = buffer.read(cx).snapshot();
 5517        let scope = snapshot.language_scope_at(position);
 5518        let Some(server_id) = self
 5519            .as_local()
 5520            .and_then(|local| {
 5521                buffer.update(cx, |buffer, cx| {
 5522                    local
 5523                        .language_servers_for_buffer(buffer, cx)
 5524                        .filter(|(_, server)| {
 5525                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5526                        })
 5527                        .filter(|(adapter, _)| {
 5528                            scope
 5529                                .as_ref()
 5530                                .map(|scope| scope.language_allowed(&adapter.name))
 5531                                .unwrap_or(true)
 5532                        })
 5533                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5534                        .next()
 5535                })
 5536            })
 5537            .or_else(|| {
 5538                self.upstream_client()
 5539                    .is_some()
 5540                    .then_some(LanguageServerToQuery::FirstCapable)
 5541            })
 5542            .filter(|_| {
 5543                maybe!({
 5544                    let language = buffer.read(cx).language_at(position)?;
 5545                    Some(
 5546                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5547                            .linked_edits,
 5548                    )
 5549                }) == Some(true)
 5550            })
 5551        else {
 5552            return Task::ready(Ok(Vec::new()));
 5553        };
 5554
 5555        self.request_lsp(
 5556            buffer.clone(),
 5557            server_id,
 5558            LinkedEditingRange { position },
 5559            cx,
 5560        )
 5561    }
 5562
 5563    fn apply_on_type_formatting(
 5564        &mut self,
 5565        buffer: Entity<Buffer>,
 5566        position: Anchor,
 5567        trigger: String,
 5568        cx: &mut Context<Self>,
 5569    ) -> Task<Result<Option<Transaction>>> {
 5570        if let Some((client, project_id)) = self.upstream_client() {
 5571            if !self.check_if_capable_for_proto_request(
 5572                &buffer,
 5573                |capabilities| {
 5574                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5575                },
 5576                cx,
 5577            ) {
 5578                return Task::ready(Ok(None));
 5579            }
 5580            let request = proto::OnTypeFormatting {
 5581                project_id,
 5582                buffer_id: buffer.read(cx).remote_id().into(),
 5583                position: Some(serialize_anchor(&position)),
 5584                trigger,
 5585                version: serialize_version(&buffer.read(cx).version()),
 5586            };
 5587            cx.background_spawn(async move {
 5588                client
 5589                    .request(request)
 5590                    .await?
 5591                    .transaction
 5592                    .map(language::proto::deserialize_transaction)
 5593                    .transpose()
 5594            })
 5595        } else if let Some(local) = self.as_local_mut() {
 5596            let buffer_id = buffer.read(cx).remote_id();
 5597            local.buffers_being_formatted.insert(buffer_id);
 5598            cx.spawn(async move |this, cx| {
 5599                let _cleanup = defer({
 5600                    let this = this.clone();
 5601                    let mut cx = cx.clone();
 5602                    move || {
 5603                        this.update(&mut cx, |this, _| {
 5604                            if let Some(local) = this.as_local_mut() {
 5605                                local.buffers_being_formatted.remove(&buffer_id);
 5606                            }
 5607                        })
 5608                        .ok();
 5609                    }
 5610                });
 5611
 5612                buffer
 5613                    .update(cx, |buffer, _| {
 5614                        buffer.wait_for_edits(Some(position.timestamp()))
 5615                    })
 5616                    .await?;
 5617                this.update(cx, |this, cx| {
 5618                    let position = position.to_point_utf16(buffer.read(cx));
 5619                    this.on_type_format(buffer, position, trigger, false, cx)
 5620                })?
 5621                .await
 5622            })
 5623        } else {
 5624            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5625        }
 5626    }
 5627
 5628    pub fn on_type_format<T: ToPointUtf16>(
 5629        &mut self,
 5630        buffer: Entity<Buffer>,
 5631        position: T,
 5632        trigger: String,
 5633        push_to_history: bool,
 5634        cx: &mut Context<Self>,
 5635    ) -> Task<Result<Option<Transaction>>> {
 5636        let position = position.to_point_utf16(buffer.read(cx));
 5637        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5638    }
 5639
 5640    fn on_type_format_impl(
 5641        &mut self,
 5642        buffer: Entity<Buffer>,
 5643        position: PointUtf16,
 5644        trigger: String,
 5645        push_to_history: bool,
 5646        cx: &mut Context<Self>,
 5647    ) -> Task<Result<Option<Transaction>>> {
 5648        let options = buffer.update(cx, |buffer, cx| {
 5649            lsp_command::lsp_formatting_options(
 5650                language_settings(
 5651                    buffer.language_at(position).map(|l| l.name()),
 5652                    buffer.file(),
 5653                    cx,
 5654                )
 5655                .as_ref(),
 5656            )
 5657        });
 5658
 5659        cx.spawn(async move |this, cx| {
 5660            if let Some(waiter) =
 5661                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5662            {
 5663                waiter.await?;
 5664            }
 5665            cx.update(|cx| {
 5666                this.update(cx, |this, cx| {
 5667                    this.request_lsp(
 5668                        buffer.clone(),
 5669                        LanguageServerToQuery::FirstCapable,
 5670                        OnTypeFormatting {
 5671                            position,
 5672                            trigger,
 5673                            options,
 5674                            push_to_history,
 5675                        },
 5676                        cx,
 5677                    )
 5678                })
 5679            })?
 5680            .await
 5681        })
 5682    }
 5683
 5684    pub fn definitions(
 5685        &mut self,
 5686        buffer: &Entity<Buffer>,
 5687        position: PointUtf16,
 5688        cx: &mut Context<Self>,
 5689    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5690        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5691            let request = GetDefinitions { position };
 5692            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5693                return Task::ready(Ok(None));
 5694            }
 5695
 5696            let request_timeout = ProjectSettings::get_global(cx)
 5697                .global_lsp_settings
 5698                .get_request_timeout();
 5699
 5700            let request_task = upstream_client.request_lsp(
 5701                project_id,
 5702                None,
 5703                request_timeout,
 5704                cx.background_executor().clone(),
 5705                request.to_proto(project_id, buffer.read(cx)),
 5706            );
 5707            let buffer = buffer.clone();
 5708            cx.spawn(async move |weak_lsp_store, cx| {
 5709                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5710                    return Ok(None);
 5711                };
 5712                let Some(responses) = request_task.await? else {
 5713                    return Ok(None);
 5714                };
 5715                let actions = join_all(responses.payload.into_iter().map(|response| {
 5716                    GetDefinitions { position }.response_from_proto(
 5717                        response.response,
 5718                        lsp_store.clone(),
 5719                        buffer.clone(),
 5720                        cx.clone(),
 5721                    )
 5722                }))
 5723                .await;
 5724
 5725                Ok(Some(
 5726                    actions
 5727                        .into_iter()
 5728                        .collect::<Result<Vec<Vec<_>>>>()?
 5729                        .into_iter()
 5730                        .flatten()
 5731                        .dedup()
 5732                        .collect(),
 5733                ))
 5734            })
 5735        } else {
 5736            let definitions_task = self.request_multiple_lsp_locally(
 5737                buffer,
 5738                Some(position),
 5739                GetDefinitions { position },
 5740                cx,
 5741            );
 5742            cx.background_spawn(async move {
 5743                Ok(Some(
 5744                    definitions_task
 5745                        .await
 5746                        .into_iter()
 5747                        .flat_map(|(_, definitions)| definitions)
 5748                        .dedup()
 5749                        .collect(),
 5750                ))
 5751            })
 5752        }
 5753    }
 5754
 5755    pub fn declarations(
 5756        &mut self,
 5757        buffer: &Entity<Buffer>,
 5758        position: PointUtf16,
 5759        cx: &mut Context<Self>,
 5760    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5761        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5762            let request = GetDeclarations { position };
 5763            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5764                return Task::ready(Ok(None));
 5765            }
 5766            let request_timeout = ProjectSettings::get_global(cx)
 5767                .global_lsp_settings
 5768                .get_request_timeout();
 5769            let request_task = upstream_client.request_lsp(
 5770                project_id,
 5771                None,
 5772                request_timeout,
 5773                cx.background_executor().clone(),
 5774                request.to_proto(project_id, buffer.read(cx)),
 5775            );
 5776            let buffer = buffer.clone();
 5777            cx.spawn(async move |weak_lsp_store, cx| {
 5778                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5779                    return Ok(None);
 5780                };
 5781                let Some(responses) = request_task.await? else {
 5782                    return Ok(None);
 5783                };
 5784                let actions = join_all(responses.payload.into_iter().map(|response| {
 5785                    GetDeclarations { position }.response_from_proto(
 5786                        response.response,
 5787                        lsp_store.clone(),
 5788                        buffer.clone(),
 5789                        cx.clone(),
 5790                    )
 5791                }))
 5792                .await;
 5793
 5794                Ok(Some(
 5795                    actions
 5796                        .into_iter()
 5797                        .collect::<Result<Vec<Vec<_>>>>()?
 5798                        .into_iter()
 5799                        .flatten()
 5800                        .dedup()
 5801                        .collect(),
 5802                ))
 5803            })
 5804        } else {
 5805            let declarations_task = self.request_multiple_lsp_locally(
 5806                buffer,
 5807                Some(position),
 5808                GetDeclarations { position },
 5809                cx,
 5810            );
 5811            cx.background_spawn(async move {
 5812                Ok(Some(
 5813                    declarations_task
 5814                        .await
 5815                        .into_iter()
 5816                        .flat_map(|(_, declarations)| declarations)
 5817                        .dedup()
 5818                        .collect(),
 5819                ))
 5820            })
 5821        }
 5822    }
 5823
 5824    pub fn type_definitions(
 5825        &mut self,
 5826        buffer: &Entity<Buffer>,
 5827        position: PointUtf16,
 5828        cx: &mut Context<Self>,
 5829    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5830        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5831            let request = GetTypeDefinitions { position };
 5832            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5833                return Task::ready(Ok(None));
 5834            }
 5835            let request_timeout = ProjectSettings::get_global(cx)
 5836                .global_lsp_settings
 5837                .get_request_timeout();
 5838            let request_task = upstream_client.request_lsp(
 5839                project_id,
 5840                None,
 5841                request_timeout,
 5842                cx.background_executor().clone(),
 5843                request.to_proto(project_id, buffer.read(cx)),
 5844            );
 5845            let buffer = buffer.clone();
 5846            cx.spawn(async move |weak_lsp_store, cx| {
 5847                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5848                    return Ok(None);
 5849                };
 5850                let Some(responses) = request_task.await? else {
 5851                    return Ok(None);
 5852                };
 5853                let actions = join_all(responses.payload.into_iter().map(|response| {
 5854                    GetTypeDefinitions { position }.response_from_proto(
 5855                        response.response,
 5856                        lsp_store.clone(),
 5857                        buffer.clone(),
 5858                        cx.clone(),
 5859                    )
 5860                }))
 5861                .await;
 5862
 5863                Ok(Some(
 5864                    actions
 5865                        .into_iter()
 5866                        .collect::<Result<Vec<Vec<_>>>>()?
 5867                        .into_iter()
 5868                        .flatten()
 5869                        .dedup()
 5870                        .collect(),
 5871                ))
 5872            })
 5873        } else {
 5874            let type_definitions_task = self.request_multiple_lsp_locally(
 5875                buffer,
 5876                Some(position),
 5877                GetTypeDefinitions { position },
 5878                cx,
 5879            );
 5880            cx.background_spawn(async move {
 5881                Ok(Some(
 5882                    type_definitions_task
 5883                        .await
 5884                        .into_iter()
 5885                        .flat_map(|(_, type_definitions)| type_definitions)
 5886                        .dedup()
 5887                        .collect(),
 5888                ))
 5889            })
 5890        }
 5891    }
 5892
 5893    pub fn implementations(
 5894        &mut self,
 5895        buffer: &Entity<Buffer>,
 5896        position: PointUtf16,
 5897        cx: &mut Context<Self>,
 5898    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5899        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5900            let request = GetImplementations { position };
 5901            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5902                return Task::ready(Ok(None));
 5903            }
 5904
 5905            let request_timeout = ProjectSettings::get_global(cx)
 5906                .global_lsp_settings
 5907                .get_request_timeout();
 5908            let request_task = upstream_client.request_lsp(
 5909                project_id,
 5910                None,
 5911                request_timeout,
 5912                cx.background_executor().clone(),
 5913                request.to_proto(project_id, buffer.read(cx)),
 5914            );
 5915            let buffer = buffer.clone();
 5916            cx.spawn(async move |weak_lsp_store, cx| {
 5917                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5918                    return Ok(None);
 5919                };
 5920                let Some(responses) = request_task.await? else {
 5921                    return Ok(None);
 5922                };
 5923                let actions = join_all(responses.payload.into_iter().map(|response| {
 5924                    GetImplementations { position }.response_from_proto(
 5925                        response.response,
 5926                        lsp_store.clone(),
 5927                        buffer.clone(),
 5928                        cx.clone(),
 5929                    )
 5930                }))
 5931                .await;
 5932
 5933                Ok(Some(
 5934                    actions
 5935                        .into_iter()
 5936                        .collect::<Result<Vec<Vec<_>>>>()?
 5937                        .into_iter()
 5938                        .flatten()
 5939                        .dedup()
 5940                        .collect(),
 5941                ))
 5942            })
 5943        } else {
 5944            let implementations_task = self.request_multiple_lsp_locally(
 5945                buffer,
 5946                Some(position),
 5947                GetImplementations { position },
 5948                cx,
 5949            );
 5950            cx.background_spawn(async move {
 5951                Ok(Some(
 5952                    implementations_task
 5953                        .await
 5954                        .into_iter()
 5955                        .flat_map(|(_, implementations)| implementations)
 5956                        .dedup()
 5957                        .collect(),
 5958                ))
 5959            })
 5960        }
 5961    }
 5962
 5963    pub fn references(
 5964        &mut self,
 5965        buffer: &Entity<Buffer>,
 5966        position: PointUtf16,
 5967        cx: &mut Context<Self>,
 5968    ) -> Task<Result<Option<Vec<Location>>>> {
 5969        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5970            let request = GetReferences { position };
 5971            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5972                return Task::ready(Ok(None));
 5973            }
 5974
 5975            let request_timeout = ProjectSettings::get_global(cx)
 5976                .global_lsp_settings
 5977                .get_request_timeout();
 5978            let request_task = upstream_client.request_lsp(
 5979                project_id,
 5980                None,
 5981                request_timeout,
 5982                cx.background_executor().clone(),
 5983                request.to_proto(project_id, buffer.read(cx)),
 5984            );
 5985            let buffer = buffer.clone();
 5986            cx.spawn(async move |weak_lsp_store, cx| {
 5987                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5988                    return Ok(None);
 5989                };
 5990                let Some(responses) = request_task.await? else {
 5991                    return Ok(None);
 5992                };
 5993
 5994                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5995                    GetReferences { position }.response_from_proto(
 5996                        lsp_response.response,
 5997                        lsp_store.clone(),
 5998                        buffer.clone(),
 5999                        cx.clone(),
 6000                    )
 6001                }))
 6002                .await
 6003                .into_iter()
 6004                .collect::<Result<Vec<Vec<_>>>>()?
 6005                .into_iter()
 6006                .flatten()
 6007                .dedup()
 6008                .collect();
 6009                Ok(Some(locations))
 6010            })
 6011        } else {
 6012            let references_task = self.request_multiple_lsp_locally(
 6013                buffer,
 6014                Some(position),
 6015                GetReferences { position },
 6016                cx,
 6017            );
 6018            cx.background_spawn(async move {
 6019                Ok(Some(
 6020                    references_task
 6021                        .await
 6022                        .into_iter()
 6023                        .flat_map(|(_, references)| references)
 6024                        .dedup()
 6025                        .collect(),
 6026                ))
 6027            })
 6028        }
 6029    }
 6030
 6031    pub fn code_actions(
 6032        &mut self,
 6033        buffer: &Entity<Buffer>,
 6034        range: Range<Anchor>,
 6035        kinds: Option<Vec<CodeActionKind>>,
 6036        cx: &mut Context<Self>,
 6037    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6038        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6039            let request = GetCodeActions {
 6040                range: range.clone(),
 6041                kinds: kinds.clone(),
 6042            };
 6043            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6044                return Task::ready(Ok(None));
 6045            }
 6046            let request_timeout = ProjectSettings::get_global(cx)
 6047                .global_lsp_settings
 6048                .get_request_timeout();
 6049            let request_task = upstream_client.request_lsp(
 6050                project_id,
 6051                None,
 6052                request_timeout,
 6053                cx.background_executor().clone(),
 6054                request.to_proto(project_id, buffer.read(cx)),
 6055            );
 6056            let buffer = buffer.clone();
 6057            cx.spawn(async move |weak_lsp_store, cx| {
 6058                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6059                    return Ok(None);
 6060                };
 6061                let Some(responses) = request_task.await? else {
 6062                    return Ok(None);
 6063                };
 6064                let actions = join_all(responses.payload.into_iter().map(|response| {
 6065                    GetCodeActions {
 6066                        range: range.clone(),
 6067                        kinds: kinds.clone(),
 6068                    }
 6069                    .response_from_proto(
 6070                        response.response,
 6071                        lsp_store.clone(),
 6072                        buffer.clone(),
 6073                        cx.clone(),
 6074                    )
 6075                }))
 6076                .await;
 6077
 6078                Ok(Some(
 6079                    actions
 6080                        .into_iter()
 6081                        .collect::<Result<Vec<Vec<_>>>>()?
 6082                        .into_iter()
 6083                        .flatten()
 6084                        .collect(),
 6085                ))
 6086            })
 6087        } else {
 6088            let all_actions_task = self.request_multiple_lsp_locally(
 6089                buffer,
 6090                Some(range.start),
 6091                GetCodeActions { range, kinds },
 6092                cx,
 6093            );
 6094            cx.background_spawn(async move {
 6095                Ok(Some(
 6096                    all_actions_task
 6097                        .await
 6098                        .into_iter()
 6099                        .flat_map(|(_, actions)| actions)
 6100                        .collect(),
 6101                ))
 6102            })
 6103        }
 6104    }
 6105
 6106    #[inline(never)]
 6107    pub fn completions(
 6108        &self,
 6109        buffer: &Entity<Buffer>,
 6110        position: PointUtf16,
 6111        context: CompletionContext,
 6112        cx: &mut Context<Self>,
 6113    ) -> Task<Result<Vec<CompletionResponse>>> {
 6114        let language_registry = self.languages.clone();
 6115
 6116        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6117            let snapshot = buffer.read(cx).snapshot();
 6118            let offset = position.to_offset(&snapshot);
 6119            let scope = snapshot.language_scope_at(offset);
 6120            let capable_lsps = self.all_capable_for_proto_request(
 6121                buffer,
 6122                |server_name, capabilities| {
 6123                    capabilities.completion_provider.is_some()
 6124                        && scope
 6125                            .as_ref()
 6126                            .map(|scope| scope.language_allowed(server_name))
 6127                            .unwrap_or(true)
 6128                },
 6129                cx,
 6130            );
 6131            if capable_lsps.is_empty() {
 6132                return Task::ready(Ok(Vec::new()));
 6133            }
 6134
 6135            let language = buffer.read(cx).language().cloned();
 6136
 6137            let buffer = buffer.clone();
 6138
 6139            cx.spawn(async move |this, cx| {
 6140                let requests = join_all(
 6141                    capable_lsps
 6142                        .into_iter()
 6143                        .map(|(id, server_name)| {
 6144                            let request = GetCompletions {
 6145                                position,
 6146                                context: context.clone(),
 6147                                server_id: Some(id),
 6148                            };
 6149                            let buffer = buffer.clone();
 6150                            let language = language.clone();
 6151                            let lsp_adapter = language.as_ref().and_then(|language| {
 6152                                let adapters = language_registry.lsp_adapters(&language.name());
 6153                                adapters
 6154                                    .iter()
 6155                                    .find(|adapter| adapter.name() == server_name)
 6156                                    .or_else(|| adapters.first())
 6157                                    .cloned()
 6158                            });
 6159                            let upstream_client = upstream_client.clone();
 6160                            let response = this
 6161                                .update(cx, |this, cx| {
 6162                                    this.send_lsp_proto_request(
 6163                                        buffer,
 6164                                        upstream_client,
 6165                                        project_id,
 6166                                        request,
 6167                                        cx,
 6168                                    )
 6169                                })
 6170                                .log_err();
 6171                            async move {
 6172                                let response = response?.await.log_err()?;
 6173
 6174                                let completions = populate_labels_for_completions(
 6175                                    response.completions,
 6176                                    language,
 6177                                    lsp_adapter,
 6178                                )
 6179                                .await;
 6180
 6181                                Some(CompletionResponse {
 6182                                    completions,
 6183                                    display_options: CompletionDisplayOptions::default(),
 6184                                    is_incomplete: response.is_incomplete,
 6185                                })
 6186                            }
 6187                        })
 6188                        .collect::<Vec<_>>(),
 6189                );
 6190                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6191            })
 6192        } else if let Some(local) = self.as_local() {
 6193            let snapshot = buffer.read(cx).snapshot();
 6194            let offset = position.to_offset(&snapshot);
 6195            let scope = snapshot.language_scope_at(offset);
 6196            let language = snapshot.language().cloned();
 6197            let completion_settings = language_settings(
 6198                language.as_ref().map(|language| language.name()),
 6199                buffer.read(cx).file(),
 6200                cx,
 6201            )
 6202            .completions
 6203            .clone();
 6204            if !completion_settings.lsp {
 6205                return Task::ready(Ok(Vec::new()));
 6206            }
 6207
 6208            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6209                local
 6210                    .language_servers_for_buffer(buffer, cx)
 6211                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6212                    .filter(|(adapter, _)| {
 6213                        scope
 6214                            .as_ref()
 6215                            .map(|scope| scope.language_allowed(&adapter.name))
 6216                            .unwrap_or(true)
 6217                    })
 6218                    .map(|(_, server)| server.server_id())
 6219                    .collect()
 6220            });
 6221
 6222            let buffer = buffer.clone();
 6223            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6224            let lsp_timeout = if lsp_timeout > 0 {
 6225                Some(Duration::from_millis(lsp_timeout))
 6226            } else {
 6227                None
 6228            };
 6229            cx.spawn(async move |this,  cx| {
 6230                let mut tasks = Vec::with_capacity(server_ids.len());
 6231                this.update(cx, |lsp_store, cx| {
 6232                    for server_id in server_ids {
 6233                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6234                        let lsp_timeout = lsp_timeout
 6235                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6236                        let mut timeout = cx.background_spawn(async move {
 6237                            match lsp_timeout {
 6238                                Some(lsp_timeout) => {
 6239                                    lsp_timeout.await;
 6240                                    true
 6241                                },
 6242                                None => false,
 6243                            }
 6244                        }).fuse();
 6245                        let mut lsp_request = lsp_store.request_lsp(
 6246                            buffer.clone(),
 6247                            LanguageServerToQuery::Other(server_id),
 6248                            GetCompletions {
 6249                                position,
 6250                                context: context.clone(),
 6251                                server_id: Some(server_id),
 6252                            },
 6253                            cx,
 6254                        ).fuse();
 6255                        let new_task = cx.background_spawn(async move {
 6256                            select_biased! {
 6257                                response = lsp_request => anyhow::Ok(Some(response?)),
 6258                                timeout_happened = timeout => {
 6259                                    if timeout_happened {
 6260                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6261                                        Ok(None)
 6262                                    } else {
 6263                                        let completions = lsp_request.await?;
 6264                                        Ok(Some(completions))
 6265                                    }
 6266                                },
 6267                            }
 6268                        });
 6269                        tasks.push((lsp_adapter, new_task));
 6270                    }
 6271                })?;
 6272
 6273                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6274                    let completion_response = task.await.ok()??;
 6275                    let completions = populate_labels_for_completions(
 6276                            completion_response.completions,
 6277                            language.clone(),
 6278                            lsp_adapter,
 6279                        )
 6280                        .await;
 6281                    Some(CompletionResponse {
 6282                        completions,
 6283                        display_options: CompletionDisplayOptions::default(),
 6284                        is_incomplete: completion_response.is_incomplete,
 6285                    })
 6286                });
 6287
 6288                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6289
 6290                Ok(responses.into_iter().flatten().collect())
 6291            })
 6292        } else {
 6293            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6294        }
 6295    }
 6296
 6297    pub fn resolve_completions(
 6298        &self,
 6299        buffer: Entity<Buffer>,
 6300        completion_indices: Vec<usize>,
 6301        completions: Rc<RefCell<Box<[Completion]>>>,
 6302        cx: &mut Context<Self>,
 6303    ) -> Task<Result<bool>> {
 6304        let client = self.upstream_client();
 6305        let buffer_id = buffer.read(cx).remote_id();
 6306        let buffer_snapshot = buffer.read(cx).snapshot();
 6307
 6308        if !self.check_if_capable_for_proto_request(
 6309            &buffer,
 6310            GetCompletions::can_resolve_completions,
 6311            cx,
 6312        ) {
 6313            return Task::ready(Ok(false));
 6314        }
 6315        cx.spawn(async move |lsp_store, cx| {
 6316            let request_timeout = cx.update(|app| {
 6317                ProjectSettings::get_global(app)
 6318                    .global_lsp_settings
 6319                    .get_request_timeout()
 6320            });
 6321
 6322            let mut did_resolve = false;
 6323            if let Some((client, project_id)) = client {
 6324                for completion_index in completion_indices {
 6325                    let server_id = {
 6326                        let completion = &completions.borrow()[completion_index];
 6327                        completion.source.server_id()
 6328                    };
 6329                    if let Some(server_id) = server_id {
 6330                        if Self::resolve_completion_remote(
 6331                            project_id,
 6332                            server_id,
 6333                            buffer_id,
 6334                            completions.clone(),
 6335                            completion_index,
 6336                            client.clone(),
 6337                        )
 6338                        .await
 6339                        .log_err()
 6340                        .is_some()
 6341                        {
 6342                            did_resolve = true;
 6343                        }
 6344                    } else {
 6345                        resolve_word_completion(
 6346                            &buffer_snapshot,
 6347                            &mut completions.borrow_mut()[completion_index],
 6348                        );
 6349                    }
 6350                }
 6351            } else {
 6352                for completion_index in completion_indices {
 6353                    let server_id = {
 6354                        let completion = &completions.borrow()[completion_index];
 6355                        completion.source.server_id()
 6356                    };
 6357                    if let Some(server_id) = server_id {
 6358                        let server_and_adapter = lsp_store
 6359                            .read_with(cx, |lsp_store, _| {
 6360                                let server = lsp_store.language_server_for_id(server_id)?;
 6361                                let adapter =
 6362                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6363                                Some((server, adapter))
 6364                            })
 6365                            .ok()
 6366                            .flatten();
 6367                        let Some((server, adapter)) = server_and_adapter else {
 6368                            continue;
 6369                        };
 6370
 6371                        let resolved = Self::resolve_completion_local(
 6372                            server,
 6373                            completions.clone(),
 6374                            completion_index,
 6375                            request_timeout,
 6376                        )
 6377                        .await
 6378                        .log_err()
 6379                        .is_some();
 6380                        if resolved {
 6381                            Self::regenerate_completion_labels(
 6382                                adapter,
 6383                                &buffer_snapshot,
 6384                                completions.clone(),
 6385                                completion_index,
 6386                            )
 6387                            .await
 6388                            .log_err();
 6389                            did_resolve = true;
 6390                        }
 6391                    } else {
 6392                        resolve_word_completion(
 6393                            &buffer_snapshot,
 6394                            &mut completions.borrow_mut()[completion_index],
 6395                        );
 6396                    }
 6397                }
 6398            }
 6399
 6400            Ok(did_resolve)
 6401        })
 6402    }
 6403
 6404    async fn resolve_completion_local(
 6405        server: Arc<lsp::LanguageServer>,
 6406        completions: Rc<RefCell<Box<[Completion]>>>,
 6407        completion_index: usize,
 6408        request_timeout: Duration,
 6409    ) -> Result<()> {
 6410        let server_id = server.server_id();
 6411        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6412            return Ok(());
 6413        }
 6414
 6415        let request = {
 6416            let completion = &completions.borrow()[completion_index];
 6417            match &completion.source {
 6418                CompletionSource::Lsp {
 6419                    lsp_completion,
 6420                    resolved,
 6421                    server_id: completion_server_id,
 6422                    ..
 6423                } => {
 6424                    if *resolved {
 6425                        return Ok(());
 6426                    }
 6427                    anyhow::ensure!(
 6428                        server_id == *completion_server_id,
 6429                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6430                    );
 6431                    server.request::<lsp::request::ResolveCompletionItem>(
 6432                        *lsp_completion.clone(),
 6433                        request_timeout,
 6434                    )
 6435                }
 6436                CompletionSource::BufferWord { .. }
 6437                | CompletionSource::Dap { .. }
 6438                | CompletionSource::Custom => {
 6439                    return Ok(());
 6440                }
 6441            }
 6442        };
 6443        let resolved_completion = request
 6444            .await
 6445            .into_response()
 6446            .context("resolve completion")?;
 6447
 6448        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6449        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6450
 6451        let mut completions = completions.borrow_mut();
 6452        let completion = &mut completions[completion_index];
 6453        if let CompletionSource::Lsp {
 6454            lsp_completion,
 6455            resolved,
 6456            server_id: completion_server_id,
 6457            ..
 6458        } = &mut completion.source
 6459        {
 6460            if *resolved {
 6461                return Ok(());
 6462            }
 6463            anyhow::ensure!(
 6464                server_id == *completion_server_id,
 6465                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6466            );
 6467            **lsp_completion = resolved_completion;
 6468            *resolved = true;
 6469        }
 6470        Ok(())
 6471    }
 6472
 6473    async fn regenerate_completion_labels(
 6474        adapter: Arc<CachedLspAdapter>,
 6475        snapshot: &BufferSnapshot,
 6476        completions: Rc<RefCell<Box<[Completion]>>>,
 6477        completion_index: usize,
 6478    ) -> Result<()> {
 6479        let completion_item = completions.borrow()[completion_index]
 6480            .source
 6481            .lsp_completion(true)
 6482            .map(Cow::into_owned);
 6483        if let Some(lsp_documentation) = completion_item
 6484            .as_ref()
 6485            .and_then(|completion_item| completion_item.documentation.clone())
 6486        {
 6487            let mut completions = completions.borrow_mut();
 6488            let completion = &mut completions[completion_index];
 6489            completion.documentation = Some(lsp_documentation.into());
 6490        } else {
 6491            let mut completions = completions.borrow_mut();
 6492            let completion = &mut completions[completion_index];
 6493            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6494        }
 6495
 6496        let mut new_label = match completion_item {
 6497            Some(completion_item) => {
 6498                // Some language servers always return `detail` lazily via resolve, regardless of
 6499                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6500                // See: https://github.com/yioneko/vtsls/issues/213
 6501                let language = snapshot.language();
 6502                match language {
 6503                    Some(language) => {
 6504                        adapter
 6505                            .labels_for_completions(
 6506                                std::slice::from_ref(&completion_item),
 6507                                language,
 6508                            )
 6509                            .await?
 6510                    }
 6511                    None => Vec::new(),
 6512                }
 6513                .pop()
 6514                .flatten()
 6515                .unwrap_or_else(|| {
 6516                    CodeLabel::fallback_for_completion(
 6517                        &completion_item,
 6518                        language.map(|language| language.as_ref()),
 6519                    )
 6520                })
 6521            }
 6522            None => CodeLabel::plain(
 6523                completions.borrow()[completion_index].new_text.clone(),
 6524                None,
 6525            ),
 6526        };
 6527        ensure_uniform_list_compatible_label(&mut new_label);
 6528
 6529        let mut completions = completions.borrow_mut();
 6530        let completion = &mut completions[completion_index];
 6531        if completion.label.filter_text() == new_label.filter_text() {
 6532            completion.label = new_label;
 6533        } else {
 6534            log::error!(
 6535                "Resolved completion changed display label from {} to {}. \
 6536                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6537                completion.label.text(),
 6538                new_label.text(),
 6539                completion.label.filter_text(),
 6540                new_label.filter_text()
 6541            );
 6542        }
 6543
 6544        Ok(())
 6545    }
 6546
 6547    async fn resolve_completion_remote(
 6548        project_id: u64,
 6549        server_id: LanguageServerId,
 6550        buffer_id: BufferId,
 6551        completions: Rc<RefCell<Box<[Completion]>>>,
 6552        completion_index: usize,
 6553        client: AnyProtoClient,
 6554    ) -> Result<()> {
 6555        let lsp_completion = {
 6556            let completion = &completions.borrow()[completion_index];
 6557            match &completion.source {
 6558                CompletionSource::Lsp {
 6559                    lsp_completion,
 6560                    resolved,
 6561                    server_id: completion_server_id,
 6562                    ..
 6563                } => {
 6564                    anyhow::ensure!(
 6565                        server_id == *completion_server_id,
 6566                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6567                    );
 6568                    if *resolved {
 6569                        return Ok(());
 6570                    }
 6571                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6572                }
 6573                CompletionSource::Custom
 6574                | CompletionSource::Dap { .. }
 6575                | CompletionSource::BufferWord { .. } => {
 6576                    return Ok(());
 6577                }
 6578            }
 6579        };
 6580        let request = proto::ResolveCompletionDocumentation {
 6581            project_id,
 6582            language_server_id: server_id.0 as u64,
 6583            lsp_completion,
 6584            buffer_id: buffer_id.into(),
 6585        };
 6586
 6587        let response = client
 6588            .request(request)
 6589            .await
 6590            .context("completion documentation resolve proto request")?;
 6591        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6592
 6593        let documentation = if response.documentation.is_empty() {
 6594            CompletionDocumentation::Undocumented
 6595        } else if response.documentation_is_markdown {
 6596            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6597        } else if response.documentation.lines().count() <= 1 {
 6598            CompletionDocumentation::SingleLine(response.documentation.into())
 6599        } else {
 6600            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6601        };
 6602
 6603        let mut completions = completions.borrow_mut();
 6604        let completion = &mut completions[completion_index];
 6605        completion.documentation = Some(documentation);
 6606        if let CompletionSource::Lsp {
 6607            insert_range,
 6608            lsp_completion,
 6609            resolved,
 6610            server_id: completion_server_id,
 6611            lsp_defaults: _,
 6612        } = &mut completion.source
 6613        {
 6614            let completion_insert_range = response
 6615                .old_insert_start
 6616                .and_then(deserialize_anchor)
 6617                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6618            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6619
 6620            if *resolved {
 6621                return Ok(());
 6622            }
 6623            anyhow::ensure!(
 6624                server_id == *completion_server_id,
 6625                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6626            );
 6627            **lsp_completion = resolved_lsp_completion;
 6628            *resolved = true;
 6629        }
 6630
 6631        let replace_range = response
 6632            .old_replace_start
 6633            .and_then(deserialize_anchor)
 6634            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6635        if let Some((old_replace_start, old_replace_end)) = replace_range
 6636            && !response.new_text.is_empty()
 6637        {
 6638            completion.new_text = response.new_text;
 6639            completion.replace_range = old_replace_start..old_replace_end;
 6640        }
 6641
 6642        Ok(())
 6643    }
 6644
 6645    pub fn apply_additional_edits_for_completion(
 6646        &self,
 6647        buffer_handle: Entity<Buffer>,
 6648        completions: Rc<RefCell<Box<[Completion]>>>,
 6649        completion_index: usize,
 6650        push_to_history: bool,
 6651        all_commit_ranges: Vec<Range<language::Anchor>>,
 6652        cx: &mut Context<Self>,
 6653    ) -> Task<Result<Option<Transaction>>> {
 6654        if let Some((client, project_id)) = self.upstream_client() {
 6655            let buffer = buffer_handle.read(cx);
 6656            let buffer_id = buffer.remote_id();
 6657            cx.spawn(async move |_, cx| {
 6658                let request = {
 6659                    let completion = completions.borrow()[completion_index].clone();
 6660                    proto::ApplyCompletionAdditionalEdits {
 6661                        project_id,
 6662                        buffer_id: buffer_id.into(),
 6663                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6664                            replace_range: completion.replace_range,
 6665                            new_text: completion.new_text,
 6666                            source: completion.source,
 6667                        })),
 6668                        all_commit_ranges: all_commit_ranges
 6669                            .iter()
 6670                            .cloned()
 6671                            .map(language::proto::serialize_anchor_range)
 6672                            .collect(),
 6673                    }
 6674                };
 6675
 6676                let Some(transaction) = client.request(request).await?.transaction else {
 6677                    return Ok(None);
 6678                };
 6679
 6680                let transaction = language::proto::deserialize_transaction(transaction)?;
 6681                buffer_handle
 6682                    .update(cx, |buffer, _| {
 6683                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6684                    })
 6685                    .await?;
 6686                if push_to_history {
 6687                    buffer_handle.update(cx, |buffer, _| {
 6688                        buffer.push_transaction(transaction.clone(), Instant::now());
 6689                        buffer.finalize_last_transaction();
 6690                    });
 6691                }
 6692                Ok(Some(transaction))
 6693            })
 6694        } else {
 6695            let request_timeout = ProjectSettings::get_global(cx)
 6696                .global_lsp_settings
 6697                .get_request_timeout();
 6698
 6699            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6700                let completion = &completions.borrow()[completion_index];
 6701                let server_id = completion.source.server_id()?;
 6702                Some(
 6703                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6704                        .1
 6705                        .clone(),
 6706                )
 6707            }) else {
 6708                return Task::ready(Ok(None));
 6709            };
 6710
 6711            cx.spawn(async move |this, cx| {
 6712                Self::resolve_completion_local(
 6713                    server.clone(),
 6714                    completions.clone(),
 6715                    completion_index,
 6716                    request_timeout,
 6717                )
 6718                .await
 6719                .context("resolving completion")?;
 6720                let completion = completions.borrow()[completion_index].clone();
 6721                let additional_text_edits = completion
 6722                    .source
 6723                    .lsp_completion(true)
 6724                    .as_ref()
 6725                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6726                if let Some(edits) = additional_text_edits {
 6727                    let edits = this
 6728                        .update(cx, |this, cx| {
 6729                            this.as_local_mut().unwrap().edits_from_lsp(
 6730                                &buffer_handle,
 6731                                edits,
 6732                                server.server_id(),
 6733                                None,
 6734                                cx,
 6735                            )
 6736                        })?
 6737                        .await?;
 6738
 6739                    buffer_handle.update(cx, |buffer, cx| {
 6740                        buffer.finalize_last_transaction();
 6741                        buffer.start_transaction();
 6742
 6743                        for (range, text) in edits {
 6744                            let primary = &completion.replace_range;
 6745
 6746                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6747                            // and the primary completion is just an insertion (empty range), then this is likely
 6748                            // an auto-import scenario and should not be considered overlapping
 6749                            // https://github.com/zed-industries/zed/issues/26136
 6750                            let is_file_start_auto_import = {
 6751                                let snapshot = buffer.snapshot();
 6752                                let primary_start_point = primary.start.to_point(&snapshot);
 6753                                let range_start_point = range.start.to_point(&snapshot);
 6754
 6755                                let result = primary_start_point.row == 0
 6756                                    && primary_start_point.column == 0
 6757                                    && range_start_point.row == 0
 6758                                    && range_start_point.column == 0;
 6759
 6760                                result
 6761                            };
 6762
 6763                            let has_overlap = if is_file_start_auto_import {
 6764                                false
 6765                            } else {
 6766                                all_commit_ranges.iter().any(|commit_range| {
 6767                                    let start_within =
 6768                                        commit_range.start.cmp(&range.start, buffer).is_le()
 6769                                            && commit_range.end.cmp(&range.start, buffer).is_ge();
 6770                                    let end_within =
 6771                                        range.start.cmp(&commit_range.end, buffer).is_le()
 6772                                            && range.end.cmp(&commit_range.end, buffer).is_ge();
 6773                                    start_within || end_within
 6774                                })
 6775                            };
 6776
 6777                            //Skip additional edits which overlap with the primary completion edit
 6778                            //https://github.com/zed-industries/zed/pull/1871
 6779                            if !has_overlap {
 6780                                buffer.edit([(range, text)], None, cx);
 6781                            }
 6782                        }
 6783
 6784                        let transaction = if buffer.end_transaction(cx).is_some() {
 6785                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6786                            if !push_to_history {
 6787                                buffer.forget_transaction(transaction.id);
 6788                            }
 6789                            Some(transaction)
 6790                        } else {
 6791                            None
 6792                        };
 6793                        Ok(transaction)
 6794                    })
 6795                } else {
 6796                    Ok(None)
 6797                }
 6798            })
 6799        }
 6800    }
 6801
 6802    pub fn pull_diagnostics(
 6803        &mut self,
 6804        buffer: Entity<Buffer>,
 6805        cx: &mut Context<Self>,
 6806    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6807        let buffer_id = buffer.read(cx).remote_id();
 6808
 6809        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6810            let mut suitable_capabilities = None;
 6811            // Are we capable for proto request?
 6812            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6813                &buffer,
 6814                |capabilities| {
 6815                    if let Some(caps) = &capabilities.diagnostic_provider {
 6816                        suitable_capabilities = Some(caps.clone());
 6817                        true
 6818                    } else {
 6819                        false
 6820                    }
 6821                },
 6822                cx,
 6823            );
 6824            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6825            let Some(dynamic_caps) = suitable_capabilities else {
 6826                return Task::ready(Ok(None));
 6827            };
 6828            assert!(any_server_has_diagnostics_provider);
 6829
 6830            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6831            let request = GetDocumentDiagnostics {
 6832                previous_result_id: None,
 6833                identifier,
 6834                registration_id: None,
 6835            };
 6836            let request_timeout = ProjectSettings::get_global(cx)
 6837                .global_lsp_settings
 6838                .get_request_timeout();
 6839            let request_task = client.request_lsp(
 6840                upstream_project_id,
 6841                None,
 6842                request_timeout,
 6843                cx.background_executor().clone(),
 6844                request.to_proto(upstream_project_id, buffer.read(cx)),
 6845            );
 6846            cx.background_spawn(async move {
 6847                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6848                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6849                // Do not attempt to further process the dummy responses here.
 6850                let _response = request_task.await?;
 6851                Ok(None)
 6852            })
 6853        } else {
 6854            let servers = buffer.update(cx, |buffer, cx| {
 6855                self.running_language_servers_for_local_buffer(buffer, cx)
 6856                    .map(|(_, server)| server.clone())
 6857                    .collect::<Vec<_>>()
 6858            });
 6859
 6860            let pull_diagnostics = servers
 6861                .into_iter()
 6862                .flat_map(|server| {
 6863                    let result = maybe!({
 6864                        let local = self.as_local()?;
 6865                        let server_id = server.server_id();
 6866                        let providers_with_identifiers = local
 6867                            .language_server_dynamic_registrations
 6868                            .get(&server_id)
 6869                            .into_iter()
 6870                            .flat_map(|registrations| registrations.diagnostics.clone())
 6871                            .collect::<Vec<_>>();
 6872                        Some(
 6873                            providers_with_identifiers
 6874                                .into_iter()
 6875                                .map(|(registration_id, dynamic_caps)| {
 6876                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6877                                    let registration_id = registration_id.map(SharedString::from);
 6878                                    let result_id = self.result_id_for_buffer_pull(
 6879                                        server_id,
 6880                                        buffer_id,
 6881                                        &registration_id,
 6882                                        cx,
 6883                                    );
 6884                                    self.request_lsp(
 6885                                        buffer.clone(),
 6886                                        LanguageServerToQuery::Other(server_id),
 6887                                        GetDocumentDiagnostics {
 6888                                            previous_result_id: result_id,
 6889                                            registration_id,
 6890                                            identifier,
 6891                                        },
 6892                                        cx,
 6893                                    )
 6894                                })
 6895                                .collect::<Vec<_>>(),
 6896                        )
 6897                    });
 6898
 6899                    result.unwrap_or_default()
 6900                })
 6901                .collect::<Vec<_>>();
 6902
 6903            cx.background_spawn(async move {
 6904                let mut responses = Vec::new();
 6905                for diagnostics in join_all(pull_diagnostics).await {
 6906                    responses.extend(diagnostics?);
 6907                }
 6908                Ok(Some(responses))
 6909            })
 6910        }
 6911    }
 6912
 6913    pub fn applicable_inlay_chunks(
 6914        &mut self,
 6915        buffer: &Entity<Buffer>,
 6916        ranges: &[Range<text::Anchor>],
 6917        cx: &mut Context<Self>,
 6918    ) -> Vec<Range<BufferRow>> {
 6919        let buffer_snapshot = buffer.read(cx).snapshot();
 6920        let ranges = ranges
 6921            .iter()
 6922            .map(|range| range.to_point(&buffer_snapshot))
 6923            .collect::<Vec<_>>();
 6924
 6925        self.latest_lsp_data(buffer, cx)
 6926            .inlay_hints
 6927            .applicable_chunks(ranges.as_slice())
 6928            .map(|chunk| chunk.row_range())
 6929            .collect()
 6930    }
 6931
 6932    pub fn invalidate_inlay_hints<'a>(
 6933        &'a mut self,
 6934        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6935    ) {
 6936        for buffer_id in for_buffers {
 6937            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6938                lsp_data.inlay_hints.clear();
 6939            }
 6940        }
 6941    }
 6942
 6943    pub fn inlay_hints(
 6944        &mut self,
 6945        invalidate: InvalidationStrategy,
 6946        buffer: Entity<Buffer>,
 6947        ranges: Vec<Range<text::Anchor>>,
 6948        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6949        cx: &mut Context<Self>,
 6950    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6951        let next_hint_id = self.next_hint_id.clone();
 6952        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6953        let query_version = lsp_data.buffer_version.clone();
 6954        let mut lsp_refresh_requested = false;
 6955        let for_server = if let InvalidationStrategy::RefreshRequested {
 6956            server_id,
 6957            request_id,
 6958        } = invalidate
 6959        {
 6960            let invalidated = lsp_data
 6961                .inlay_hints
 6962                .invalidate_for_server_refresh(server_id, request_id);
 6963            lsp_refresh_requested = invalidated;
 6964            Some(server_id)
 6965        } else {
 6966            None
 6967        };
 6968        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6969        let known_chunks = known_chunks
 6970            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6971            .map(|(_, known_chunks)| known_chunks)
 6972            .unwrap_or_default();
 6973
 6974        let buffer_snapshot = buffer.read(cx).snapshot();
 6975        let ranges = ranges
 6976            .iter()
 6977            .map(|range| range.to_point(&buffer_snapshot))
 6978            .collect::<Vec<_>>();
 6979
 6980        let mut hint_fetch_tasks = Vec::new();
 6981        let mut cached_inlay_hints = None;
 6982        let mut ranges_to_query = None;
 6983        let applicable_chunks = existing_inlay_hints
 6984            .applicable_chunks(ranges.as_slice())
 6985            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 6986            .collect::<Vec<_>>();
 6987        if applicable_chunks.is_empty() {
 6988            return HashMap::default();
 6989        }
 6990
 6991        for row_chunk in applicable_chunks {
 6992            match (
 6993                existing_inlay_hints
 6994                    .cached_hints(&row_chunk)
 6995                    .filter(|_| !lsp_refresh_requested)
 6996                    .cloned(),
 6997                existing_inlay_hints
 6998                    .fetched_hints(&row_chunk)
 6999                    .as_ref()
 7000                    .filter(|_| !lsp_refresh_requested)
 7001                    .cloned(),
 7002            ) {
 7003                (None, None) => {
 7004                    let chunk_range = row_chunk.anchor_range();
 7005                    ranges_to_query
 7006                        .get_or_insert_with(Vec::new)
 7007                        .push((row_chunk, chunk_range));
 7008                }
 7009                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7010                (Some(cached_hints), None) => {
 7011                    for (server_id, cached_hints) in cached_hints {
 7012                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7013                            cached_inlay_hints
 7014                                .get_or_insert_with(HashMap::default)
 7015                                .entry(row_chunk.row_range())
 7016                                .or_insert_with(HashMap::default)
 7017                                .entry(server_id)
 7018                                .or_insert_with(Vec::new)
 7019                                .extend(cached_hints);
 7020                        }
 7021                    }
 7022                }
 7023                (Some(cached_hints), Some(fetched_hints)) => {
 7024                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7025                    for (server_id, cached_hints) in cached_hints {
 7026                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7027                            cached_inlay_hints
 7028                                .get_or_insert_with(HashMap::default)
 7029                                .entry(row_chunk.row_range())
 7030                                .or_insert_with(HashMap::default)
 7031                                .entry(server_id)
 7032                                .or_insert_with(Vec::new)
 7033                                .extend(cached_hints);
 7034                        }
 7035                    }
 7036                }
 7037            }
 7038        }
 7039
 7040        if hint_fetch_tasks.is_empty()
 7041            && ranges_to_query
 7042                .as_ref()
 7043                .is_none_or(|ranges| ranges.is_empty())
 7044            && let Some(cached_inlay_hints) = cached_inlay_hints
 7045        {
 7046            cached_inlay_hints
 7047                .into_iter()
 7048                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7049                .collect()
 7050        } else {
 7051            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7052                // When a server refresh was requested, other servers' cached hints
 7053                // are unaffected by the refresh and must be included in the result.
 7054                // Otherwise apply_fetched_hints (with should_invalidate()=true)
 7055                // removes all visible hints but only adds back the requesting
 7056                // server's new hints, permanently losing other servers' hints.
 7057                let other_servers_cached: CacheInlayHints = if lsp_refresh_requested {
 7058                    lsp_data
 7059                        .inlay_hints
 7060                        .cached_hints(&chunk)
 7061                        .cloned()
 7062                        .unwrap_or_default()
 7063                } else {
 7064                    HashMap::default()
 7065                };
 7066
 7067                let next_hint_id = next_hint_id.clone();
 7068                let buffer = buffer.clone();
 7069                let query_version = query_version.clone();
 7070                let new_inlay_hints = cx
 7071                    .spawn(async move |lsp_store, cx| {
 7072                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7073                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7074                        })?;
 7075                        new_fetch_task
 7076                            .await
 7077                            .and_then(|new_hints_by_server| {
 7078                                lsp_store.update(cx, |lsp_store, cx| {
 7079                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7080                                    let update_cache = lsp_data.buffer_version == query_version;
 7081                                    if new_hints_by_server.is_empty() {
 7082                                        if update_cache {
 7083                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7084                                        }
 7085                                        other_servers_cached
 7086                                    } else {
 7087                                        let mut result = other_servers_cached;
 7088                                        for (server_id, new_hints) in new_hints_by_server {
 7089                                            let new_hints = new_hints
 7090                                                .into_iter()
 7091                                                .map(|new_hint| {
 7092                                                    (
 7093                                                        InlayId::Hint(next_hint_id.fetch_add(
 7094                                                            1,
 7095                                                            atomic::Ordering::AcqRel,
 7096                                                        )),
 7097                                                        new_hint,
 7098                                                    )
 7099                                                })
 7100                                                .collect::<Vec<_>>();
 7101                                            if update_cache {
 7102                                                lsp_data.inlay_hints.insert_new_hints(
 7103                                                    chunk,
 7104                                                    server_id,
 7105                                                    new_hints.clone(),
 7106                                                );
 7107                                            }
 7108                                            result.insert(server_id, new_hints);
 7109                                        }
 7110                                        result
 7111                                    }
 7112                                })
 7113                            })
 7114                            .map_err(Arc::new)
 7115                    })
 7116                    .shared();
 7117
 7118                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7119                *fetch_task = Some(new_inlay_hints.clone());
 7120                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7121            }
 7122
 7123            cached_inlay_hints
 7124                .unwrap_or_default()
 7125                .into_iter()
 7126                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7127                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7128                    (
 7129                        chunk.row_range(),
 7130                        cx.spawn(async move |_, _| {
 7131                            hints_fetch.await.map_err(|e| {
 7132                                if e.error_code() != ErrorCode::Internal {
 7133                                    anyhow!(e.error_code())
 7134                                } else {
 7135                                    anyhow!("{e:#}")
 7136                                }
 7137                            })
 7138                        }),
 7139                    )
 7140                }))
 7141                .collect()
 7142        }
 7143    }
 7144
 7145    fn fetch_inlay_hints(
 7146        &mut self,
 7147        for_server: Option<LanguageServerId>,
 7148        buffer: &Entity<Buffer>,
 7149        range: Range<Anchor>,
 7150        cx: &mut Context<Self>,
 7151    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7152        let request = InlayHints {
 7153            range: range.clone(),
 7154        };
 7155        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7156            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7157                return Task::ready(Ok(HashMap::default()));
 7158            }
 7159            let request_timeout = ProjectSettings::get_global(cx)
 7160                .global_lsp_settings
 7161                .get_request_timeout();
 7162            let request_task = upstream_client.request_lsp(
 7163                project_id,
 7164                for_server.map(|id| id.to_proto()),
 7165                request_timeout,
 7166                cx.background_executor().clone(),
 7167                request.to_proto(project_id, buffer.read(cx)),
 7168            );
 7169            let buffer = buffer.clone();
 7170            cx.spawn(async move |weak_lsp_store, cx| {
 7171                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7172                    return Ok(HashMap::default());
 7173                };
 7174                let Some(responses) = request_task.await? else {
 7175                    return Ok(HashMap::default());
 7176                };
 7177
 7178                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7179                    let lsp_store = lsp_store.clone();
 7180                    let buffer = buffer.clone();
 7181                    let cx = cx.clone();
 7182                    let request = request.clone();
 7183                    async move {
 7184                        (
 7185                            LanguageServerId::from_proto(response.server_id),
 7186                            request
 7187                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7188                                .await,
 7189                        )
 7190                    }
 7191                }))
 7192                .await;
 7193
 7194                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7195                let mut has_errors = false;
 7196                let inlay_hints = inlay_hints
 7197                    .into_iter()
 7198                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7199                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7200                        Err(e) => {
 7201                            has_errors = true;
 7202                            log::error!("{e:#}");
 7203                            None
 7204                        }
 7205                    })
 7206                    .map(|(server_id, mut new_hints)| {
 7207                        new_hints.retain(|hint| {
 7208                            hint.position.is_valid(&buffer_snapshot)
 7209                                && range.start.is_valid(&buffer_snapshot)
 7210                                && range.end.is_valid(&buffer_snapshot)
 7211                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7212                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7213                        });
 7214                        (server_id, new_hints)
 7215                    })
 7216                    .collect::<HashMap<_, _>>();
 7217                anyhow::ensure!(
 7218                    !has_errors || !inlay_hints.is_empty(),
 7219                    "Failed to fetch inlay hints"
 7220                );
 7221                Ok(inlay_hints)
 7222            })
 7223        } else {
 7224            let inlay_hints_task = match for_server {
 7225                Some(server_id) => {
 7226                    let server_task = self.request_lsp(
 7227                        buffer.clone(),
 7228                        LanguageServerToQuery::Other(server_id),
 7229                        request,
 7230                        cx,
 7231                    );
 7232                    cx.background_spawn(async move {
 7233                        let mut responses = Vec::new();
 7234                        match server_task.await {
 7235                            Ok(response) => responses.push((server_id, response)),
 7236                            // rust-analyzer likes to error with this when its still loading up
 7237                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7238                            Err(e) => log::error!(
 7239                                "Error handling response for inlay hints request: {e:#}"
 7240                            ),
 7241                        }
 7242                        responses
 7243                    })
 7244                }
 7245                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7246            };
 7247            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7248            cx.background_spawn(async move {
 7249                Ok(inlay_hints_task
 7250                    .await
 7251                    .into_iter()
 7252                    .map(|(server_id, mut new_hints)| {
 7253                        new_hints.retain(|hint| {
 7254                            hint.position.is_valid(&buffer_snapshot)
 7255                                && range.start.is_valid(&buffer_snapshot)
 7256                                && range.end.is_valid(&buffer_snapshot)
 7257                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7258                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7259                        });
 7260                        (server_id, new_hints)
 7261                    })
 7262                    .collect())
 7263            })
 7264        }
 7265    }
 7266
 7267    fn diagnostic_registration_exists(
 7268        &self,
 7269        server_id: LanguageServerId,
 7270        registration_id: &Option<SharedString>,
 7271    ) -> bool {
 7272        let Some(local) = self.as_local() else {
 7273            return false;
 7274        };
 7275        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7276        else {
 7277            return false;
 7278        };
 7279        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7280        registrations.diagnostics.contains_key(&registration_key)
 7281    }
 7282
 7283    pub fn pull_diagnostics_for_buffer(
 7284        &mut self,
 7285        buffer: Entity<Buffer>,
 7286        cx: &mut Context<Self>,
 7287    ) -> Task<anyhow::Result<()>> {
 7288        let diagnostics = self.pull_diagnostics(buffer, cx);
 7289        cx.spawn(async move |lsp_store, cx| {
 7290            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7291                return Ok(());
 7292            };
 7293            lsp_store.update(cx, |lsp_store, cx| {
 7294                if lsp_store.as_local().is_none() {
 7295                    return;
 7296                }
 7297
 7298                let mut unchanged_buffers = HashMap::default();
 7299                let server_diagnostics_updates = diagnostics
 7300                    .into_iter()
 7301                    .filter_map(|diagnostics_set| match diagnostics_set {
 7302                        LspPullDiagnostics::Response {
 7303                            server_id,
 7304                            uri,
 7305                            diagnostics,
 7306                            registration_id,
 7307                        } => Some((server_id, uri, diagnostics, registration_id)),
 7308                        LspPullDiagnostics::Default => None,
 7309                    })
 7310                    .filter(|(server_id, _, _, registration_id)| {
 7311                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7312                    })
 7313                    .fold(
 7314                        HashMap::default(),
 7315                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7316                            let (result_id, diagnostics) = match diagnostics {
 7317                                PulledDiagnostics::Unchanged { result_id } => {
 7318                                    unchanged_buffers
 7319                                        .entry(new_registration_id.clone())
 7320                                        .or_insert_with(HashSet::default)
 7321                                        .insert(uri.clone());
 7322                                    (Some(result_id), Vec::new())
 7323                                }
 7324                                PulledDiagnostics::Changed {
 7325                                    result_id,
 7326                                    diagnostics,
 7327                                } => (result_id, diagnostics),
 7328                            };
 7329                            let disk_based_sources = Cow::Owned(
 7330                                lsp_store
 7331                                    .language_server_adapter_for_id(server_id)
 7332                                    .as_ref()
 7333                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7334                                    .unwrap_or(&[])
 7335                                    .to_vec(),
 7336                            );
 7337                            acc.entry(server_id)
 7338                                .or_insert_with(HashMap::default)
 7339                                .entry(new_registration_id.clone())
 7340                                .or_insert_with(Vec::new)
 7341                                .push(DocumentDiagnosticsUpdate {
 7342                                    server_id,
 7343                                    diagnostics: lsp::PublishDiagnosticsParams {
 7344                                        uri,
 7345                                        diagnostics,
 7346                                        version: None,
 7347                                    },
 7348                                    result_id: result_id.map(SharedString::new),
 7349                                    disk_based_sources,
 7350                                    registration_id: new_registration_id,
 7351                                });
 7352                            acc
 7353                        },
 7354                    );
 7355
 7356                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7357                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7358                        lsp_store
 7359                            .merge_lsp_diagnostics(
 7360                                DiagnosticSourceKind::Pulled,
 7361                                diagnostic_updates,
 7362                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7363                                    DiagnosticSourceKind::Pulled => {
 7364                                        old_diagnostic.registration_id != registration_id
 7365                                            || unchanged_buffers
 7366                                                .get(&old_diagnostic.registration_id)
 7367                                                .is_some_and(|unchanged_buffers| {
 7368                                                    unchanged_buffers.contains(&document_uri)
 7369                                                })
 7370                                    }
 7371                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7372                                        true
 7373                                    }
 7374                                },
 7375                                cx,
 7376                            )
 7377                            .log_err();
 7378                    }
 7379                }
 7380            })
 7381        })
 7382    }
 7383
 7384    pub fn signature_help<T: ToPointUtf16>(
 7385        &mut self,
 7386        buffer: &Entity<Buffer>,
 7387        position: T,
 7388        cx: &mut Context<Self>,
 7389    ) -> Task<Option<Vec<SignatureHelp>>> {
 7390        let position = position.to_point_utf16(buffer.read(cx));
 7391
 7392        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7393            let request = GetSignatureHelp { position };
 7394            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7395                return Task::ready(None);
 7396            }
 7397            let request_timeout = ProjectSettings::get_global(cx)
 7398                .global_lsp_settings
 7399                .get_request_timeout();
 7400            let request_task = client.request_lsp(
 7401                upstream_project_id,
 7402                None,
 7403                request_timeout,
 7404                cx.background_executor().clone(),
 7405                request.to_proto(upstream_project_id, buffer.read(cx)),
 7406            );
 7407            let buffer = buffer.clone();
 7408            cx.spawn(async move |weak_lsp_store, cx| {
 7409                let lsp_store = weak_lsp_store.upgrade()?;
 7410                let signatures = join_all(
 7411                    request_task
 7412                        .await
 7413                        .log_err()
 7414                        .flatten()
 7415                        .map(|response| response.payload)
 7416                        .unwrap_or_default()
 7417                        .into_iter()
 7418                        .map(|response| {
 7419                            let response = GetSignatureHelp { position }.response_from_proto(
 7420                                response.response,
 7421                                lsp_store.clone(),
 7422                                buffer.clone(),
 7423                                cx.clone(),
 7424                            );
 7425                            async move { response.await.log_err().flatten() }
 7426                        }),
 7427                )
 7428                .await
 7429                .into_iter()
 7430                .flatten()
 7431                .collect();
 7432                Some(signatures)
 7433            })
 7434        } else {
 7435            let all_actions_task = self.request_multiple_lsp_locally(
 7436                buffer,
 7437                Some(position),
 7438                GetSignatureHelp { position },
 7439                cx,
 7440            );
 7441            cx.background_spawn(async move {
 7442                Some(
 7443                    all_actions_task
 7444                        .await
 7445                        .into_iter()
 7446                        .flat_map(|(_, actions)| actions)
 7447                        .collect::<Vec<_>>(),
 7448                )
 7449            })
 7450        }
 7451    }
 7452
 7453    pub fn hover(
 7454        &mut self,
 7455        buffer: &Entity<Buffer>,
 7456        position: PointUtf16,
 7457        cx: &mut Context<Self>,
 7458    ) -> Task<Option<Vec<Hover>>> {
 7459        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7460            let request = GetHover { position };
 7461            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7462                return Task::ready(None);
 7463            }
 7464            let request_timeout = ProjectSettings::get_global(cx)
 7465                .global_lsp_settings
 7466                .get_request_timeout();
 7467            let request_task = client.request_lsp(
 7468                upstream_project_id,
 7469                None,
 7470                request_timeout,
 7471                cx.background_executor().clone(),
 7472                request.to_proto(upstream_project_id, buffer.read(cx)),
 7473            );
 7474            let buffer = buffer.clone();
 7475            cx.spawn(async move |weak_lsp_store, cx| {
 7476                let lsp_store = weak_lsp_store.upgrade()?;
 7477                let hovers = join_all(
 7478                    request_task
 7479                        .await
 7480                        .log_err()
 7481                        .flatten()
 7482                        .map(|response| response.payload)
 7483                        .unwrap_or_default()
 7484                        .into_iter()
 7485                        .map(|response| {
 7486                            let response = GetHover { position }.response_from_proto(
 7487                                response.response,
 7488                                lsp_store.clone(),
 7489                                buffer.clone(),
 7490                                cx.clone(),
 7491                            );
 7492                            async move {
 7493                                response
 7494                                    .await
 7495                                    .log_err()
 7496                                    .flatten()
 7497                                    .and_then(remove_empty_hover_blocks)
 7498                            }
 7499                        }),
 7500                )
 7501                .await
 7502                .into_iter()
 7503                .flatten()
 7504                .collect();
 7505                Some(hovers)
 7506            })
 7507        } else {
 7508            let all_actions_task = self.request_multiple_lsp_locally(
 7509                buffer,
 7510                Some(position),
 7511                GetHover { position },
 7512                cx,
 7513            );
 7514            cx.background_spawn(async move {
 7515                Some(
 7516                    all_actions_task
 7517                        .await
 7518                        .into_iter()
 7519                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7520                        .collect::<Vec<Hover>>(),
 7521                )
 7522            })
 7523        }
 7524    }
 7525
 7526    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7527        let language_registry = self.languages.clone();
 7528
 7529        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7530            let request = upstream_client.request(proto::GetProjectSymbols {
 7531                project_id: *project_id,
 7532                query: query.to_string(),
 7533            });
 7534            cx.foreground_executor().spawn(async move {
 7535                let response = request.await?;
 7536                let mut symbols = Vec::new();
 7537                let core_symbols = response
 7538                    .symbols
 7539                    .into_iter()
 7540                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7541                    .collect::<Vec<_>>();
 7542                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7543                    .await;
 7544                Ok(symbols)
 7545            })
 7546        } else if let Some(local) = self.as_local() {
 7547            struct WorkspaceSymbolsResult {
 7548                server_id: LanguageServerId,
 7549                lsp_adapter: Arc<CachedLspAdapter>,
 7550                worktree: WeakEntity<Worktree>,
 7551                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7552            }
 7553
 7554            let mut requests = Vec::new();
 7555            let mut requested_servers = BTreeSet::new();
 7556            let request_timeout = ProjectSettings::get_global(cx)
 7557                .global_lsp_settings
 7558                .get_request_timeout();
 7559
 7560            for (seed, state) in local.language_server_ids.iter() {
 7561                let Some(worktree_handle) = self
 7562                    .worktree_store
 7563                    .read(cx)
 7564                    .worktree_for_id(seed.worktree_id, cx)
 7565                else {
 7566                    continue;
 7567                };
 7568
 7569                let worktree = worktree_handle.read(cx);
 7570                if !worktree.is_visible() {
 7571                    continue;
 7572                }
 7573
 7574                if !requested_servers.insert(state.id) {
 7575                    continue;
 7576                }
 7577
 7578                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7579                    Some(LanguageServerState::Running {
 7580                        adapter, server, ..
 7581                    }) => (adapter.clone(), server),
 7582
 7583                    _ => continue,
 7584                };
 7585
 7586                let supports_workspace_symbol_request =
 7587                    match server.capabilities().workspace_symbol_provider {
 7588                        Some(OneOf::Left(supported)) => supported,
 7589                        Some(OneOf::Right(_)) => true,
 7590                        None => false,
 7591                    };
 7592
 7593                if !supports_workspace_symbol_request {
 7594                    continue;
 7595                }
 7596
 7597                let worktree_handle = worktree_handle.clone();
 7598                let server_id = server.server_id();
 7599                requests.push(
 7600                    server
 7601                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7602                            lsp::WorkspaceSymbolParams {
 7603                                query: query.to_string(),
 7604                                ..Default::default()
 7605                            },
 7606                            request_timeout,
 7607                        )
 7608                        .map(move |response| {
 7609                            let lsp_symbols = response
 7610                                .into_response()
 7611                                .context("workspace symbols request")
 7612                                .log_err()
 7613                                .flatten()
 7614                                .map(|symbol_response| match symbol_response {
 7615                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7616                                        flat_responses
 7617                                            .into_iter()
 7618                                            .map(|lsp_symbol| {
 7619                                                (
 7620                                                    lsp_symbol.name,
 7621                                                    lsp_symbol.kind,
 7622                                                    lsp_symbol.location,
 7623                                                    lsp_symbol.container_name,
 7624                                                )
 7625                                            })
 7626                                            .collect::<Vec<_>>()
 7627                                    }
 7628                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7629                                        nested_responses
 7630                                            .into_iter()
 7631                                            .filter_map(|lsp_symbol| {
 7632                                                let location = match lsp_symbol.location {
 7633                                                    OneOf::Left(location) => location,
 7634                                                    OneOf::Right(_) => {
 7635                                                        log::error!(
 7636                                                            "Unexpected: client capabilities \
 7637                                                            forbid symbol resolutions in \
 7638                                                            workspace.symbol.resolveSupport"
 7639                                                        );
 7640                                                        return None;
 7641                                                    }
 7642                                                };
 7643                                                Some((
 7644                                                    lsp_symbol.name,
 7645                                                    lsp_symbol.kind,
 7646                                                    location,
 7647                                                    lsp_symbol.container_name,
 7648                                                ))
 7649                                            })
 7650                                            .collect::<Vec<_>>()
 7651                                    }
 7652                                })
 7653                                .unwrap_or_default();
 7654
 7655                            WorkspaceSymbolsResult {
 7656                                server_id,
 7657                                lsp_adapter,
 7658                                worktree: worktree_handle.downgrade(),
 7659                                lsp_symbols,
 7660                            }
 7661                        }),
 7662                );
 7663            }
 7664
 7665            cx.spawn(async move |this, cx| {
 7666                let responses = futures::future::join_all(requests).await;
 7667                let this = match this.upgrade() {
 7668                    Some(this) => this,
 7669                    None => return Ok(Vec::new()),
 7670                };
 7671
 7672                let mut symbols = Vec::new();
 7673                for result in responses {
 7674                    let core_symbols = this.update(cx, |this, cx| {
 7675                        result
 7676                            .lsp_symbols
 7677                            .into_iter()
 7678                            .filter_map(
 7679                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7680                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7681                                    let source_worktree = result.worktree.upgrade()?;
 7682                                    let source_worktree_id = source_worktree.read(cx).id();
 7683
 7684                                    let path = if let Some((tree, rel_path)) =
 7685                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7686                                    {
 7687                                        let worktree_id = tree.read(cx).id();
 7688                                        SymbolLocation::InProject(ProjectPath {
 7689                                            worktree_id,
 7690                                            path: rel_path,
 7691                                        })
 7692                                    } else {
 7693                                        SymbolLocation::OutsideProject {
 7694                                            signature: this.symbol_signature(&abs_path),
 7695                                            abs_path: abs_path.into(),
 7696                                        }
 7697                                    };
 7698
 7699                                    Some(CoreSymbol {
 7700                                        source_language_server_id: result.server_id,
 7701                                        language_server_name: result.lsp_adapter.name.clone(),
 7702                                        source_worktree_id,
 7703                                        path,
 7704                                        kind: symbol_kind,
 7705                                        name: collapse_newlines(&symbol_name, ""),
 7706                                        range: range_from_lsp(symbol_location.range),
 7707                                        container_name: container_name
 7708                                            .map(|c| collapse_newlines(&c, "")),
 7709                                    })
 7710                                },
 7711                            )
 7712                            .collect::<Vec<_>>()
 7713                    });
 7714
 7715                    populate_labels_for_symbols(
 7716                        core_symbols,
 7717                        &language_registry,
 7718                        Some(result.lsp_adapter),
 7719                        &mut symbols,
 7720                    )
 7721                    .await;
 7722                }
 7723
 7724                Ok(symbols)
 7725            })
 7726        } else {
 7727            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7728        }
 7729    }
 7730
 7731    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7732        let mut summary = DiagnosticSummary::default();
 7733        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7734            summary.error_count += path_summary.error_count;
 7735            summary.warning_count += path_summary.warning_count;
 7736        }
 7737        summary
 7738    }
 7739
 7740    /// Returns the diagnostic summary for a specific project path.
 7741    pub fn diagnostic_summary_for_path(
 7742        &self,
 7743        project_path: &ProjectPath,
 7744        _: &App,
 7745    ) -> DiagnosticSummary {
 7746        if let Some(summaries) = self
 7747            .diagnostic_summaries
 7748            .get(&project_path.worktree_id)
 7749            .and_then(|map| map.get(&project_path.path))
 7750        {
 7751            let (error_count, warning_count) = summaries.iter().fold(
 7752                (0, 0),
 7753                |(error_count, warning_count), (_language_server_id, summary)| {
 7754                    (
 7755                        error_count + summary.error_count,
 7756                        warning_count + summary.warning_count,
 7757                    )
 7758                },
 7759            );
 7760
 7761            DiagnosticSummary {
 7762                error_count,
 7763                warning_count,
 7764            }
 7765        } else {
 7766            DiagnosticSummary::default()
 7767        }
 7768    }
 7769
 7770    pub fn diagnostic_summaries<'a>(
 7771        &'a self,
 7772        include_ignored: bool,
 7773        cx: &'a App,
 7774    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7775        self.worktree_store
 7776            .read(cx)
 7777            .visible_worktrees(cx)
 7778            .filter_map(|worktree| {
 7779                let worktree = worktree.read(cx);
 7780                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7781            })
 7782            .flat_map(move |(worktree, summaries)| {
 7783                let worktree_id = worktree.id();
 7784                summaries
 7785                    .iter()
 7786                    .filter(move |(path, _)| {
 7787                        include_ignored
 7788                            || worktree
 7789                                .entry_for_path(path.as_ref())
 7790                                .is_some_and(|entry| !entry.is_ignored)
 7791                    })
 7792                    .flat_map(move |(path, summaries)| {
 7793                        summaries.iter().map(move |(server_id, summary)| {
 7794                            (
 7795                                ProjectPath {
 7796                                    worktree_id,
 7797                                    path: path.clone(),
 7798                                },
 7799                                *server_id,
 7800                                *summary,
 7801                            )
 7802                        })
 7803                    })
 7804            })
 7805    }
 7806
 7807    pub fn on_buffer_edited(
 7808        &mut self,
 7809        buffer: Entity<Buffer>,
 7810        cx: &mut Context<Self>,
 7811    ) -> Option<()> {
 7812        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7813            Some(
 7814                self.as_local()?
 7815                    .language_servers_for_buffer(buffer, cx)
 7816                    .map(|i| i.1.clone())
 7817                    .collect(),
 7818            )
 7819        })?;
 7820
 7821        let buffer = buffer.read(cx);
 7822        let file = File::from_dyn(buffer.file())?;
 7823        let abs_path = file.as_local()?.abs_path(cx);
 7824        let uri = lsp::Uri::from_file_path(&abs_path)
 7825            .ok()
 7826            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7827            .log_err()?;
 7828        let next_snapshot = buffer.text_snapshot();
 7829        for language_server in language_servers {
 7830            let language_server = language_server.clone();
 7831
 7832            let buffer_snapshots = self
 7833                .as_local_mut()?
 7834                .buffer_snapshots
 7835                .get_mut(&buffer.remote_id())
 7836                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7837            let previous_snapshot = buffer_snapshots.last()?;
 7838
 7839            let build_incremental_change = || {
 7840                buffer
 7841                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7842                        previous_snapshot.snapshot.version(),
 7843                    )
 7844                    .map(|edit| {
 7845                        let edit_start = edit.new.start.0;
 7846                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7847                        let new_text = next_snapshot
 7848                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7849                            .collect();
 7850                        lsp::TextDocumentContentChangeEvent {
 7851                            range: Some(lsp::Range::new(
 7852                                point_to_lsp(edit_start),
 7853                                point_to_lsp(edit_end),
 7854                            )),
 7855                            range_length: None,
 7856                            text: new_text,
 7857                        }
 7858                    })
 7859                    .collect()
 7860            };
 7861
 7862            let document_sync_kind = language_server
 7863                .capabilities()
 7864                .text_document_sync
 7865                .as_ref()
 7866                .and_then(|sync| match sync {
 7867                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7868                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7869                });
 7870
 7871            let content_changes: Vec<_> = match document_sync_kind {
 7872                Some(lsp::TextDocumentSyncKind::FULL) => {
 7873                    vec![lsp::TextDocumentContentChangeEvent {
 7874                        range: None,
 7875                        range_length: None,
 7876                        text: next_snapshot.text(),
 7877                    }]
 7878                }
 7879                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7880                _ => {
 7881                    #[cfg(any(test, feature = "test-support"))]
 7882                    {
 7883                        build_incremental_change()
 7884                    }
 7885
 7886                    #[cfg(not(any(test, feature = "test-support")))]
 7887                    {
 7888                        continue;
 7889                    }
 7890                }
 7891            };
 7892
 7893            let next_version = previous_snapshot.version + 1;
 7894            buffer_snapshots.push(LspBufferSnapshot {
 7895                version: next_version,
 7896                snapshot: next_snapshot.clone(),
 7897            });
 7898
 7899            language_server
 7900                .notify::<lsp::notification::DidChangeTextDocument>(
 7901                    lsp::DidChangeTextDocumentParams {
 7902                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7903                            uri.clone(),
 7904                            next_version,
 7905                        ),
 7906                        content_changes,
 7907                    },
 7908                )
 7909                .ok();
 7910            self.pull_workspace_diagnostics(language_server.server_id());
 7911        }
 7912
 7913        None
 7914    }
 7915
 7916    pub fn on_buffer_saved(
 7917        &mut self,
 7918        buffer: Entity<Buffer>,
 7919        cx: &mut Context<Self>,
 7920    ) -> Option<()> {
 7921        let file = File::from_dyn(buffer.read(cx).file())?;
 7922        let worktree_id = file.worktree_id(cx);
 7923        let abs_path = file.as_local()?.abs_path(cx);
 7924        let text_document = lsp::TextDocumentIdentifier {
 7925            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7926        };
 7927        let local = self.as_local()?;
 7928
 7929        for server in local.language_servers_for_worktree(worktree_id) {
 7930            if let Some(include_text) = include_text(server.as_ref()) {
 7931                let text = if include_text {
 7932                    Some(buffer.read(cx).text())
 7933                } else {
 7934                    None
 7935                };
 7936                server
 7937                    .notify::<lsp::notification::DidSaveTextDocument>(
 7938                        lsp::DidSaveTextDocumentParams {
 7939                            text_document: text_document.clone(),
 7940                            text,
 7941                        },
 7942                    )
 7943                    .ok();
 7944            }
 7945        }
 7946
 7947        let language_servers = buffer.update(cx, |buffer, cx| {
 7948            local.language_server_ids_for_buffer(buffer, cx)
 7949        });
 7950        for language_server_id in language_servers {
 7951            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7952        }
 7953
 7954        None
 7955    }
 7956
 7957    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7958        maybe!(async move {
 7959            let mut refreshed_servers = HashSet::default();
 7960            let servers = lsp_store
 7961                .update(cx, |lsp_store, cx| {
 7962                    let local = lsp_store.as_local()?;
 7963
 7964                    let servers = local
 7965                        .language_server_ids
 7966                        .iter()
 7967                        .filter_map(|(seed, state)| {
 7968                            let worktree = lsp_store
 7969                                .worktree_store
 7970                                .read(cx)
 7971                                .worktree_for_id(seed.worktree_id, cx);
 7972                            let delegate: Arc<dyn LspAdapterDelegate> =
 7973                                worktree.map(|worktree| {
 7974                                    LocalLspAdapterDelegate::new(
 7975                                        local.languages.clone(),
 7976                                        &local.environment,
 7977                                        cx.weak_entity(),
 7978                                        &worktree,
 7979                                        local.http_client.clone(),
 7980                                        local.fs.clone(),
 7981                                        cx,
 7982                                    )
 7983                                })?;
 7984                            let server_id = state.id;
 7985
 7986                            let states = local.language_servers.get(&server_id)?;
 7987
 7988                            match states {
 7989                                LanguageServerState::Starting { .. } => None,
 7990                                LanguageServerState::Running {
 7991                                    adapter, server, ..
 7992                                } => {
 7993                                    let adapter = adapter.clone();
 7994                                    let server = server.clone();
 7995                                    refreshed_servers.insert(server.name());
 7996                                    let toolchain = seed.toolchain.clone();
 7997                                    Some(cx.spawn(async move |_, cx| {
 7998                                        let settings =
 7999                                            LocalLspStore::workspace_configuration_for_adapter(
 8000                                                adapter.adapter.clone(),
 8001                                                &delegate,
 8002                                                toolchain,
 8003                                                None,
 8004                                                cx,
 8005                                            )
 8006                                            .await
 8007                                            .ok()?;
 8008                                        server
 8009                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8010                                                lsp::DidChangeConfigurationParams { settings },
 8011                                            )
 8012                                            .ok()?;
 8013                                        Some(())
 8014                                    }))
 8015                                }
 8016                            }
 8017                        })
 8018                        .collect::<Vec<_>>();
 8019
 8020                    Some(servers)
 8021                })
 8022                .ok()
 8023                .flatten()?;
 8024
 8025            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8026            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8027            // to stop and unregister its language server wrapper.
 8028            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8029            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8030            let _: Vec<Option<()>> = join_all(servers).await;
 8031
 8032            Some(())
 8033        })
 8034        .await;
 8035    }
 8036
 8037    fn maintain_workspace_config(
 8038        external_refresh_requests: watch::Receiver<()>,
 8039        cx: &mut Context<Self>,
 8040    ) -> Task<Result<()>> {
 8041        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8042        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8043
 8044        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8045            *settings_changed_tx.borrow_mut() = ();
 8046        });
 8047
 8048        let mut joint_future =
 8049            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8050        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8051        // - 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).
 8052        // - 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.
 8053        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8054        // - 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,
 8055        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8056        cx.spawn(async move |this, cx| {
 8057            while let Some(()) = joint_future.next().await {
 8058                this.update(cx, |this, cx| {
 8059                    this.refresh_server_tree(cx);
 8060                })
 8061                .ok();
 8062
 8063                Self::refresh_workspace_configurations(&this, cx).await;
 8064            }
 8065
 8066            drop(settings_observation);
 8067            anyhow::Ok(())
 8068        })
 8069    }
 8070
 8071    pub fn running_language_servers_for_local_buffer<'a>(
 8072        &'a self,
 8073        buffer: &Buffer,
 8074        cx: &mut App,
 8075    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8076        let local = self.as_local();
 8077        let language_server_ids = local
 8078            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8079            .unwrap_or_default();
 8080
 8081        language_server_ids
 8082            .into_iter()
 8083            .filter_map(
 8084                move |server_id| match local?.language_servers.get(&server_id)? {
 8085                    LanguageServerState::Running {
 8086                        adapter, server, ..
 8087                    } => Some((adapter, server)),
 8088                    _ => None,
 8089                },
 8090            )
 8091    }
 8092
 8093    pub fn language_servers_for_local_buffer(
 8094        &self,
 8095        buffer: &Buffer,
 8096        cx: &mut App,
 8097    ) -> Vec<LanguageServerId> {
 8098        let local = self.as_local();
 8099        local
 8100            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8101            .unwrap_or_default()
 8102    }
 8103
 8104    pub fn language_server_for_local_buffer<'a>(
 8105        &'a self,
 8106        buffer: &'a Buffer,
 8107        server_id: LanguageServerId,
 8108        cx: &'a mut App,
 8109    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8110        self.as_local()?
 8111            .language_servers_for_buffer(buffer, cx)
 8112            .find(|(_, s)| s.server_id() == server_id)
 8113    }
 8114
 8115    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8116        self.diagnostic_summaries.remove(&id_to_remove);
 8117        if let Some(local) = self.as_local_mut() {
 8118            let to_remove = local.remove_worktree(id_to_remove, cx);
 8119            for server in to_remove {
 8120                self.language_server_statuses.remove(&server);
 8121            }
 8122        }
 8123    }
 8124
 8125    pub fn shared(
 8126        &mut self,
 8127        project_id: u64,
 8128        downstream_client: AnyProtoClient,
 8129        _: &mut Context<Self>,
 8130    ) {
 8131        self.downstream_client = Some((downstream_client.clone(), project_id));
 8132
 8133        for (server_id, status) in &self.language_server_statuses {
 8134            if let Some(server) = self.language_server_for_id(*server_id) {
 8135                downstream_client
 8136                    .send(proto::StartLanguageServer {
 8137                        project_id,
 8138                        server: Some(proto::LanguageServer {
 8139                            id: server_id.to_proto(),
 8140                            name: status.name.to_string(),
 8141                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8142                        }),
 8143                        capabilities: serde_json::to_string(&server.capabilities())
 8144                            .expect("serializing server LSP capabilities"),
 8145                    })
 8146                    .log_err();
 8147            }
 8148        }
 8149    }
 8150
 8151    pub fn disconnected_from_host(&mut self) {
 8152        self.downstream_client.take();
 8153    }
 8154
 8155    pub fn disconnected_from_ssh_remote(&mut self) {
 8156        if let LspStoreMode::Remote(RemoteLspStore {
 8157            upstream_client, ..
 8158        }) = &mut self.mode
 8159        {
 8160            upstream_client.take();
 8161        }
 8162    }
 8163
 8164    pub(crate) fn set_language_server_statuses_from_proto(
 8165        &mut self,
 8166        project: WeakEntity<Project>,
 8167        language_servers: Vec<proto::LanguageServer>,
 8168        server_capabilities: Vec<String>,
 8169        cx: &mut Context<Self>,
 8170    ) {
 8171        let lsp_logs = cx
 8172            .try_global::<GlobalLogStore>()
 8173            .map(|lsp_store| lsp_store.0.clone());
 8174
 8175        self.language_server_statuses = language_servers
 8176            .into_iter()
 8177            .zip(server_capabilities)
 8178            .map(|(server, server_capabilities)| {
 8179                let server_id = LanguageServerId(server.id as usize);
 8180                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8181                    self.lsp_server_capabilities
 8182                        .insert(server_id, server_capabilities);
 8183                }
 8184
 8185                let name = LanguageServerName::from_proto(server.name);
 8186                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8187
 8188                if let Some(lsp_logs) = &lsp_logs {
 8189                    lsp_logs.update(cx, |lsp_logs, cx| {
 8190                        lsp_logs.add_language_server(
 8191                            // Only remote clients get their language servers set from proto
 8192                            LanguageServerKind::Remote {
 8193                                project: project.clone(),
 8194                            },
 8195                            server_id,
 8196                            Some(name.clone()),
 8197                            worktree,
 8198                            None,
 8199                            cx,
 8200                        );
 8201                    });
 8202                }
 8203
 8204                (
 8205                    server_id,
 8206                    LanguageServerStatus {
 8207                        name,
 8208                        server_version: None,
 8209                        server_readable_version: None,
 8210                        pending_work: Default::default(),
 8211                        has_pending_diagnostic_updates: false,
 8212                        progress_tokens: Default::default(),
 8213                        worktree,
 8214                        binary: None,
 8215                        configuration: None,
 8216                        workspace_folders: BTreeSet::new(),
 8217                        process_id: None,
 8218                    },
 8219                )
 8220            })
 8221            .collect();
 8222    }
 8223
 8224    #[cfg(feature = "test-support")]
 8225    pub fn update_diagnostic_entries(
 8226        &mut self,
 8227        server_id: LanguageServerId,
 8228        abs_path: PathBuf,
 8229        result_id: Option<SharedString>,
 8230        version: Option<i32>,
 8231        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8232        cx: &mut Context<Self>,
 8233    ) -> anyhow::Result<()> {
 8234        self.merge_diagnostic_entries(
 8235            vec![DocumentDiagnosticsUpdate {
 8236                diagnostics: DocumentDiagnostics {
 8237                    diagnostics,
 8238                    document_abs_path: abs_path,
 8239                    version,
 8240                },
 8241                result_id,
 8242                server_id,
 8243                disk_based_sources: Cow::Borrowed(&[]),
 8244                registration_id: None,
 8245            }],
 8246            |_, _, _| false,
 8247            cx,
 8248        )?;
 8249        Ok(())
 8250    }
 8251
 8252    pub fn merge_diagnostic_entries<'a>(
 8253        &mut self,
 8254        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8255        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8256        cx: &mut Context<Self>,
 8257    ) -> anyhow::Result<()> {
 8258        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8259        let mut updated_diagnostics_paths = HashMap::default();
 8260        for mut update in diagnostic_updates {
 8261            let abs_path = &update.diagnostics.document_abs_path;
 8262            let server_id = update.server_id;
 8263            let Some((worktree, relative_path)) =
 8264                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8265            else {
 8266                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8267                return Ok(());
 8268            };
 8269
 8270            let worktree_id = worktree.read(cx).id();
 8271            let project_path = ProjectPath {
 8272                worktree_id,
 8273                path: relative_path,
 8274            };
 8275
 8276            let document_uri = lsp::Uri::from_file_path(abs_path)
 8277                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8278            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8279                let snapshot = buffer_handle.read(cx).snapshot();
 8280                let buffer = buffer_handle.read(cx);
 8281                let reused_diagnostics = buffer
 8282                    .buffer_diagnostics(Some(server_id))
 8283                    .iter()
 8284                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8285                    .map(|v| {
 8286                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8287                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8288                        DiagnosticEntry {
 8289                            range: start..end,
 8290                            diagnostic: v.diagnostic.clone(),
 8291                        }
 8292                    })
 8293                    .collect::<Vec<_>>();
 8294
 8295                self.as_local_mut()
 8296                    .context("cannot merge diagnostics on a remote LspStore")?
 8297                    .update_buffer_diagnostics(
 8298                        &buffer_handle,
 8299                        server_id,
 8300                        Some(update.registration_id),
 8301                        update.result_id,
 8302                        update.diagnostics.version,
 8303                        update.diagnostics.diagnostics.clone(),
 8304                        reused_diagnostics.clone(),
 8305                        cx,
 8306                    )?;
 8307
 8308                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8309            } else if let Some(local) = self.as_local() {
 8310                let reused_diagnostics = local
 8311                    .diagnostics
 8312                    .get(&worktree_id)
 8313                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8314                    .and_then(|diagnostics_by_server_id| {
 8315                        diagnostics_by_server_id
 8316                            .binary_search_by_key(&server_id, |e| e.0)
 8317                            .ok()
 8318                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8319                    })
 8320                    .into_iter()
 8321                    .flatten()
 8322                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8323
 8324                update
 8325                    .diagnostics
 8326                    .diagnostics
 8327                    .extend(reused_diagnostics.cloned());
 8328            }
 8329
 8330            let updated = worktree.update(cx, |worktree, cx| {
 8331                self.update_worktree_diagnostics(
 8332                    worktree.id(),
 8333                    server_id,
 8334                    project_path.path.clone(),
 8335                    update.diagnostics.diagnostics,
 8336                    cx,
 8337                )
 8338            })?;
 8339            match updated {
 8340                ControlFlow::Continue(new_summary) => {
 8341                    if let Some((project_id, new_summary)) = new_summary {
 8342                        match &mut diagnostics_summary {
 8343                            Some(diagnostics_summary) => {
 8344                                diagnostics_summary
 8345                                    .more_summaries
 8346                                    .push(proto::DiagnosticSummary {
 8347                                        path: project_path.path.as_ref().to_proto(),
 8348                                        language_server_id: server_id.0 as u64,
 8349                                        error_count: new_summary.error_count,
 8350                                        warning_count: new_summary.warning_count,
 8351                                    })
 8352                            }
 8353                            None => {
 8354                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8355                                    project_id,
 8356                                    worktree_id: worktree_id.to_proto(),
 8357                                    summary: Some(proto::DiagnosticSummary {
 8358                                        path: project_path.path.as_ref().to_proto(),
 8359                                        language_server_id: server_id.0 as u64,
 8360                                        error_count: new_summary.error_count,
 8361                                        warning_count: new_summary.warning_count,
 8362                                    }),
 8363                                    more_summaries: Vec::new(),
 8364                                })
 8365                            }
 8366                        }
 8367                    }
 8368                    updated_diagnostics_paths
 8369                        .entry(server_id)
 8370                        .or_insert_with(Vec::new)
 8371                        .push(project_path);
 8372                }
 8373                ControlFlow::Break(()) => {}
 8374            }
 8375        }
 8376
 8377        if let Some((diagnostics_summary, (downstream_client, _))) =
 8378            diagnostics_summary.zip(self.downstream_client.as_ref())
 8379        {
 8380            downstream_client.send(diagnostics_summary).log_err();
 8381        }
 8382        for (server_id, paths) in updated_diagnostics_paths {
 8383            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8384        }
 8385        Ok(())
 8386    }
 8387
 8388    fn update_worktree_diagnostics(
 8389        &mut self,
 8390        worktree_id: WorktreeId,
 8391        server_id: LanguageServerId,
 8392        path_in_worktree: Arc<RelPath>,
 8393        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8394        _: &mut Context<Worktree>,
 8395    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8396        let local = match &mut self.mode {
 8397            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8398            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8399        };
 8400
 8401        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8402        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8403        let summaries_by_server_id = summaries_for_tree
 8404            .entry(path_in_worktree.clone())
 8405            .or_default();
 8406
 8407        let old_summary = summaries_by_server_id
 8408            .remove(&server_id)
 8409            .unwrap_or_default();
 8410
 8411        let new_summary = DiagnosticSummary::new(&diagnostics);
 8412        if diagnostics.is_empty() {
 8413            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8414            {
 8415                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8416                    diagnostics_by_server_id.remove(ix);
 8417                }
 8418                if diagnostics_by_server_id.is_empty() {
 8419                    diagnostics_for_tree.remove(&path_in_worktree);
 8420                }
 8421            }
 8422        } else {
 8423            summaries_by_server_id.insert(server_id, new_summary);
 8424            let diagnostics_by_server_id = diagnostics_for_tree
 8425                .entry(path_in_worktree.clone())
 8426                .or_default();
 8427            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8428                Ok(ix) => {
 8429                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8430                }
 8431                Err(ix) => {
 8432                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8433                }
 8434            }
 8435        }
 8436
 8437        if !old_summary.is_empty() || !new_summary.is_empty() {
 8438            if let Some((_, project_id)) = &self.downstream_client {
 8439                Ok(ControlFlow::Continue(Some((
 8440                    *project_id,
 8441                    proto::DiagnosticSummary {
 8442                        path: path_in_worktree.to_proto(),
 8443                        language_server_id: server_id.0 as u64,
 8444                        error_count: new_summary.error_count as u32,
 8445                        warning_count: new_summary.warning_count as u32,
 8446                    },
 8447                ))))
 8448            } else {
 8449                Ok(ControlFlow::Continue(None))
 8450            }
 8451        } else {
 8452            Ok(ControlFlow::Break(()))
 8453        }
 8454    }
 8455
 8456    pub fn open_buffer_for_symbol(
 8457        &mut self,
 8458        symbol: &Symbol,
 8459        cx: &mut Context<Self>,
 8460    ) -> Task<Result<Entity<Buffer>>> {
 8461        if let Some((client, project_id)) = self.upstream_client() {
 8462            let request = client.request(proto::OpenBufferForSymbol {
 8463                project_id,
 8464                symbol: Some(Self::serialize_symbol(symbol)),
 8465            });
 8466            cx.spawn(async move |this, cx| {
 8467                let response = request.await?;
 8468                let buffer_id = BufferId::new(response.buffer_id)?;
 8469                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8470                    .await
 8471            })
 8472        } else if let Some(local) = self.as_local() {
 8473            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8474                seed.worktree_id == symbol.source_worktree_id
 8475                    && state.id == symbol.source_language_server_id
 8476                    && symbol.language_server_name == seed.name
 8477            });
 8478            if !is_valid {
 8479                return Task::ready(Err(anyhow!(
 8480                    "language server for worktree and language not found"
 8481                )));
 8482            };
 8483
 8484            let symbol_abs_path = match &symbol.path {
 8485                SymbolLocation::InProject(project_path) => self
 8486                    .worktree_store
 8487                    .read(cx)
 8488                    .absolutize(&project_path, cx)
 8489                    .context("no such worktree"),
 8490                SymbolLocation::OutsideProject {
 8491                    abs_path,
 8492                    signature: _,
 8493                } => Ok(abs_path.to_path_buf()),
 8494            };
 8495            let symbol_abs_path = match symbol_abs_path {
 8496                Ok(abs_path) => abs_path,
 8497                Err(err) => return Task::ready(Err(err)),
 8498            };
 8499            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8500                uri
 8501            } else {
 8502                return Task::ready(Err(anyhow!("invalid symbol path")));
 8503            };
 8504
 8505            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8506        } else {
 8507            Task::ready(Err(anyhow!("no upstream client or local store")))
 8508        }
 8509    }
 8510
 8511    pub(crate) fn open_local_buffer_via_lsp(
 8512        &mut self,
 8513        abs_path: lsp::Uri,
 8514        language_server_id: LanguageServerId,
 8515        cx: &mut Context<Self>,
 8516    ) -> Task<Result<Entity<Buffer>>> {
 8517        let path_style = self.worktree_store.read(cx).path_style();
 8518        cx.spawn(async move |lsp_store, cx| {
 8519            // Escape percent-encoded string.
 8520            let current_scheme = abs_path.scheme().to_owned();
 8521            // Uri is immutable, so we can't modify the scheme
 8522
 8523            let abs_path = abs_path
 8524                .to_file_path_ext(path_style)
 8525                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8526            let p = abs_path.clone();
 8527            let yarn_worktree = lsp_store
 8528                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8529                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8530                        cx.spawn(async move |this, cx| {
 8531                            let t = this
 8532                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8533                                .ok()?;
 8534                            t.await
 8535                        })
 8536                    }),
 8537                    None => Task::ready(None),
 8538                })?
 8539                .await;
 8540            let (worktree_root_target, known_relative_path) =
 8541                if let Some((zip_root, relative_path)) = yarn_worktree {
 8542                    (zip_root, Some(relative_path))
 8543                } else {
 8544                    (Arc::<Path>::from(abs_path.as_path()), None)
 8545                };
 8546            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8547                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8548                    worktree_store.find_worktree(&worktree_root_target, cx)
 8549                })
 8550            })?;
 8551            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8552                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8553                (result.0, relative_path, None)
 8554            } else {
 8555                let worktree = lsp_store
 8556                    .update(cx, |lsp_store, cx| {
 8557                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8558                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8559                        })
 8560                    })?
 8561                    .await?;
 8562                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8563                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8564                    lsp_store
 8565                        .update(cx, |lsp_store, cx| {
 8566                            if let Some(local) = lsp_store.as_local_mut() {
 8567                                local.register_language_server_for_invisible_worktree(
 8568                                    &worktree,
 8569                                    language_server_id,
 8570                                    cx,
 8571                                )
 8572                            }
 8573                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8574                                Some(status) => status.worktree,
 8575                                None => None,
 8576                            }
 8577                        })
 8578                        .ok()
 8579                        .flatten()
 8580                        .zip(Some(worktree_root.clone()))
 8581                } else {
 8582                    None
 8583                };
 8584                let relative_path = if let Some(known_path) = known_relative_path {
 8585                    known_path
 8586                } else {
 8587                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8588                        .into_arc()
 8589                };
 8590                (worktree, relative_path, source_ws)
 8591            };
 8592            let project_path = ProjectPath {
 8593                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8594                path: relative_path,
 8595            };
 8596            let buffer = lsp_store
 8597                .update(cx, |lsp_store, cx| {
 8598                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8599                        buffer_store.open_buffer(project_path, cx)
 8600                    })
 8601                })?
 8602                .await?;
 8603            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8604            if let Some((source_ws, worktree_root)) = source_ws {
 8605                buffer.update(cx, |buffer, cx| {
 8606                    let settings = WorktreeSettings::get(
 8607                        Some(
 8608                            (&ProjectPath {
 8609                                worktree_id: source_ws,
 8610                                path: Arc::from(RelPath::empty()),
 8611                            })
 8612                                .into(),
 8613                        ),
 8614                        cx,
 8615                    );
 8616                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8617                    if is_read_only {
 8618                        buffer.set_capability(Capability::ReadOnly, cx);
 8619                    }
 8620                });
 8621            }
 8622            Ok(buffer)
 8623        })
 8624    }
 8625
 8626    fn local_lsp_servers_for_buffer(
 8627        &self,
 8628        buffer: &Entity<Buffer>,
 8629        cx: &mut Context<Self>,
 8630    ) -> Vec<LanguageServerId> {
 8631        let Some(local) = self.as_local() else {
 8632            return Vec::new();
 8633        };
 8634
 8635        let snapshot = buffer.read(cx).snapshot();
 8636
 8637        buffer.update(cx, |buffer, cx| {
 8638            local
 8639                .language_servers_for_buffer(buffer, cx)
 8640                .map(|(_, server)| server.server_id())
 8641                .filter(|server_id| {
 8642                    self.as_local().is_none_or(|local| {
 8643                        local
 8644                            .buffers_opened_in_servers
 8645                            .get(&snapshot.remote_id())
 8646                            .is_some_and(|servers| servers.contains(server_id))
 8647                    })
 8648                })
 8649                .collect()
 8650        })
 8651    }
 8652
 8653    fn request_multiple_lsp_locally<P, R>(
 8654        &mut self,
 8655        buffer: &Entity<Buffer>,
 8656        position: Option<P>,
 8657        request: R,
 8658        cx: &mut Context<Self>,
 8659    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8660    where
 8661        P: ToOffset,
 8662        R: LspCommand + Clone,
 8663        <R::LspRequest as lsp::request::Request>::Result: Send,
 8664        <R::LspRequest as lsp::request::Request>::Params: Send,
 8665    {
 8666        let Some(local) = self.as_local() else {
 8667            return Task::ready(Vec::new());
 8668        };
 8669
 8670        let snapshot = buffer.read(cx).snapshot();
 8671        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8672
 8673        let server_ids = buffer.update(cx, |buffer, cx| {
 8674            local
 8675                .language_servers_for_buffer(buffer, cx)
 8676                .filter(|(adapter, _)| {
 8677                    scope
 8678                        .as_ref()
 8679                        .map(|scope| scope.language_allowed(&adapter.name))
 8680                        .unwrap_or(true)
 8681                })
 8682                .map(|(_, server)| server.server_id())
 8683                .filter(|server_id| {
 8684                    self.as_local().is_none_or(|local| {
 8685                        local
 8686                            .buffers_opened_in_servers
 8687                            .get(&snapshot.remote_id())
 8688                            .is_some_and(|servers| servers.contains(server_id))
 8689                    })
 8690                })
 8691                .collect::<Vec<_>>()
 8692        });
 8693
 8694        let mut response_results = server_ids
 8695            .into_iter()
 8696            .map(|server_id| {
 8697                let task = self.request_lsp(
 8698                    buffer.clone(),
 8699                    LanguageServerToQuery::Other(server_id),
 8700                    request.clone(),
 8701                    cx,
 8702                );
 8703                async move { (server_id, task.await) }
 8704            })
 8705            .collect::<FuturesUnordered<_>>();
 8706
 8707        cx.background_spawn(async move {
 8708            let mut responses = Vec::with_capacity(response_results.len());
 8709            while let Some((server_id, response_result)) = response_results.next().await {
 8710                match response_result {
 8711                    Ok(response) => responses.push((server_id, response)),
 8712                    // rust-analyzer likes to error with this when its still loading up
 8713                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8714                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8715                }
 8716            }
 8717            responses
 8718        })
 8719    }
 8720
 8721    async fn handle_lsp_get_completions(
 8722        this: Entity<Self>,
 8723        envelope: TypedEnvelope<proto::GetCompletions>,
 8724        mut cx: AsyncApp,
 8725    ) -> Result<proto::GetCompletionsResponse> {
 8726        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8727
 8728        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8729        let buffer_handle = this.update(&mut cx, |this, cx| {
 8730            this.buffer_store.read(cx).get_existing(buffer_id)
 8731        })?;
 8732        let request = GetCompletions::from_proto(
 8733            envelope.payload,
 8734            this.clone(),
 8735            buffer_handle.clone(),
 8736            cx.clone(),
 8737        )
 8738        .await?;
 8739
 8740        let server_to_query = match request.server_id {
 8741            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8742            None => LanguageServerToQuery::FirstCapable,
 8743        };
 8744
 8745        let response = this
 8746            .update(&mut cx, |this, cx| {
 8747                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8748            })
 8749            .await?;
 8750        this.update(&mut cx, |this, cx| {
 8751            Ok(GetCompletions::response_to_proto(
 8752                response,
 8753                this,
 8754                sender_id,
 8755                &buffer_handle.read(cx).version(),
 8756                cx,
 8757            ))
 8758        })
 8759    }
 8760
 8761    async fn handle_lsp_command<T: LspCommand>(
 8762        this: Entity<Self>,
 8763        envelope: TypedEnvelope<T::ProtoRequest>,
 8764        mut cx: AsyncApp,
 8765    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8766    where
 8767        <T::LspRequest as lsp::request::Request>::Params: Send,
 8768        <T::LspRequest as lsp::request::Request>::Result: Send,
 8769    {
 8770        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8771        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8772        let buffer_handle = this.update(&mut cx, |this, cx| {
 8773            this.buffer_store.read(cx).get_existing(buffer_id)
 8774        })?;
 8775        let request = T::from_proto(
 8776            envelope.payload,
 8777            this.clone(),
 8778            buffer_handle.clone(),
 8779            cx.clone(),
 8780        )
 8781        .await?;
 8782        let response = this
 8783            .update(&mut cx, |this, cx| {
 8784                this.request_lsp(
 8785                    buffer_handle.clone(),
 8786                    LanguageServerToQuery::FirstCapable,
 8787                    request,
 8788                    cx,
 8789                )
 8790            })
 8791            .await?;
 8792        this.update(&mut cx, |this, cx| {
 8793            Ok(T::response_to_proto(
 8794                response,
 8795                this,
 8796                sender_id,
 8797                &buffer_handle.read(cx).version(),
 8798                cx,
 8799            ))
 8800        })
 8801    }
 8802
 8803    async fn handle_lsp_query(
 8804        lsp_store: Entity<Self>,
 8805        envelope: TypedEnvelope<proto::LspQuery>,
 8806        mut cx: AsyncApp,
 8807    ) -> Result<proto::Ack> {
 8808        use proto::lsp_query::Request;
 8809        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8810        let lsp_query = envelope.payload;
 8811        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8812        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8813        match lsp_query.request.context("invalid LSP query request")? {
 8814            Request::GetReferences(get_references) => {
 8815                let position = get_references.position.clone().and_then(deserialize_anchor);
 8816                Self::query_lsp_locally::<GetReferences>(
 8817                    lsp_store,
 8818                    server_id,
 8819                    sender_id,
 8820                    lsp_request_id,
 8821                    get_references,
 8822                    position,
 8823                    &mut cx,
 8824                )
 8825                .await?;
 8826            }
 8827            Request::GetDocumentColor(get_document_color) => {
 8828                Self::query_lsp_locally::<GetDocumentColor>(
 8829                    lsp_store,
 8830                    server_id,
 8831                    sender_id,
 8832                    lsp_request_id,
 8833                    get_document_color,
 8834                    None,
 8835                    &mut cx,
 8836                )
 8837                .await?;
 8838            }
 8839            Request::GetFoldingRanges(get_folding_ranges) => {
 8840                Self::query_lsp_locally::<GetFoldingRanges>(
 8841                    lsp_store,
 8842                    server_id,
 8843                    sender_id,
 8844                    lsp_request_id,
 8845                    get_folding_ranges,
 8846                    None,
 8847                    &mut cx,
 8848                )
 8849                .await?;
 8850            }
 8851            Request::GetDocumentSymbols(get_document_symbols) => {
 8852                Self::query_lsp_locally::<GetDocumentSymbols>(
 8853                    lsp_store,
 8854                    server_id,
 8855                    sender_id,
 8856                    lsp_request_id,
 8857                    get_document_symbols,
 8858                    None,
 8859                    &mut cx,
 8860                )
 8861                .await?;
 8862            }
 8863            Request::GetHover(get_hover) => {
 8864                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8865                Self::query_lsp_locally::<GetHover>(
 8866                    lsp_store,
 8867                    server_id,
 8868                    sender_id,
 8869                    lsp_request_id,
 8870                    get_hover,
 8871                    position,
 8872                    &mut cx,
 8873                )
 8874                .await?;
 8875            }
 8876            Request::GetCodeActions(get_code_actions) => {
 8877                Self::query_lsp_locally::<GetCodeActions>(
 8878                    lsp_store,
 8879                    server_id,
 8880                    sender_id,
 8881                    lsp_request_id,
 8882                    get_code_actions,
 8883                    None,
 8884                    &mut cx,
 8885                )
 8886                .await?;
 8887            }
 8888            Request::GetSignatureHelp(get_signature_help) => {
 8889                let position = get_signature_help
 8890                    .position
 8891                    .clone()
 8892                    .and_then(deserialize_anchor);
 8893                Self::query_lsp_locally::<GetSignatureHelp>(
 8894                    lsp_store,
 8895                    server_id,
 8896                    sender_id,
 8897                    lsp_request_id,
 8898                    get_signature_help,
 8899                    position,
 8900                    &mut cx,
 8901                )
 8902                .await?;
 8903            }
 8904            Request::GetCodeLens(get_code_lens) => {
 8905                Self::query_lsp_locally::<GetCodeLens>(
 8906                    lsp_store,
 8907                    server_id,
 8908                    sender_id,
 8909                    lsp_request_id,
 8910                    get_code_lens,
 8911                    None,
 8912                    &mut cx,
 8913                )
 8914                .await?;
 8915            }
 8916            Request::GetDefinition(get_definition) => {
 8917                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8918                Self::query_lsp_locally::<GetDefinitions>(
 8919                    lsp_store,
 8920                    server_id,
 8921                    sender_id,
 8922                    lsp_request_id,
 8923                    get_definition,
 8924                    position,
 8925                    &mut cx,
 8926                )
 8927                .await?;
 8928            }
 8929            Request::GetDeclaration(get_declaration) => {
 8930                let position = get_declaration
 8931                    .position
 8932                    .clone()
 8933                    .and_then(deserialize_anchor);
 8934                Self::query_lsp_locally::<GetDeclarations>(
 8935                    lsp_store,
 8936                    server_id,
 8937                    sender_id,
 8938                    lsp_request_id,
 8939                    get_declaration,
 8940                    position,
 8941                    &mut cx,
 8942                )
 8943                .await?;
 8944            }
 8945            Request::GetTypeDefinition(get_type_definition) => {
 8946                let position = get_type_definition
 8947                    .position
 8948                    .clone()
 8949                    .and_then(deserialize_anchor);
 8950                Self::query_lsp_locally::<GetTypeDefinitions>(
 8951                    lsp_store,
 8952                    server_id,
 8953                    sender_id,
 8954                    lsp_request_id,
 8955                    get_type_definition,
 8956                    position,
 8957                    &mut cx,
 8958                )
 8959                .await?;
 8960            }
 8961            Request::GetImplementation(get_implementation) => {
 8962                let position = get_implementation
 8963                    .position
 8964                    .clone()
 8965                    .and_then(deserialize_anchor);
 8966                Self::query_lsp_locally::<GetImplementations>(
 8967                    lsp_store,
 8968                    server_id,
 8969                    sender_id,
 8970                    lsp_request_id,
 8971                    get_implementation,
 8972                    position,
 8973                    &mut cx,
 8974                )
 8975                .await?;
 8976            }
 8977            Request::InlayHints(inlay_hints) => {
 8978                let query_start = inlay_hints
 8979                    .start
 8980                    .clone()
 8981                    .and_then(deserialize_anchor)
 8982                    .context("invalid inlay hints range start")?;
 8983                let query_end = inlay_hints
 8984                    .end
 8985                    .clone()
 8986                    .and_then(deserialize_anchor)
 8987                    .context("invalid inlay hints range end")?;
 8988                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 8989                    &lsp_store,
 8990                    server_id,
 8991                    lsp_request_id,
 8992                    &inlay_hints,
 8993                    query_start..query_end,
 8994                    &mut cx,
 8995                )
 8996                .await
 8997                .context("preparing inlay hints request")?;
 8998                Self::query_lsp_locally::<InlayHints>(
 8999                    lsp_store,
 9000                    server_id,
 9001                    sender_id,
 9002                    lsp_request_id,
 9003                    inlay_hints,
 9004                    None,
 9005                    &mut cx,
 9006                )
 9007                .await
 9008                .context("querying for inlay hints")?
 9009            }
 9010            //////////////////////////////
 9011            // Below are LSP queries that need to fetch more data,
 9012            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 9013            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9014                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 9015                    &lsp_store,
 9016                    &get_document_diagnostics,
 9017                    &mut cx,
 9018                )
 9019                .await?;
 9020                lsp_store.update(&mut cx, |lsp_store, cx| {
 9021                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9022                    let key = LspKey {
 9023                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9024                        server_queried: server_id,
 9025                    };
 9026                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9027                    ) {
 9028                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9029                            lsp_requests.clear();
 9030                        };
 9031                    }
 9032
 9033                    lsp_data.lsp_requests.entry(key).or_default().insert(
 9034                        lsp_request_id,
 9035                        cx.spawn(async move |lsp_store, cx| {
 9036                            let diagnostics_pull = lsp_store
 9037                                .update(cx, |lsp_store, cx| {
 9038                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9039                                })
 9040                                .ok();
 9041                            if let Some(diagnostics_pull) = diagnostics_pull {
 9042                                match diagnostics_pull.await {
 9043                                    Ok(()) => {}
 9044                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9045                                };
 9046                            }
 9047                        }),
 9048                    );
 9049                });
 9050            }
 9051            Request::SemanticTokens(semantic_tokens) => {
 9052                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 9053                    &lsp_store,
 9054                    &semantic_tokens,
 9055                    &mut cx,
 9056                )
 9057                .await?;
 9058                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9059                lsp_store.update(&mut cx, |lsp_store, cx| {
 9060                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9061                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9062                        let key = LspKey {
 9063                            request_type: TypeId::of::<SemanticTokensFull>(),
 9064                            server_queried: server_id,
 9065                        };
 9066                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9067                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9068                                lsp_requests.clear();
 9069                            };
 9070                        }
 9071
 9072                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9073                            lsp_request_id,
 9074                            cx.spawn(async move |lsp_store, cx| {
 9075                                let tokens_fetch = lsp_store
 9076                                    .update(cx, |lsp_store, cx| {
 9077                                        lsp_store
 9078                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9079                                    })
 9080                                    .ok();
 9081                                if let Some(tokens_fetch) = tokens_fetch {
 9082                                    let new_tokens = tokens_fetch.await;
 9083                                    if let Some(new_tokens) = new_tokens {
 9084                                        lsp_store
 9085                                            .update(cx, |lsp_store, cx| {
 9086                                                let response = new_tokens
 9087                                                    .into_iter()
 9088                                                    .map(|(server_id, response)| {
 9089                                                        (
 9090                                                            server_id.to_proto(),
 9091                                                            SemanticTokensFull::response_to_proto(
 9092                                                                response,
 9093                                                                lsp_store,
 9094                                                                sender_id,
 9095                                                                &buffer_version,
 9096                                                                cx,
 9097                                                            ),
 9098                                                        )
 9099                                                    })
 9100                                                    .collect::<HashMap<_, _>>();
 9101                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9102                                                    project_id,
 9103                                                    lsp_request_id,
 9104                                                    response,
 9105                                                ) {
 9106                                                    Ok(()) => {}
 9107                                                    Err(e) => {
 9108                                                        log::error!(
 9109                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9110                                                        )
 9111                                                    }
 9112                                                }
 9113                                            })
 9114                                            .ok();
 9115                                    }
 9116                                }
 9117                            }),
 9118                        );
 9119                    }
 9120                });
 9121            }
 9122        }
 9123        Ok(proto::Ack {})
 9124    }
 9125
 9126    async fn handle_lsp_query_response(
 9127        lsp_store: Entity<Self>,
 9128        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9129        cx: AsyncApp,
 9130    ) -> Result<()> {
 9131        lsp_store.read_with(&cx, |lsp_store, _| {
 9132            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9133                upstream_client.handle_lsp_response(envelope.clone());
 9134            }
 9135        });
 9136        Ok(())
 9137    }
 9138
 9139    async fn handle_apply_code_action(
 9140        this: Entity<Self>,
 9141        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9142        mut cx: AsyncApp,
 9143    ) -> Result<proto::ApplyCodeActionResponse> {
 9144        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9145        let action =
 9146            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9147        let apply_code_action = this.update(&mut cx, |this, cx| {
 9148            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9149            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9150            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9151        })?;
 9152
 9153        let project_transaction = apply_code_action.await?;
 9154        let project_transaction = this.update(&mut cx, |this, cx| {
 9155            this.buffer_store.update(cx, |buffer_store, cx| {
 9156                buffer_store.serialize_project_transaction_for_peer(
 9157                    project_transaction,
 9158                    sender_id,
 9159                    cx,
 9160                )
 9161            })
 9162        });
 9163        Ok(proto::ApplyCodeActionResponse {
 9164            transaction: Some(project_transaction),
 9165        })
 9166    }
 9167
 9168    async fn handle_register_buffer_with_language_servers(
 9169        this: Entity<Self>,
 9170        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9171        mut cx: AsyncApp,
 9172    ) -> Result<proto::Ack> {
 9173        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9174        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9175        this.update(&mut cx, |this, cx| {
 9176            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9177                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9178                    project_id: upstream_project_id,
 9179                    buffer_id: buffer_id.to_proto(),
 9180                    only_servers: envelope.payload.only_servers,
 9181                });
 9182            }
 9183
 9184            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9185                anyhow::bail!("buffer is not open");
 9186            };
 9187
 9188            let handle = this.register_buffer_with_language_servers(
 9189                &buffer,
 9190                envelope
 9191                    .payload
 9192                    .only_servers
 9193                    .into_iter()
 9194                    .filter_map(|selector| {
 9195                        Some(match selector.selector? {
 9196                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9197                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9198                            }
 9199                            proto::language_server_selector::Selector::Name(name) => {
 9200                                LanguageServerSelector::Name(LanguageServerName(
 9201                                    SharedString::from(name),
 9202                                ))
 9203                            }
 9204                        })
 9205                    })
 9206                    .collect(),
 9207                false,
 9208                cx,
 9209            );
 9210            // Pull diagnostics for the buffer even if it was already registered.
 9211            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9212            // but it's unclear if we need it.
 9213            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9214                .detach();
 9215            this.buffer_store().update(cx, |buffer_store, _| {
 9216                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9217            });
 9218
 9219            Ok(())
 9220        })?;
 9221        Ok(proto::Ack {})
 9222    }
 9223
 9224    async fn handle_rename_project_entry(
 9225        this: Entity<Self>,
 9226        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9227        mut cx: AsyncApp,
 9228    ) -> Result<proto::ProjectEntryResponse> {
 9229        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9230        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9231        let new_path =
 9232            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9233
 9234        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9235            .update(&mut cx, |this, cx| {
 9236                let (worktree, entry) = this
 9237                    .worktree_store
 9238                    .read(cx)
 9239                    .worktree_and_entry_for_id(entry_id, cx)?;
 9240                let new_worktree = this
 9241                    .worktree_store
 9242                    .read(cx)
 9243                    .worktree_for_id(new_worktree_id, cx)?;
 9244                Some((
 9245                    this.worktree_store.clone(),
 9246                    worktree,
 9247                    new_worktree,
 9248                    entry.clone(),
 9249                ))
 9250            })
 9251            .context("worktree not found")?;
 9252        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9253            (worktree.absolutize(&old_entry.path), worktree.id())
 9254        });
 9255        let new_abs_path =
 9256            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9257
 9258        let _transaction = Self::will_rename_entry(
 9259            this.downgrade(),
 9260            old_worktree_id,
 9261            &old_abs_path,
 9262            &new_abs_path,
 9263            old_entry.is_dir(),
 9264            cx.clone(),
 9265        )
 9266        .await;
 9267        let response = WorktreeStore::handle_rename_project_entry(
 9268            worktree_store,
 9269            envelope.payload,
 9270            cx.clone(),
 9271        )
 9272        .await;
 9273        this.read_with(&cx, |this, _| {
 9274            this.did_rename_entry(
 9275                old_worktree_id,
 9276                &old_abs_path,
 9277                &new_abs_path,
 9278                old_entry.is_dir(),
 9279            );
 9280        });
 9281        response
 9282    }
 9283
 9284    async fn handle_update_diagnostic_summary(
 9285        this: Entity<Self>,
 9286        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9287        mut cx: AsyncApp,
 9288    ) -> Result<()> {
 9289        this.update(&mut cx, |lsp_store, cx| {
 9290            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9291            let mut updated_diagnostics_paths = HashMap::default();
 9292            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9293            for message_summary in envelope
 9294                .payload
 9295                .summary
 9296                .into_iter()
 9297                .chain(envelope.payload.more_summaries)
 9298            {
 9299                let project_path = ProjectPath {
 9300                    worktree_id,
 9301                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9302                };
 9303                let path = project_path.path.clone();
 9304                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9305                let summary = DiagnosticSummary {
 9306                    error_count: message_summary.error_count as usize,
 9307                    warning_count: message_summary.warning_count as usize,
 9308                };
 9309
 9310                if summary.is_empty() {
 9311                    if let Some(worktree_summaries) =
 9312                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9313                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9314                    {
 9315                        summaries.remove(&server_id);
 9316                        if summaries.is_empty() {
 9317                            worktree_summaries.remove(&path);
 9318                        }
 9319                    }
 9320                } else {
 9321                    lsp_store
 9322                        .diagnostic_summaries
 9323                        .entry(worktree_id)
 9324                        .or_default()
 9325                        .entry(path)
 9326                        .or_default()
 9327                        .insert(server_id, summary);
 9328                }
 9329
 9330                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9331                    match &mut diagnostics_summary {
 9332                        Some(diagnostics_summary) => {
 9333                            diagnostics_summary
 9334                                .more_summaries
 9335                                .push(proto::DiagnosticSummary {
 9336                                    path: project_path.path.as_ref().to_proto(),
 9337                                    language_server_id: server_id.0 as u64,
 9338                                    error_count: summary.error_count as u32,
 9339                                    warning_count: summary.warning_count as u32,
 9340                                })
 9341                        }
 9342                        None => {
 9343                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9344                                project_id: *project_id,
 9345                                worktree_id: worktree_id.to_proto(),
 9346                                summary: Some(proto::DiagnosticSummary {
 9347                                    path: project_path.path.as_ref().to_proto(),
 9348                                    language_server_id: server_id.0 as u64,
 9349                                    error_count: summary.error_count as u32,
 9350                                    warning_count: summary.warning_count as u32,
 9351                                }),
 9352                                more_summaries: Vec::new(),
 9353                            })
 9354                        }
 9355                    }
 9356                }
 9357                updated_diagnostics_paths
 9358                    .entry(server_id)
 9359                    .or_insert_with(Vec::new)
 9360                    .push(project_path);
 9361            }
 9362
 9363            if let Some((diagnostics_summary, (downstream_client, _))) =
 9364                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9365            {
 9366                downstream_client.send(diagnostics_summary).log_err();
 9367            }
 9368            for (server_id, paths) in updated_diagnostics_paths {
 9369                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9370            }
 9371            Ok(())
 9372        })
 9373    }
 9374
 9375    async fn handle_start_language_server(
 9376        lsp_store: Entity<Self>,
 9377        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9378        mut cx: AsyncApp,
 9379    ) -> Result<()> {
 9380        let server = envelope.payload.server.context("invalid server")?;
 9381        let server_capabilities =
 9382            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9383                .with_context(|| {
 9384                    format!(
 9385                        "incorrect server capabilities {}",
 9386                        envelope.payload.capabilities
 9387                    )
 9388                })?;
 9389        lsp_store.update(&mut cx, |lsp_store, cx| {
 9390            let server_id = LanguageServerId(server.id as usize);
 9391            let server_name = LanguageServerName::from_proto(server.name.clone());
 9392            lsp_store
 9393                .lsp_server_capabilities
 9394                .insert(server_id, server_capabilities);
 9395            lsp_store.language_server_statuses.insert(
 9396                server_id,
 9397                LanguageServerStatus {
 9398                    name: server_name.clone(),
 9399                    server_version: None,
 9400                    server_readable_version: None,
 9401                    pending_work: Default::default(),
 9402                    has_pending_diagnostic_updates: false,
 9403                    progress_tokens: Default::default(),
 9404                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9405                    binary: None,
 9406                    configuration: None,
 9407                    workspace_folders: BTreeSet::new(),
 9408                    process_id: None,
 9409                },
 9410            );
 9411            cx.emit(LspStoreEvent::LanguageServerAdded(
 9412                server_id,
 9413                server_name,
 9414                server.worktree_id.map(WorktreeId::from_proto),
 9415            ));
 9416            cx.notify();
 9417        });
 9418        Ok(())
 9419    }
 9420
 9421    async fn handle_update_language_server(
 9422        lsp_store: Entity<Self>,
 9423        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9424        mut cx: AsyncApp,
 9425    ) -> Result<()> {
 9426        lsp_store.update(&mut cx, |lsp_store, cx| {
 9427            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9428
 9429            match envelope.payload.variant.context("invalid variant")? {
 9430                proto::update_language_server::Variant::WorkStart(payload) => {
 9431                    lsp_store.on_lsp_work_start(
 9432                        language_server_id,
 9433                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9434                            .context("invalid progress token value")?,
 9435                        LanguageServerProgress {
 9436                            title: payload.title,
 9437                            is_disk_based_diagnostics_progress: false,
 9438                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9439                            message: payload.message,
 9440                            percentage: payload.percentage.map(|p| p as usize),
 9441                            last_update_at: cx.background_executor().now(),
 9442                        },
 9443                        cx,
 9444                    );
 9445                }
 9446                proto::update_language_server::Variant::WorkProgress(payload) => {
 9447                    lsp_store.on_lsp_work_progress(
 9448                        language_server_id,
 9449                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9450                            .context("invalid progress token value")?,
 9451                        LanguageServerProgress {
 9452                            title: None,
 9453                            is_disk_based_diagnostics_progress: false,
 9454                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9455                            message: payload.message,
 9456                            percentage: payload.percentage.map(|p| p as usize),
 9457                            last_update_at: cx.background_executor().now(),
 9458                        },
 9459                        cx,
 9460                    );
 9461                }
 9462
 9463                proto::update_language_server::Variant::WorkEnd(payload) => {
 9464                    lsp_store.on_lsp_work_end(
 9465                        language_server_id,
 9466                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9467                            .context("invalid progress token value")?,
 9468                        cx,
 9469                    );
 9470                }
 9471
 9472                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9473                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9474                }
 9475
 9476                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9477                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9478                }
 9479
 9480                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9481                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9482                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9483                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9484                        language_server_id,
 9485                        name: envelope
 9486                            .payload
 9487                            .server_name
 9488                            .map(SharedString::new)
 9489                            .map(LanguageServerName),
 9490                        message: non_lsp,
 9491                    });
 9492                }
 9493            }
 9494
 9495            Ok(())
 9496        })
 9497    }
 9498
 9499    async fn handle_language_server_log(
 9500        this: Entity<Self>,
 9501        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9502        mut cx: AsyncApp,
 9503    ) -> Result<()> {
 9504        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9505        let log_type = envelope
 9506            .payload
 9507            .log_type
 9508            .map(LanguageServerLogType::from_proto)
 9509            .context("invalid language server log type")?;
 9510
 9511        let message = envelope.payload.message;
 9512
 9513        this.update(&mut cx, |_, cx| {
 9514            cx.emit(LspStoreEvent::LanguageServerLog(
 9515                language_server_id,
 9516                log_type,
 9517                message,
 9518            ));
 9519        });
 9520        Ok(())
 9521    }
 9522
 9523    async fn handle_lsp_ext_cancel_flycheck(
 9524        lsp_store: Entity<Self>,
 9525        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9526        cx: AsyncApp,
 9527    ) -> Result<proto::Ack> {
 9528        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9529        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9530            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9531                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9532            } else {
 9533                None
 9534            }
 9535        });
 9536        if let Some(task) = task {
 9537            task.context("handling lsp ext cancel flycheck")?;
 9538        }
 9539
 9540        Ok(proto::Ack {})
 9541    }
 9542
 9543    async fn handle_lsp_ext_run_flycheck(
 9544        lsp_store: Entity<Self>,
 9545        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9546        mut cx: AsyncApp,
 9547    ) -> Result<proto::Ack> {
 9548        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9549        lsp_store.update(&mut cx, |lsp_store, cx| {
 9550            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9551                let text_document = if envelope.payload.current_file_only {
 9552                    let buffer_id = envelope
 9553                        .payload
 9554                        .buffer_id
 9555                        .map(|id| BufferId::new(id))
 9556                        .transpose()?;
 9557                    buffer_id
 9558                        .and_then(|buffer_id| {
 9559                            lsp_store
 9560                                .buffer_store()
 9561                                .read(cx)
 9562                                .get(buffer_id)
 9563                                .and_then(|buffer| {
 9564                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9565                                })
 9566                                .map(|path| make_text_document_identifier(&path))
 9567                        })
 9568                        .transpose()?
 9569                } else {
 9570                    None
 9571                };
 9572                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9573                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9574                )?;
 9575            }
 9576            anyhow::Ok(())
 9577        })?;
 9578
 9579        Ok(proto::Ack {})
 9580    }
 9581
 9582    async fn handle_lsp_ext_clear_flycheck(
 9583        lsp_store: Entity<Self>,
 9584        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9585        cx: AsyncApp,
 9586    ) -> Result<proto::Ack> {
 9587        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9588        lsp_store.read_with(&cx, |lsp_store, _| {
 9589            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9590                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9591            } else {
 9592                None
 9593            }
 9594        });
 9595
 9596        Ok(proto::Ack {})
 9597    }
 9598
 9599    pub fn disk_based_diagnostics_started(
 9600        &mut self,
 9601        language_server_id: LanguageServerId,
 9602        cx: &mut Context<Self>,
 9603    ) {
 9604        if let Some(language_server_status) =
 9605            self.language_server_statuses.get_mut(&language_server_id)
 9606        {
 9607            language_server_status.has_pending_diagnostic_updates = true;
 9608        }
 9609
 9610        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9611        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9612            language_server_id,
 9613            name: self
 9614                .language_server_adapter_for_id(language_server_id)
 9615                .map(|adapter| adapter.name()),
 9616            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9617                Default::default(),
 9618            ),
 9619        })
 9620    }
 9621
 9622    pub fn disk_based_diagnostics_finished(
 9623        &mut self,
 9624        language_server_id: LanguageServerId,
 9625        cx: &mut Context<Self>,
 9626    ) {
 9627        if let Some(language_server_status) =
 9628            self.language_server_statuses.get_mut(&language_server_id)
 9629        {
 9630            language_server_status.has_pending_diagnostic_updates = false;
 9631        }
 9632
 9633        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9634        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9635            language_server_id,
 9636            name: self
 9637                .language_server_adapter_for_id(language_server_id)
 9638                .map(|adapter| adapter.name()),
 9639            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9640                Default::default(),
 9641            ),
 9642        })
 9643    }
 9644
 9645    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9646    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9647    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9648    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9649    // the language server might take some time to publish diagnostics.
 9650    fn simulate_disk_based_diagnostics_events_if_needed(
 9651        &mut self,
 9652        language_server_id: LanguageServerId,
 9653        cx: &mut Context<Self>,
 9654    ) {
 9655        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9656
 9657        let Some(LanguageServerState::Running {
 9658            simulate_disk_based_diagnostics_completion,
 9659            adapter,
 9660            ..
 9661        }) = self
 9662            .as_local_mut()
 9663            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9664        else {
 9665            return;
 9666        };
 9667
 9668        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9669            return;
 9670        }
 9671
 9672        let prev_task =
 9673            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9674                cx.background_executor()
 9675                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9676                    .await;
 9677
 9678                this.update(cx, |this, cx| {
 9679                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9680
 9681                    if let Some(LanguageServerState::Running {
 9682                        simulate_disk_based_diagnostics_completion,
 9683                        ..
 9684                    }) = this.as_local_mut().and_then(|local_store| {
 9685                        local_store.language_servers.get_mut(&language_server_id)
 9686                    }) {
 9687                        *simulate_disk_based_diagnostics_completion = None;
 9688                    }
 9689                })
 9690                .ok();
 9691            }));
 9692
 9693        if prev_task.is_none() {
 9694            self.disk_based_diagnostics_started(language_server_id, cx);
 9695        }
 9696    }
 9697
 9698    pub fn language_server_statuses(
 9699        &self,
 9700    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9701        self.language_server_statuses
 9702            .iter()
 9703            .map(|(key, value)| (*key, value))
 9704    }
 9705
 9706    pub(super) fn did_rename_entry(
 9707        &self,
 9708        worktree_id: WorktreeId,
 9709        old_path: &Path,
 9710        new_path: &Path,
 9711        is_dir: bool,
 9712    ) {
 9713        maybe!({
 9714            let local_store = self.as_local()?;
 9715
 9716            let old_uri = lsp::Uri::from_file_path(old_path)
 9717                .ok()
 9718                .map(|uri| uri.to_string())?;
 9719            let new_uri = lsp::Uri::from_file_path(new_path)
 9720                .ok()
 9721                .map(|uri| uri.to_string())?;
 9722
 9723            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9724                let Some(filter) = local_store
 9725                    .language_server_paths_watched_for_rename
 9726                    .get(&language_server.server_id())
 9727                else {
 9728                    continue;
 9729                };
 9730
 9731                if filter.should_send_did_rename(&old_uri, is_dir) {
 9732                    language_server
 9733                        .notify::<DidRenameFiles>(RenameFilesParams {
 9734                            files: vec![FileRename {
 9735                                old_uri: old_uri.clone(),
 9736                                new_uri: new_uri.clone(),
 9737                            }],
 9738                        })
 9739                        .ok();
 9740                }
 9741            }
 9742            Some(())
 9743        });
 9744    }
 9745
 9746    pub(super) fn will_rename_entry(
 9747        this: WeakEntity<Self>,
 9748        worktree_id: WorktreeId,
 9749        old_path: &Path,
 9750        new_path: &Path,
 9751        is_dir: bool,
 9752        cx: AsyncApp,
 9753    ) -> Task<ProjectTransaction> {
 9754        let old_uri = lsp::Uri::from_file_path(old_path)
 9755            .ok()
 9756            .map(|uri| uri.to_string());
 9757        let new_uri = lsp::Uri::from_file_path(new_path)
 9758            .ok()
 9759            .map(|uri| uri.to_string());
 9760        cx.spawn(async move |cx| {
 9761            let mut tasks = vec![];
 9762            this.update(cx, |this, cx| {
 9763                let local_store = this.as_local()?;
 9764                let old_uri = old_uri?;
 9765                let new_uri = new_uri?;
 9766                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9767                    let Some(filter) = local_store
 9768                        .language_server_paths_watched_for_rename
 9769                        .get(&language_server.server_id())
 9770                    else {
 9771                        continue;
 9772                    };
 9773
 9774                    if !filter.should_send_will_rename(&old_uri, is_dir) {
 9775                        continue;
 9776                    }
 9777                    let request_timeout = ProjectSettings::get_global(cx)
 9778                        .global_lsp_settings
 9779                        .get_request_timeout();
 9780
 9781                    let apply_edit = cx.spawn({
 9782                        let old_uri = old_uri.clone();
 9783                        let new_uri = new_uri.clone();
 9784                        let language_server = language_server.clone();
 9785                        async move |this, cx| {
 9786                            let edit = language_server
 9787                                .request::<WillRenameFiles>(
 9788                                    RenameFilesParams {
 9789                                        files: vec![FileRename { old_uri, new_uri }],
 9790                                    },
 9791                                    request_timeout,
 9792                                )
 9793                                .await
 9794                                .into_response()
 9795                                .context("will rename files")
 9796                                .log_err()
 9797                                .flatten()?;
 9798
 9799                            LocalLspStore::deserialize_workspace_edit(
 9800                                this.upgrade()?,
 9801                                edit,
 9802                                false,
 9803                                language_server.clone(),
 9804                                cx,
 9805                            )
 9806                            .await
 9807                            .ok()
 9808                        }
 9809                    });
 9810                    tasks.push(apply_edit);
 9811                }
 9812                Some(())
 9813            })
 9814            .ok()
 9815            .flatten();
 9816            let mut merged_transaction = ProjectTransaction::default();
 9817            for task in tasks {
 9818                // Await on tasks sequentially so that the order of application of edits is deterministic
 9819                // (at least with regards to the order of registration of language servers)
 9820                if let Some(transaction) = task.await {
 9821                    for (buffer, buffer_transaction) in transaction.0 {
 9822                        merged_transaction.0.insert(buffer, buffer_transaction);
 9823                    }
 9824                }
 9825            }
 9826            merged_transaction
 9827        })
 9828    }
 9829
 9830    fn lsp_notify_abs_paths_changed(
 9831        &mut self,
 9832        server_id: LanguageServerId,
 9833        changes: Vec<PathEvent>,
 9834    ) {
 9835        maybe!({
 9836            let server = self.language_server_for_id(server_id)?;
 9837            let changes = changes
 9838                .into_iter()
 9839                .filter_map(|event| {
 9840                    let typ = match event.kind? {
 9841                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9842                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9843                        PathEventKind::Changed | PathEventKind::Rescan => {
 9844                            lsp::FileChangeType::CHANGED
 9845                        }
 9846                    };
 9847                    Some(lsp::FileEvent {
 9848                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9849                        typ,
 9850                    })
 9851                })
 9852                .collect::<Vec<_>>();
 9853            if !changes.is_empty() {
 9854                server
 9855                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9856                        lsp::DidChangeWatchedFilesParams { changes },
 9857                    )
 9858                    .ok();
 9859            }
 9860            Some(())
 9861        });
 9862    }
 9863
 9864    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9865        self.as_local()?.language_server_for_id(id)
 9866    }
 9867
 9868    fn on_lsp_progress(
 9869        &mut self,
 9870        progress_params: lsp::ProgressParams,
 9871        language_server_id: LanguageServerId,
 9872        disk_based_diagnostics_progress_token: Option<String>,
 9873        cx: &mut Context<Self>,
 9874    ) {
 9875        match progress_params.value {
 9876            lsp::ProgressParamsValue::WorkDone(progress) => {
 9877                self.handle_work_done_progress(
 9878                    progress,
 9879                    language_server_id,
 9880                    disk_based_diagnostics_progress_token,
 9881                    ProgressToken::from_lsp(progress_params.token),
 9882                    cx,
 9883                );
 9884            }
 9885            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9886                let registration_id = match progress_params.token {
 9887                    lsp::NumberOrString::Number(_) => None,
 9888                    lsp::NumberOrString::String(token) => token
 9889                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9890                        .map(|(_, id)| id.to_owned()),
 9891                };
 9892                if let Some(LanguageServerState::Running {
 9893                    workspace_diagnostics_refresh_tasks,
 9894                    ..
 9895                }) = self
 9896                    .as_local_mut()
 9897                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9898                    && let Some(workspace_diagnostics) =
 9899                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9900                {
 9901                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9902                    self.apply_workspace_diagnostic_report(
 9903                        language_server_id,
 9904                        report,
 9905                        registration_id.map(SharedString::from),
 9906                        cx,
 9907                    )
 9908                }
 9909            }
 9910        }
 9911    }
 9912
 9913    fn handle_work_done_progress(
 9914        &mut self,
 9915        progress: lsp::WorkDoneProgress,
 9916        language_server_id: LanguageServerId,
 9917        disk_based_diagnostics_progress_token: Option<String>,
 9918        token: ProgressToken,
 9919        cx: &mut Context<Self>,
 9920    ) {
 9921        let language_server_status =
 9922            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9923                status
 9924            } else {
 9925                return;
 9926            };
 9927
 9928        if !language_server_status.progress_tokens.contains(&token) {
 9929            return;
 9930        }
 9931
 9932        let is_disk_based_diagnostics_progress =
 9933            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9934                (&disk_based_diagnostics_progress_token, &token)
 9935            {
 9936                token.starts_with(disk_based_token)
 9937            } else {
 9938                false
 9939            };
 9940
 9941        match progress {
 9942            lsp::WorkDoneProgress::Begin(report) => {
 9943                if is_disk_based_diagnostics_progress {
 9944                    self.disk_based_diagnostics_started(language_server_id, cx);
 9945                }
 9946                self.on_lsp_work_start(
 9947                    language_server_id,
 9948                    token.clone(),
 9949                    LanguageServerProgress {
 9950                        title: Some(report.title),
 9951                        is_disk_based_diagnostics_progress,
 9952                        is_cancellable: report.cancellable.unwrap_or(false),
 9953                        message: report.message.clone(),
 9954                        percentage: report.percentage.map(|p| p as usize),
 9955                        last_update_at: cx.background_executor().now(),
 9956                    },
 9957                    cx,
 9958                );
 9959            }
 9960            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9961                language_server_id,
 9962                token,
 9963                LanguageServerProgress {
 9964                    title: None,
 9965                    is_disk_based_diagnostics_progress,
 9966                    is_cancellable: report.cancellable.unwrap_or(false),
 9967                    message: report.message,
 9968                    percentage: report.percentage.map(|p| p as usize),
 9969                    last_update_at: cx.background_executor().now(),
 9970                },
 9971                cx,
 9972            ),
 9973            lsp::WorkDoneProgress::End(_) => {
 9974                language_server_status.progress_tokens.remove(&token);
 9975                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9976                if is_disk_based_diagnostics_progress {
 9977                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9978                }
 9979            }
 9980        }
 9981    }
 9982
 9983    fn on_lsp_work_start(
 9984        &mut self,
 9985        language_server_id: LanguageServerId,
 9986        token: ProgressToken,
 9987        progress: LanguageServerProgress,
 9988        cx: &mut Context<Self>,
 9989    ) {
 9990        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9991            status.pending_work.insert(token.clone(), progress.clone());
 9992            cx.notify();
 9993        }
 9994        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9995            language_server_id,
 9996            name: self
 9997                .language_server_adapter_for_id(language_server_id)
 9998                .map(|adapter| adapter.name()),
 9999            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10000                token: Some(token.to_proto()),
10001                title: progress.title,
10002                message: progress.message,
10003                percentage: progress.percentage.map(|p| p as u32),
10004                is_cancellable: Some(progress.is_cancellable),
10005            }),
10006        })
10007    }
10008
10009    fn on_lsp_work_progress(
10010        &mut self,
10011        language_server_id: LanguageServerId,
10012        token: ProgressToken,
10013        progress: LanguageServerProgress,
10014        cx: &mut Context<Self>,
10015    ) {
10016        let mut did_update = false;
10017        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10018            match status.pending_work.entry(token.clone()) {
10019                btree_map::Entry::Vacant(entry) => {
10020                    entry.insert(progress.clone());
10021                    did_update = true;
10022                }
10023                btree_map::Entry::Occupied(mut entry) => {
10024                    let entry = entry.get_mut();
10025                    if (progress.last_update_at - entry.last_update_at)
10026                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10027                    {
10028                        entry.last_update_at = progress.last_update_at;
10029                        if progress.message.is_some() {
10030                            entry.message = progress.message.clone();
10031                        }
10032                        if progress.percentage.is_some() {
10033                            entry.percentage = progress.percentage;
10034                        }
10035                        if progress.is_cancellable != entry.is_cancellable {
10036                            entry.is_cancellable = progress.is_cancellable;
10037                        }
10038                        did_update = true;
10039                    }
10040                }
10041            }
10042        }
10043
10044        if did_update {
10045            cx.emit(LspStoreEvent::LanguageServerUpdate {
10046                language_server_id,
10047                name: self
10048                    .language_server_adapter_for_id(language_server_id)
10049                    .map(|adapter| adapter.name()),
10050                message: proto::update_language_server::Variant::WorkProgress(
10051                    proto::LspWorkProgress {
10052                        token: Some(token.to_proto()),
10053                        message: progress.message,
10054                        percentage: progress.percentage.map(|p| p as u32),
10055                        is_cancellable: Some(progress.is_cancellable),
10056                    },
10057                ),
10058            })
10059        }
10060    }
10061
10062    fn on_lsp_work_end(
10063        &mut self,
10064        language_server_id: LanguageServerId,
10065        token: ProgressToken,
10066        cx: &mut Context<Self>,
10067    ) {
10068        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10069            if let Some(work) = status.pending_work.remove(&token)
10070                && !work.is_disk_based_diagnostics_progress
10071            {
10072                cx.emit(LspStoreEvent::RefreshInlayHints {
10073                    server_id: language_server_id,
10074                    request_id: None,
10075                });
10076            }
10077            cx.notify();
10078        }
10079
10080        cx.emit(LspStoreEvent::LanguageServerUpdate {
10081            language_server_id,
10082            name: self
10083                .language_server_adapter_for_id(language_server_id)
10084                .map(|adapter| adapter.name()),
10085            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10086                token: Some(token.to_proto()),
10087            }),
10088        })
10089    }
10090
10091    pub async fn handle_resolve_completion_documentation(
10092        this: Entity<Self>,
10093        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10094        mut cx: AsyncApp,
10095    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10096        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10097
10098        let completion = this
10099            .read_with(&cx, |this, cx| {
10100                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10101                let server = this
10102                    .language_server_for_id(id)
10103                    .with_context(|| format!("No language server {id}"))?;
10104
10105                let request_timeout = ProjectSettings::get_global(cx)
10106                    .global_lsp_settings
10107                    .get_request_timeout();
10108
10109                anyhow::Ok(cx.background_spawn(async move {
10110                    let can_resolve = server
10111                        .capabilities()
10112                        .completion_provider
10113                        .as_ref()
10114                        .and_then(|options| options.resolve_provider)
10115                        .unwrap_or(false);
10116                    if can_resolve {
10117                        server
10118                            .request::<lsp::request::ResolveCompletionItem>(
10119                                lsp_completion,
10120                                request_timeout,
10121                            )
10122                            .await
10123                            .into_response()
10124                            .context("resolve completion item")
10125                    } else {
10126                        anyhow::Ok(lsp_completion)
10127                    }
10128                }))
10129            })?
10130            .await?;
10131
10132        let mut documentation_is_markdown = false;
10133        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10134        let documentation = match completion.documentation {
10135            Some(lsp::Documentation::String(text)) => text,
10136
10137            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10138                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10139                value
10140            }
10141
10142            _ => String::new(),
10143        };
10144
10145        // If we have a new buffer_id, that means we're talking to a new client
10146        // and want to check for new text_edits in the completion too.
10147        let mut old_replace_start = None;
10148        let mut old_replace_end = None;
10149        let mut old_insert_start = None;
10150        let mut old_insert_end = None;
10151        let mut new_text = String::default();
10152        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10153            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10154                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10155                anyhow::Ok(buffer.read(cx).snapshot())
10156            })?;
10157
10158            if let Some(text_edit) = completion.text_edit.as_ref() {
10159                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10160
10161                if let Some(mut edit) = edit {
10162                    LineEnding::normalize(&mut edit.new_text);
10163
10164                    new_text = edit.new_text;
10165                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10166                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10167                    if let Some(insert_range) = edit.insert_range {
10168                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10169                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10170                    }
10171                }
10172            }
10173        }
10174
10175        Ok(proto::ResolveCompletionDocumentationResponse {
10176            documentation,
10177            documentation_is_markdown,
10178            old_replace_start,
10179            old_replace_end,
10180            new_text,
10181            lsp_completion,
10182            old_insert_start,
10183            old_insert_end,
10184        })
10185    }
10186
10187    async fn handle_on_type_formatting(
10188        this: Entity<Self>,
10189        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10190        mut cx: AsyncApp,
10191    ) -> Result<proto::OnTypeFormattingResponse> {
10192        let on_type_formatting = this.update(&mut cx, |this, cx| {
10193            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10194            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10195            let position = envelope
10196                .payload
10197                .position
10198                .and_then(deserialize_anchor)
10199                .context("invalid position")?;
10200            anyhow::Ok(this.apply_on_type_formatting(
10201                buffer,
10202                position,
10203                envelope.payload.trigger.clone(),
10204                cx,
10205            ))
10206        })?;
10207
10208        let transaction = on_type_formatting
10209            .await?
10210            .as_ref()
10211            .map(language::proto::serialize_transaction);
10212        Ok(proto::OnTypeFormattingResponse { transaction })
10213    }
10214
10215    async fn handle_pull_workspace_diagnostics(
10216        lsp_store: Entity<Self>,
10217        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10218        mut cx: AsyncApp,
10219    ) -> Result<proto::Ack> {
10220        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10221        lsp_store.update(&mut cx, |lsp_store, _| {
10222            lsp_store.pull_workspace_diagnostics(server_id);
10223        });
10224        Ok(proto::Ack {})
10225    }
10226
10227    async fn handle_open_buffer_for_symbol(
10228        this: Entity<Self>,
10229        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10230        mut cx: AsyncApp,
10231    ) -> Result<proto::OpenBufferForSymbolResponse> {
10232        let peer_id = envelope.original_sender_id().unwrap_or_default();
10233        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10234        let symbol = Self::deserialize_symbol(symbol)?;
10235        this.read_with(&cx, |this, _| {
10236            if let SymbolLocation::OutsideProject {
10237                abs_path,
10238                signature,
10239            } = &symbol.path
10240            {
10241                let new_signature = this.symbol_signature(&abs_path);
10242                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10243            }
10244            Ok(())
10245        })?;
10246        let buffer = this
10247            .update(&mut cx, |this, cx| {
10248                this.open_buffer_for_symbol(
10249                    &Symbol {
10250                        language_server_name: symbol.language_server_name,
10251                        source_worktree_id: symbol.source_worktree_id,
10252                        source_language_server_id: symbol.source_language_server_id,
10253                        path: symbol.path,
10254                        name: symbol.name,
10255                        kind: symbol.kind,
10256                        range: symbol.range,
10257                        label: CodeLabel::default(),
10258                        container_name: symbol.container_name,
10259                    },
10260                    cx,
10261                )
10262            })
10263            .await?;
10264
10265        this.update(&mut cx, |this, cx| {
10266            let is_private = buffer
10267                .read(cx)
10268                .file()
10269                .map(|f| f.is_private())
10270                .unwrap_or_default();
10271            if is_private {
10272                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10273            } else {
10274                this.buffer_store
10275                    .update(cx, |buffer_store, cx| {
10276                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10277                    })
10278                    .detach_and_log_err(cx);
10279                let buffer_id = buffer.read(cx).remote_id().to_proto();
10280                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10281            }
10282        })
10283    }
10284
10285    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10286        let mut hasher = Sha256::new();
10287        hasher.update(abs_path.to_string_lossy().as_bytes());
10288        hasher.update(self.nonce.to_be_bytes());
10289        hasher.finalize().as_slice().try_into().unwrap()
10290    }
10291
10292    pub async fn handle_get_project_symbols(
10293        this: Entity<Self>,
10294        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10295        mut cx: AsyncApp,
10296    ) -> Result<proto::GetProjectSymbolsResponse> {
10297        let symbols = this
10298            .update(&mut cx, |this, cx| {
10299                this.symbols(&envelope.payload.query, cx)
10300            })
10301            .await?;
10302
10303        Ok(proto::GetProjectSymbolsResponse {
10304            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10305        })
10306    }
10307
10308    pub async fn handle_restart_language_servers(
10309        this: Entity<Self>,
10310        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10311        mut cx: AsyncApp,
10312    ) -> Result<proto::Ack> {
10313        this.update(&mut cx, |lsp_store, cx| {
10314            let buffers =
10315                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10316            lsp_store.restart_language_servers_for_buffers(
10317                buffers,
10318                envelope
10319                    .payload
10320                    .only_servers
10321                    .into_iter()
10322                    .filter_map(|selector| {
10323                        Some(match selector.selector? {
10324                            proto::language_server_selector::Selector::ServerId(server_id) => {
10325                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10326                            }
10327                            proto::language_server_selector::Selector::Name(name) => {
10328                                LanguageServerSelector::Name(LanguageServerName(
10329                                    SharedString::from(name),
10330                                ))
10331                            }
10332                        })
10333                    })
10334                    .collect(),
10335                cx,
10336            );
10337        });
10338
10339        Ok(proto::Ack {})
10340    }
10341
10342    pub async fn handle_stop_language_servers(
10343        lsp_store: Entity<Self>,
10344        envelope: TypedEnvelope<proto::StopLanguageServers>,
10345        mut cx: AsyncApp,
10346    ) -> Result<proto::Ack> {
10347        lsp_store.update(&mut cx, |lsp_store, cx| {
10348            if envelope.payload.all
10349                && envelope.payload.also_servers.is_empty()
10350                && envelope.payload.buffer_ids.is_empty()
10351            {
10352                lsp_store.stop_all_language_servers(cx);
10353            } else {
10354                let buffers =
10355                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10356                lsp_store
10357                    .stop_language_servers_for_buffers(
10358                        buffers,
10359                        envelope
10360                            .payload
10361                            .also_servers
10362                            .into_iter()
10363                            .filter_map(|selector| {
10364                                Some(match selector.selector? {
10365                                    proto::language_server_selector::Selector::ServerId(
10366                                        server_id,
10367                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10368                                        server_id,
10369                                    )),
10370                                    proto::language_server_selector::Selector::Name(name) => {
10371                                        LanguageServerSelector::Name(LanguageServerName(
10372                                            SharedString::from(name),
10373                                        ))
10374                                    }
10375                                })
10376                            })
10377                            .collect(),
10378                        cx,
10379                    )
10380                    .detach_and_log_err(cx);
10381            }
10382        });
10383
10384        Ok(proto::Ack {})
10385    }
10386
10387    pub async fn handle_cancel_language_server_work(
10388        lsp_store: Entity<Self>,
10389        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10390        mut cx: AsyncApp,
10391    ) -> Result<proto::Ack> {
10392        lsp_store.update(&mut cx, |lsp_store, cx| {
10393            if let Some(work) = envelope.payload.work {
10394                match work {
10395                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10396                        let buffers =
10397                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10398                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10399                    }
10400                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10401                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10402                        let token = work
10403                            .token
10404                            .map(|token| {
10405                                ProgressToken::from_proto(token)
10406                                    .context("invalid work progress token")
10407                            })
10408                            .transpose()?;
10409                        lsp_store.cancel_language_server_work(server_id, token, cx);
10410                    }
10411                }
10412            }
10413            anyhow::Ok(())
10414        })?;
10415
10416        Ok(proto::Ack {})
10417    }
10418
10419    fn buffer_ids_to_buffers(
10420        &mut self,
10421        buffer_ids: impl Iterator<Item = u64>,
10422        cx: &mut Context<Self>,
10423    ) -> Vec<Entity<Buffer>> {
10424        buffer_ids
10425            .into_iter()
10426            .flat_map(|buffer_id| {
10427                self.buffer_store
10428                    .read(cx)
10429                    .get(BufferId::new(buffer_id).log_err()?)
10430            })
10431            .collect::<Vec<_>>()
10432    }
10433
10434    async fn handle_apply_additional_edits_for_completion(
10435        this: Entity<Self>,
10436        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10437        mut cx: AsyncApp,
10438    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10439        let (buffer, completion, all_commit_ranges) = this.update(&mut cx, |this, cx| {
10440            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10441            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10442            let completion = Self::deserialize_completion(
10443                envelope.payload.completion.context("invalid completion")?,
10444            )?;
10445            let all_commit_ranges = envelope
10446                .payload
10447                .all_commit_ranges
10448                .into_iter()
10449                .map(language::proto::deserialize_anchor_range)
10450                .collect::<Result<Vec<_>, _>>()?;
10451            anyhow::Ok((buffer, completion, all_commit_ranges))
10452        })?;
10453
10454        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10455            this.apply_additional_edits_for_completion(
10456                buffer,
10457                Rc::new(RefCell::new(Box::new([Completion {
10458                    replace_range: completion.replace_range,
10459                    new_text: completion.new_text,
10460                    source: completion.source,
10461                    documentation: None,
10462                    label: CodeLabel::default(),
10463                    match_start: None,
10464                    snippet_deduplication_key: None,
10465                    insert_text_mode: None,
10466                    icon_path: None,
10467                    confirm: None,
10468                }]))),
10469                0,
10470                false,
10471                all_commit_ranges,
10472                cx,
10473            )
10474        });
10475
10476        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10477            transaction: apply_additional_edits
10478                .await?
10479                .as_ref()
10480                .map(language::proto::serialize_transaction),
10481        })
10482    }
10483
10484    pub fn last_formatting_failure(&self) -> Option<&str> {
10485        self.last_formatting_failure.as_deref()
10486    }
10487
10488    pub fn reset_last_formatting_failure(&mut self) {
10489        self.last_formatting_failure = None;
10490    }
10491
10492    pub fn environment_for_buffer(
10493        &self,
10494        buffer: &Entity<Buffer>,
10495        cx: &mut Context<Self>,
10496    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10497        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10498            environment.update(cx, |env, cx| {
10499                env.buffer_environment(buffer, &self.worktree_store, cx)
10500            })
10501        } else {
10502            Task::ready(None).shared()
10503        }
10504    }
10505
10506    pub fn format(
10507        &mut self,
10508        buffers: HashSet<Entity<Buffer>>,
10509        target: LspFormatTarget,
10510        push_to_history: bool,
10511        trigger: FormatTrigger,
10512        cx: &mut Context<Self>,
10513    ) -> Task<anyhow::Result<ProjectTransaction>> {
10514        let logger = zlog::scoped!("format");
10515        if self.as_local().is_some() {
10516            zlog::trace!(logger => "Formatting locally");
10517            let logger = zlog::scoped!(logger => "local");
10518            let buffers = buffers
10519                .into_iter()
10520                .map(|buffer_handle| {
10521                    let buffer = buffer_handle.read(cx);
10522                    let buffer_abs_path = File::from_dyn(buffer.file())
10523                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10524
10525                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10526                })
10527                .collect::<Vec<_>>();
10528
10529            cx.spawn(async move |lsp_store, cx| {
10530                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10531
10532                for (handle, abs_path, id) in buffers {
10533                    let env = lsp_store
10534                        .update(cx, |lsp_store, cx| {
10535                            lsp_store.environment_for_buffer(&handle, cx)
10536                        })?
10537                        .await;
10538
10539                    let ranges = match &target {
10540                        LspFormatTarget::Buffers => None,
10541                        LspFormatTarget::Ranges(ranges) => {
10542                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10543                        }
10544                    };
10545
10546                    formattable_buffers.push(FormattableBuffer {
10547                        handle,
10548                        abs_path,
10549                        env,
10550                        ranges,
10551                    });
10552                }
10553                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10554
10555                let format_timer = zlog::time!(logger => "Formatting buffers");
10556                let result = LocalLspStore::format_locally(
10557                    lsp_store.clone(),
10558                    formattable_buffers,
10559                    push_to_history,
10560                    trigger,
10561                    logger,
10562                    cx,
10563                )
10564                .await;
10565                format_timer.end();
10566
10567                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10568
10569                lsp_store.update(cx, |lsp_store, _| {
10570                    lsp_store.update_last_formatting_failure(&result);
10571                })?;
10572
10573                result
10574            })
10575        } else if let Some((client, project_id)) = self.upstream_client() {
10576            zlog::trace!(logger => "Formatting remotely");
10577            let logger = zlog::scoped!(logger => "remote");
10578
10579            let buffer_ranges = match &target {
10580                LspFormatTarget::Buffers => Vec::new(),
10581                LspFormatTarget::Ranges(ranges) => ranges
10582                    .iter()
10583                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10584                        buffer_id: buffer_id.to_proto(),
10585                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10586                    })
10587                    .collect(),
10588            };
10589
10590            let buffer_store = self.buffer_store();
10591            cx.spawn(async move |lsp_store, cx| {
10592                zlog::trace!(logger => "Sending remote format request");
10593                let request_timer = zlog::time!(logger => "remote format request");
10594                let result = client
10595                    .request(proto::FormatBuffers {
10596                        project_id,
10597                        trigger: trigger as i32,
10598                        buffer_ids: buffers
10599                            .iter()
10600                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10601                            .collect(),
10602                        buffer_ranges,
10603                    })
10604                    .await
10605                    .and_then(|result| result.transaction.context("missing transaction"));
10606                request_timer.end();
10607
10608                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10609
10610                lsp_store.update(cx, |lsp_store, _| {
10611                    lsp_store.update_last_formatting_failure(&result);
10612                })?;
10613
10614                let transaction_response = result?;
10615                let _timer = zlog::time!(logger => "deserializing project transaction");
10616                buffer_store
10617                    .update(cx, |buffer_store, cx| {
10618                        buffer_store.deserialize_project_transaction(
10619                            transaction_response,
10620                            push_to_history,
10621                            cx,
10622                        )
10623                    })
10624                    .await
10625            })
10626        } else {
10627            zlog::trace!(logger => "Not formatting");
10628            Task::ready(Ok(ProjectTransaction::default()))
10629        }
10630    }
10631
10632    async fn handle_format_buffers(
10633        this: Entity<Self>,
10634        envelope: TypedEnvelope<proto::FormatBuffers>,
10635        mut cx: AsyncApp,
10636    ) -> Result<proto::FormatBuffersResponse> {
10637        let sender_id = envelope.original_sender_id().unwrap_or_default();
10638        let format = this.update(&mut cx, |this, cx| {
10639            let mut buffers = HashSet::default();
10640            for buffer_id in &envelope.payload.buffer_ids {
10641                let buffer_id = BufferId::new(*buffer_id)?;
10642                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10643            }
10644
10645            let target = if envelope.payload.buffer_ranges.is_empty() {
10646                LspFormatTarget::Buffers
10647            } else {
10648                let mut ranges_map = BTreeMap::new();
10649                for buffer_range in &envelope.payload.buffer_ranges {
10650                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10651                    let ranges: Result<Vec<_>> = buffer_range
10652                        .ranges
10653                        .iter()
10654                        .map(|range| {
10655                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10656                        })
10657                        .collect();
10658                    ranges_map.insert(buffer_id, ranges?);
10659                }
10660                LspFormatTarget::Ranges(ranges_map)
10661            };
10662
10663            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10664            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10665        })?;
10666
10667        let project_transaction = format.await?;
10668        let project_transaction = this.update(&mut cx, |this, cx| {
10669            this.buffer_store.update(cx, |buffer_store, cx| {
10670                buffer_store.serialize_project_transaction_for_peer(
10671                    project_transaction,
10672                    sender_id,
10673                    cx,
10674                )
10675            })
10676        });
10677        Ok(proto::FormatBuffersResponse {
10678            transaction: Some(project_transaction),
10679        })
10680    }
10681
10682    async fn handle_apply_code_action_kind(
10683        this: Entity<Self>,
10684        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10685        mut cx: AsyncApp,
10686    ) -> Result<proto::ApplyCodeActionKindResponse> {
10687        let sender_id = envelope.original_sender_id().unwrap_or_default();
10688        let format = this.update(&mut cx, |this, cx| {
10689            let mut buffers = HashSet::default();
10690            for buffer_id in &envelope.payload.buffer_ids {
10691                let buffer_id = BufferId::new(*buffer_id)?;
10692                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10693            }
10694            let kind = match envelope.payload.kind.as_str() {
10695                "" => CodeActionKind::EMPTY,
10696                "quickfix" => CodeActionKind::QUICKFIX,
10697                "refactor" => CodeActionKind::REFACTOR,
10698                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10699                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10700                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10701                "source" => CodeActionKind::SOURCE,
10702                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10703                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10704                _ => anyhow::bail!(
10705                    "Invalid code action kind {}",
10706                    envelope.payload.kind.as_str()
10707                ),
10708            };
10709            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10710        })?;
10711
10712        let project_transaction = format.await?;
10713        let project_transaction = this.update(&mut cx, |this, cx| {
10714            this.buffer_store.update(cx, |buffer_store, cx| {
10715                buffer_store.serialize_project_transaction_for_peer(
10716                    project_transaction,
10717                    sender_id,
10718                    cx,
10719                )
10720            })
10721        });
10722        Ok(proto::ApplyCodeActionKindResponse {
10723            transaction: Some(project_transaction),
10724        })
10725    }
10726
10727    async fn shutdown_language_server(
10728        server_state: Option<LanguageServerState>,
10729        name: LanguageServerName,
10730        cx: &mut AsyncApp,
10731    ) {
10732        let server = match server_state {
10733            Some(LanguageServerState::Starting { startup, .. }) => {
10734                let mut timer = cx
10735                    .background_executor()
10736                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10737                    .fuse();
10738
10739                select! {
10740                    server = startup.fuse() => server,
10741                    () = timer => {
10742                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10743                        None
10744                    },
10745                }
10746            }
10747
10748            Some(LanguageServerState::Running { server, .. }) => Some(server),
10749
10750            None => None,
10751        };
10752
10753        let Some(server) = server else { return };
10754        if let Some(shutdown) = server.shutdown() {
10755            shutdown.await;
10756        }
10757    }
10758
10759    // Returns a list of all of the worktrees which no longer have a language server and the root path
10760    // for the stopped server
10761    fn stop_local_language_server(
10762        &mut self,
10763        server_id: LanguageServerId,
10764        cx: &mut Context<Self>,
10765    ) -> Task<()> {
10766        let local = match &mut self.mode {
10767            LspStoreMode::Local(local) => local,
10768            _ => {
10769                return Task::ready(());
10770            }
10771        };
10772
10773        // Remove this server ID from all entries in the given worktree.
10774        local
10775            .language_server_ids
10776            .retain(|_, state| state.id != server_id);
10777        self.buffer_store.update(cx, |buffer_store, cx| {
10778            for buffer in buffer_store.buffers() {
10779                buffer.update(cx, |buffer, cx| {
10780                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10781                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10782                });
10783            }
10784        });
10785
10786        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10787            summaries.retain(|path, summaries_by_server_id| {
10788                if summaries_by_server_id.remove(&server_id).is_some() {
10789                    if let Some((client, project_id)) = self.downstream_client.clone() {
10790                        client
10791                            .send(proto::UpdateDiagnosticSummary {
10792                                project_id,
10793                                worktree_id: worktree_id.to_proto(),
10794                                summary: Some(proto::DiagnosticSummary {
10795                                    path: path.as_ref().to_proto(),
10796                                    language_server_id: server_id.0 as u64,
10797                                    error_count: 0,
10798                                    warning_count: 0,
10799                                }),
10800                                more_summaries: Vec::new(),
10801                            })
10802                            .log_err();
10803                    }
10804                    !summaries_by_server_id.is_empty()
10805                } else {
10806                    true
10807                }
10808            });
10809        }
10810
10811        let local = self.as_local_mut().unwrap();
10812        for diagnostics in local.diagnostics.values_mut() {
10813            diagnostics.retain(|_, diagnostics_by_server_id| {
10814                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10815                    diagnostics_by_server_id.remove(ix);
10816                    !diagnostics_by_server_id.is_empty()
10817                } else {
10818                    true
10819                }
10820            });
10821        }
10822        local.language_server_watched_paths.remove(&server_id);
10823
10824        let server_state = local.language_servers.remove(&server_id);
10825        self.cleanup_lsp_data(server_id);
10826        let name = self
10827            .language_server_statuses
10828            .remove(&server_id)
10829            .map(|status| status.name)
10830            .or_else(|| {
10831                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10832                    Some(adapter.name())
10833                } else {
10834                    None
10835                }
10836            });
10837
10838        if let Some(name) = name {
10839            log::info!("stopping language server {name}");
10840            self.languages
10841                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10842            cx.notify();
10843
10844            return cx.spawn(async move |lsp_store, cx| {
10845                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10846                lsp_store
10847                    .update(cx, |lsp_store, cx| {
10848                        lsp_store
10849                            .languages
10850                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10851                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10852                        cx.notify();
10853                    })
10854                    .ok();
10855            });
10856        }
10857
10858        if server_state.is_some() {
10859            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10860        }
10861        Task::ready(())
10862    }
10863
10864    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10865        self.shutdown_all_language_servers(cx).detach();
10866    }
10867
10868    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
10869        if let Some((client, project_id)) = self.upstream_client() {
10870            let request = client.request(proto::StopLanguageServers {
10871                project_id,
10872                buffer_ids: Vec::new(),
10873                also_servers: Vec::new(),
10874                all: true,
10875            });
10876            cx.background_spawn(async move {
10877                request.await.ok();
10878            })
10879        } else {
10880            let Some(local) = self.as_local_mut() else {
10881                return Task::ready(());
10882            };
10883            let language_servers_to_stop = local
10884                .language_server_ids
10885                .values()
10886                .map(|state| state.id)
10887                .collect();
10888            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10889            let tasks = language_servers_to_stop
10890                .into_iter()
10891                .map(|server| self.stop_local_language_server(server, cx))
10892                .collect::<Vec<_>>();
10893            cx.background_spawn(async move {
10894                futures::future::join_all(tasks).await;
10895            })
10896        }
10897    }
10898
10899    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
10900        let buffers = self.buffer_store.read(cx).buffers().collect();
10901        self.restart_language_servers_for_buffers(buffers, HashSet::default(), cx);
10902    }
10903
10904    pub fn restart_language_servers_for_buffers(
10905        &mut self,
10906        buffers: Vec<Entity<Buffer>>,
10907        only_restart_servers: HashSet<LanguageServerSelector>,
10908        cx: &mut Context<Self>,
10909    ) {
10910        if let Some((client, project_id)) = self.upstream_client() {
10911            let request = client.request(proto::RestartLanguageServers {
10912                project_id,
10913                buffer_ids: buffers
10914                    .into_iter()
10915                    .map(|b| b.read(cx).remote_id().to_proto())
10916                    .collect(),
10917                only_servers: only_restart_servers
10918                    .into_iter()
10919                    .map(|selector| {
10920                        let selector = match selector {
10921                            LanguageServerSelector::Id(language_server_id) => {
10922                                proto::language_server_selector::Selector::ServerId(
10923                                    language_server_id.to_proto(),
10924                                )
10925                            }
10926                            LanguageServerSelector::Name(language_server_name) => {
10927                                proto::language_server_selector::Selector::Name(
10928                                    language_server_name.to_string(),
10929                                )
10930                            }
10931                        };
10932                        proto::LanguageServerSelector {
10933                            selector: Some(selector),
10934                        }
10935                    })
10936                    .collect(),
10937                all: false,
10938            });
10939            cx.background_spawn(request).detach_and_log_err(cx);
10940        } else {
10941            let stop_task = if only_restart_servers.is_empty() {
10942                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10943            } else {
10944                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10945            };
10946            cx.spawn(async move |lsp_store, cx| {
10947                stop_task.await;
10948                lsp_store.update(cx, |lsp_store, cx| {
10949                    for buffer in buffers {
10950                        lsp_store.register_buffer_with_language_servers(
10951                            &buffer,
10952                            only_restart_servers.clone(),
10953                            true,
10954                            cx,
10955                        );
10956                    }
10957                })
10958            })
10959            .detach();
10960        }
10961    }
10962
10963    pub fn stop_language_servers_for_buffers(
10964        &mut self,
10965        buffers: Vec<Entity<Buffer>>,
10966        also_stop_servers: HashSet<LanguageServerSelector>,
10967        cx: &mut Context<Self>,
10968    ) -> Task<Result<()>> {
10969        if let Some((client, project_id)) = self.upstream_client() {
10970            let request = client.request(proto::StopLanguageServers {
10971                project_id,
10972                buffer_ids: buffers
10973                    .into_iter()
10974                    .map(|b| b.read(cx).remote_id().to_proto())
10975                    .collect(),
10976                also_servers: also_stop_servers
10977                    .into_iter()
10978                    .map(|selector| {
10979                        let selector = match selector {
10980                            LanguageServerSelector::Id(language_server_id) => {
10981                                proto::language_server_selector::Selector::ServerId(
10982                                    language_server_id.to_proto(),
10983                                )
10984                            }
10985                            LanguageServerSelector::Name(language_server_name) => {
10986                                proto::language_server_selector::Selector::Name(
10987                                    language_server_name.to_string(),
10988                                )
10989                            }
10990                        };
10991                        proto::LanguageServerSelector {
10992                            selector: Some(selector),
10993                        }
10994                    })
10995                    .collect(),
10996                all: false,
10997            });
10998            cx.background_spawn(async move {
10999                let _ = request.await?;
11000                Ok(())
11001            })
11002        } else {
11003            let task =
11004                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11005            cx.background_spawn(async move {
11006                task.await;
11007                Ok(())
11008            })
11009        }
11010    }
11011
11012    fn stop_local_language_servers_for_buffers(
11013        &mut self,
11014        buffers: &[Entity<Buffer>],
11015        also_stop_servers: HashSet<LanguageServerSelector>,
11016        cx: &mut Context<Self>,
11017    ) -> Task<()> {
11018        let Some(local) = self.as_local_mut() else {
11019            return Task::ready(());
11020        };
11021        let mut language_server_names_to_stop = BTreeSet::default();
11022        let mut language_servers_to_stop = also_stop_servers
11023            .into_iter()
11024            .flat_map(|selector| match selector {
11025                LanguageServerSelector::Id(id) => Some(id),
11026                LanguageServerSelector::Name(name) => {
11027                    language_server_names_to_stop.insert(name);
11028                    None
11029                }
11030            })
11031            .collect::<BTreeSet<_>>();
11032
11033        let mut covered_worktrees = HashSet::default();
11034        for buffer in buffers {
11035            buffer.update(cx, |buffer, cx| {
11036                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11037                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11038                    && covered_worktrees.insert(worktree_id)
11039                {
11040                    language_server_names_to_stop.retain(|name| {
11041                        let old_ids_count = language_servers_to_stop.len();
11042                        let all_language_servers_with_this_name = local
11043                            .language_server_ids
11044                            .iter()
11045                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11046                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11047                        old_ids_count == language_servers_to_stop.len()
11048                    });
11049                }
11050            });
11051        }
11052        for name in language_server_names_to_stop {
11053            language_servers_to_stop.extend(
11054                local
11055                    .language_server_ids
11056                    .iter()
11057                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11058            );
11059        }
11060
11061        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11062        let tasks = language_servers_to_stop
11063            .into_iter()
11064            .map(|server| self.stop_local_language_server(server, cx))
11065            .collect::<Vec<_>>();
11066
11067        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11068    }
11069
11070    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11071        let (worktree, relative_path) =
11072            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11073
11074        let project_path = ProjectPath {
11075            worktree_id: worktree.read(cx).id(),
11076            path: relative_path,
11077        };
11078
11079        Some(
11080            self.buffer_store()
11081                .read(cx)
11082                .get_by_path(&project_path)?
11083                .read(cx),
11084        )
11085    }
11086
11087    #[cfg(any(test, feature = "test-support"))]
11088    pub fn update_diagnostics(
11089        &mut self,
11090        server_id: LanguageServerId,
11091        diagnostics: lsp::PublishDiagnosticsParams,
11092        result_id: Option<SharedString>,
11093        source_kind: DiagnosticSourceKind,
11094        disk_based_sources: &[String],
11095        cx: &mut Context<Self>,
11096    ) -> Result<()> {
11097        self.merge_lsp_diagnostics(
11098            source_kind,
11099            vec![DocumentDiagnosticsUpdate {
11100                diagnostics,
11101                result_id,
11102                server_id,
11103                disk_based_sources: Cow::Borrowed(disk_based_sources),
11104                registration_id: None,
11105            }],
11106            |_, _, _| false,
11107            cx,
11108        )
11109    }
11110
11111    pub fn merge_lsp_diagnostics(
11112        &mut self,
11113        source_kind: DiagnosticSourceKind,
11114        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11115        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11116        cx: &mut Context<Self>,
11117    ) -> Result<()> {
11118        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11119        let updates = lsp_diagnostics
11120            .into_iter()
11121            .filter_map(|update| {
11122                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11123                Some(DocumentDiagnosticsUpdate {
11124                    diagnostics: self.lsp_to_document_diagnostics(
11125                        abs_path,
11126                        source_kind,
11127                        update.server_id,
11128                        update.diagnostics,
11129                        &update.disk_based_sources,
11130                        update.registration_id.clone(),
11131                    ),
11132                    result_id: update.result_id,
11133                    server_id: update.server_id,
11134                    disk_based_sources: update.disk_based_sources,
11135                    registration_id: update.registration_id,
11136                })
11137            })
11138            .collect();
11139        self.merge_diagnostic_entries(updates, merge, cx)?;
11140        Ok(())
11141    }
11142
11143    fn lsp_to_document_diagnostics(
11144        &mut self,
11145        document_abs_path: PathBuf,
11146        source_kind: DiagnosticSourceKind,
11147        server_id: LanguageServerId,
11148        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11149        disk_based_sources: &[String],
11150        registration_id: Option<SharedString>,
11151    ) -> DocumentDiagnostics {
11152        let mut diagnostics = Vec::default();
11153        let mut primary_diagnostic_group_ids = HashMap::default();
11154        let mut sources_by_group_id = HashMap::default();
11155        let mut supporting_diagnostics = HashMap::default();
11156
11157        let adapter = self.language_server_adapter_for_id(server_id);
11158
11159        // Ensure that primary diagnostics are always the most severe
11160        lsp_diagnostics
11161            .diagnostics
11162            .sort_by_key(|item| item.severity);
11163
11164        for diagnostic in &lsp_diagnostics.diagnostics {
11165            let source = diagnostic.source.as_ref();
11166            let range = range_from_lsp(diagnostic.range);
11167            let is_supporting = diagnostic
11168                .related_information
11169                .as_ref()
11170                .is_some_and(|infos| {
11171                    infos.iter().any(|info| {
11172                        primary_diagnostic_group_ids.contains_key(&(
11173                            source,
11174                            diagnostic.code.clone(),
11175                            range_from_lsp(info.location.range),
11176                        ))
11177                    })
11178                });
11179
11180            let is_unnecessary = diagnostic
11181                .tags
11182                .as_ref()
11183                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11184
11185            let underline = self
11186                .language_server_adapter_for_id(server_id)
11187                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11188
11189            if is_supporting {
11190                supporting_diagnostics.insert(
11191                    (source, diagnostic.code.clone(), range),
11192                    (diagnostic.severity, is_unnecessary),
11193                );
11194            } else {
11195                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11196                let is_disk_based =
11197                    source.is_some_and(|source| disk_based_sources.contains(source));
11198
11199                sources_by_group_id.insert(group_id, source);
11200                primary_diagnostic_group_ids
11201                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11202
11203                diagnostics.push(DiagnosticEntry {
11204                    range,
11205                    diagnostic: Diagnostic {
11206                        source: diagnostic.source.clone(),
11207                        source_kind,
11208                        code: diagnostic.code.clone(),
11209                        code_description: diagnostic
11210                            .code_description
11211                            .as_ref()
11212                            .and_then(|d| d.href.clone()),
11213                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11214                        markdown: adapter.as_ref().and_then(|adapter| {
11215                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11216                        }),
11217                        message: diagnostic.message.trim().to_string(),
11218                        group_id,
11219                        is_primary: true,
11220                        is_disk_based,
11221                        is_unnecessary,
11222                        underline,
11223                        data: diagnostic.data.clone(),
11224                        registration_id: registration_id.clone(),
11225                    },
11226                });
11227                if let Some(infos) = &diagnostic.related_information {
11228                    for info in infos {
11229                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11230                            let range = range_from_lsp(info.location.range);
11231                            diagnostics.push(DiagnosticEntry {
11232                                range,
11233                                diagnostic: Diagnostic {
11234                                    source: diagnostic.source.clone(),
11235                                    source_kind,
11236                                    code: diagnostic.code.clone(),
11237                                    code_description: diagnostic
11238                                        .code_description
11239                                        .as_ref()
11240                                        .and_then(|d| d.href.clone()),
11241                                    severity: DiagnosticSeverity::INFORMATION,
11242                                    markdown: adapter.as_ref().and_then(|adapter| {
11243                                        adapter.diagnostic_message_to_markdown(&info.message)
11244                                    }),
11245                                    message: info.message.trim().to_string(),
11246                                    group_id,
11247                                    is_primary: false,
11248                                    is_disk_based,
11249                                    is_unnecessary: false,
11250                                    underline,
11251                                    data: diagnostic.data.clone(),
11252                                    registration_id: registration_id.clone(),
11253                                },
11254                            });
11255                        }
11256                    }
11257                }
11258            }
11259        }
11260
11261        for entry in &mut diagnostics {
11262            let diagnostic = &mut entry.diagnostic;
11263            if !diagnostic.is_primary {
11264                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11265                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11266                    source,
11267                    diagnostic.code.clone(),
11268                    entry.range.clone(),
11269                )) {
11270                    if let Some(severity) = severity {
11271                        diagnostic.severity = severity;
11272                    }
11273                    diagnostic.is_unnecessary = is_unnecessary;
11274                }
11275            }
11276        }
11277
11278        DocumentDiagnostics {
11279            diagnostics,
11280            document_abs_path,
11281            version: lsp_diagnostics.version,
11282        }
11283    }
11284
11285    fn insert_newly_running_language_server(
11286        &mut self,
11287        adapter: Arc<CachedLspAdapter>,
11288        language_server: Arc<LanguageServer>,
11289        server_id: LanguageServerId,
11290        key: LanguageServerSeed,
11291        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11292        cx: &mut Context<Self>,
11293    ) {
11294        let Some(local) = self.as_local_mut() else {
11295            return;
11296        };
11297        // If the language server for this key doesn't match the server id, don't store the
11298        // server. Which will cause it to be dropped, killing the process
11299        if local
11300            .language_server_ids
11301            .get(&key)
11302            .map(|state| state.id != server_id)
11303            .unwrap_or(false)
11304        {
11305            return;
11306        }
11307
11308        // Update language_servers collection with Running variant of LanguageServerState
11309        // indicating that the server is up and running and ready
11310        let workspace_folders = workspace_folders.lock().clone();
11311        language_server.set_workspace_folders(workspace_folders);
11312
11313        let workspace_diagnostics_refresh_tasks = language_server
11314            .capabilities()
11315            .diagnostic_provider
11316            .and_then(|provider| {
11317                local
11318                    .language_server_dynamic_registrations
11319                    .entry(server_id)
11320                    .or_default()
11321                    .diagnostics
11322                    .entry(None)
11323                    .or_insert(provider.clone());
11324                let workspace_refresher =
11325                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11326
11327                Some((None, workspace_refresher))
11328            })
11329            .into_iter()
11330            .collect();
11331        local.language_servers.insert(
11332            server_id,
11333            LanguageServerState::Running {
11334                workspace_diagnostics_refresh_tasks,
11335                adapter: adapter.clone(),
11336                server: language_server.clone(),
11337                simulate_disk_based_diagnostics_completion: None,
11338            },
11339        );
11340        local
11341            .languages
11342            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11343        if let Some(file_ops_caps) = language_server
11344            .capabilities()
11345            .workspace
11346            .as_ref()
11347            .and_then(|ws| ws.file_operations.as_ref())
11348        {
11349            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11350            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11351            if did_rename_caps.or(will_rename_caps).is_some() {
11352                let watcher = RenamePathsWatchedForServer::default()
11353                    .with_did_rename_patterns(did_rename_caps)
11354                    .with_will_rename_patterns(will_rename_caps);
11355                local
11356                    .language_server_paths_watched_for_rename
11357                    .insert(server_id, watcher);
11358            }
11359        }
11360
11361        self.language_server_statuses.insert(
11362            server_id,
11363            LanguageServerStatus {
11364                name: language_server.name(),
11365                server_version: language_server.version(),
11366                server_readable_version: language_server.readable_version(),
11367                pending_work: Default::default(),
11368                has_pending_diagnostic_updates: false,
11369                progress_tokens: Default::default(),
11370                worktree: Some(key.worktree_id),
11371                binary: Some(language_server.binary().clone()),
11372                configuration: Some(language_server.configuration().clone()),
11373                workspace_folders: language_server.workspace_folders(),
11374                process_id: language_server.process_id(),
11375            },
11376        );
11377
11378        cx.emit(LspStoreEvent::LanguageServerAdded(
11379            server_id,
11380            language_server.name(),
11381            Some(key.worktree_id),
11382        ));
11383
11384        let server_capabilities = language_server.capabilities();
11385        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11386            downstream_client
11387                .send(proto::StartLanguageServer {
11388                    project_id: *project_id,
11389                    server: Some(proto::LanguageServer {
11390                        id: server_id.to_proto(),
11391                        name: language_server.name().to_string(),
11392                        worktree_id: Some(key.worktree_id.to_proto()),
11393                    }),
11394                    capabilities: serde_json::to_string(&server_capabilities)
11395                        .expect("serializing server LSP capabilities"),
11396                })
11397                .log_err();
11398        }
11399        self.lsp_server_capabilities
11400            .insert(server_id, server_capabilities);
11401
11402        // Tell the language server about every open buffer in the worktree that matches the language.
11403        // Also check for buffers in worktrees that reused this server
11404        let mut worktrees_using_server = vec![key.worktree_id];
11405        if let Some(local) = self.as_local() {
11406            // Find all worktrees that have this server in their language server tree
11407            for (worktree_id, servers) in &local.lsp_tree.instances {
11408                if *worktree_id != key.worktree_id {
11409                    for server_map in servers.roots.values() {
11410                        if server_map
11411                            .values()
11412                            .any(|(node, _)| node.id() == Some(server_id))
11413                        {
11414                            worktrees_using_server.push(*worktree_id);
11415                        }
11416                    }
11417                }
11418            }
11419        }
11420
11421        let mut buffer_paths_registered = Vec::new();
11422        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11423            let mut lsp_adapters = HashMap::default();
11424            for buffer_handle in buffer_store.buffers() {
11425                let buffer = buffer_handle.read(cx);
11426                let file = match File::from_dyn(buffer.file()) {
11427                    Some(file) => file,
11428                    None => continue,
11429                };
11430                let language = match buffer.language() {
11431                    Some(language) => language,
11432                    None => continue,
11433                };
11434
11435                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11436                    || !lsp_adapters
11437                        .entry(language.name())
11438                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11439                        .iter()
11440                        .any(|a| a.name == key.name)
11441                {
11442                    continue;
11443                }
11444                // didOpen
11445                let file = match file.as_local() {
11446                    Some(file) => file,
11447                    None => continue,
11448                };
11449
11450                let local = self.as_local_mut().unwrap();
11451
11452                let buffer_id = buffer.remote_id();
11453                if local.registered_buffers.contains_key(&buffer_id) {
11454                    let abs_path = file.abs_path(cx);
11455                    let uri = match lsp::Uri::from_file_path(&abs_path) {
11456                        Ok(uri) => uri,
11457                        Err(()) => {
11458                            log::error!("failed to convert path to URI: {:?}", abs_path);
11459                            continue;
11460                        }
11461                    };
11462
11463                    let versions = local
11464                        .buffer_snapshots
11465                        .entry(buffer_id)
11466                        .or_default()
11467                        .entry(server_id)
11468                        .and_modify(|_| {
11469                            assert!(
11470                            false,
11471                            "There should not be an existing snapshot for a newly inserted buffer"
11472                        )
11473                        })
11474                        .or_insert_with(|| {
11475                            vec![LspBufferSnapshot {
11476                                version: 0,
11477                                snapshot: buffer.text_snapshot(),
11478                            }]
11479                        });
11480
11481                    let snapshot = versions.last().unwrap();
11482                    let version = snapshot.version;
11483                    let initial_snapshot = &snapshot.snapshot;
11484                    language_server.register_buffer(
11485                        uri,
11486                        adapter.language_id(&language.name()),
11487                        version,
11488                        initial_snapshot.text(),
11489                    );
11490                    buffer_paths_registered.push((buffer_id, abs_path));
11491                    local
11492                        .buffers_opened_in_servers
11493                        .entry(buffer_id)
11494                        .or_default()
11495                        .insert(server_id);
11496                }
11497                buffer_handle.update(cx, |buffer, cx| {
11498                    buffer.set_completion_triggers(
11499                        server_id,
11500                        language_server
11501                            .capabilities()
11502                            .completion_provider
11503                            .as_ref()
11504                            .and_then(|provider| {
11505                                provider
11506                                    .trigger_characters
11507                                    .as_ref()
11508                                    .map(|characters| characters.iter().cloned().collect())
11509                            })
11510                            .unwrap_or_default(),
11511                        cx,
11512                    )
11513                });
11514            }
11515        });
11516
11517        for (buffer_id, abs_path) in buffer_paths_registered {
11518            cx.emit(LspStoreEvent::LanguageServerUpdate {
11519                language_server_id: server_id,
11520                name: Some(adapter.name()),
11521                message: proto::update_language_server::Variant::RegisteredForBuffer(
11522                    proto::RegisteredForBuffer {
11523                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11524                        buffer_id: buffer_id.to_proto(),
11525                    },
11526                ),
11527            });
11528        }
11529
11530        cx.notify();
11531    }
11532
11533    pub fn language_servers_running_disk_based_diagnostics(
11534        &self,
11535    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11536        self.language_server_statuses
11537            .iter()
11538            .filter_map(|(id, status)| {
11539                if status.has_pending_diagnostic_updates {
11540                    Some(*id)
11541                } else {
11542                    None
11543                }
11544            })
11545    }
11546
11547    pub(crate) fn cancel_language_server_work_for_buffers(
11548        &mut self,
11549        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11550        cx: &mut Context<Self>,
11551    ) {
11552        if let Some((client, project_id)) = self.upstream_client() {
11553            let request = client.request(proto::CancelLanguageServerWork {
11554                project_id,
11555                work: Some(proto::cancel_language_server_work::Work::Buffers(
11556                    proto::cancel_language_server_work::Buffers {
11557                        buffer_ids: buffers
11558                            .into_iter()
11559                            .map(|b| b.read(cx).remote_id().to_proto())
11560                            .collect(),
11561                    },
11562                )),
11563            });
11564            cx.background_spawn(request).detach_and_log_err(cx);
11565        } else if let Some(local) = self.as_local() {
11566            let servers = buffers
11567                .into_iter()
11568                .flat_map(|buffer| {
11569                    buffer.update(cx, |buffer, cx| {
11570                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11571                    })
11572                })
11573                .collect::<HashSet<_>>();
11574            for server_id in servers {
11575                self.cancel_language_server_work(server_id, None, cx);
11576            }
11577        }
11578    }
11579
11580    pub(crate) fn cancel_language_server_work(
11581        &mut self,
11582        server_id: LanguageServerId,
11583        token_to_cancel: Option<ProgressToken>,
11584        cx: &mut Context<Self>,
11585    ) {
11586        if let Some(local) = self.as_local() {
11587            let status = self.language_server_statuses.get(&server_id);
11588            let server = local.language_servers.get(&server_id);
11589            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11590            {
11591                for (token, progress) in &status.pending_work {
11592                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11593                        && token != token_to_cancel
11594                    {
11595                        continue;
11596                    }
11597                    if progress.is_cancellable {
11598                        server
11599                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11600                                WorkDoneProgressCancelParams {
11601                                    token: token.to_lsp(),
11602                                },
11603                            )
11604                            .ok();
11605                    }
11606                }
11607            }
11608        } else if let Some((client, project_id)) = self.upstream_client() {
11609            let request = client.request(proto::CancelLanguageServerWork {
11610                project_id,
11611                work: Some(
11612                    proto::cancel_language_server_work::Work::LanguageServerWork(
11613                        proto::cancel_language_server_work::LanguageServerWork {
11614                            language_server_id: server_id.to_proto(),
11615                            token: token_to_cancel.map(|token| token.to_proto()),
11616                        },
11617                    ),
11618                ),
11619            });
11620            cx.background_spawn(request).detach_and_log_err(cx);
11621        }
11622    }
11623
11624    fn register_supplementary_language_server(
11625        &mut self,
11626        id: LanguageServerId,
11627        name: LanguageServerName,
11628        server: Arc<LanguageServer>,
11629        cx: &mut Context<Self>,
11630    ) {
11631        if let Some(local) = self.as_local_mut() {
11632            local
11633                .supplementary_language_servers
11634                .insert(id, (name.clone(), server));
11635            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11636        }
11637    }
11638
11639    fn unregister_supplementary_language_server(
11640        &mut self,
11641        id: LanguageServerId,
11642        cx: &mut Context<Self>,
11643    ) {
11644        if let Some(local) = self.as_local_mut() {
11645            local.supplementary_language_servers.remove(&id);
11646            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11647        }
11648    }
11649
11650    pub(crate) fn supplementary_language_servers(
11651        &self,
11652    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11653        self.as_local().into_iter().flat_map(|local| {
11654            local
11655                .supplementary_language_servers
11656                .iter()
11657                .map(|(id, (name, _))| (*id, name.clone()))
11658        })
11659    }
11660
11661    pub fn language_server_adapter_for_id(
11662        &self,
11663        id: LanguageServerId,
11664    ) -> Option<Arc<CachedLspAdapter>> {
11665        self.as_local()
11666            .and_then(|local| local.language_servers.get(&id))
11667            .and_then(|language_server_state| match language_server_state {
11668                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11669                _ => None,
11670            })
11671    }
11672
11673    pub(super) fn update_local_worktree_language_servers(
11674        &mut self,
11675        worktree_handle: &Entity<Worktree>,
11676        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11677        cx: &mut Context<Self>,
11678    ) {
11679        if changes.is_empty() {
11680            return;
11681        }
11682
11683        let Some(local) = self.as_local() else { return };
11684
11685        local.prettier_store.update(cx, |prettier_store, cx| {
11686            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11687        });
11688
11689        let worktree_id = worktree_handle.read(cx).id();
11690        let mut language_server_ids = local
11691            .language_server_ids
11692            .iter()
11693            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11694            .collect::<Vec<_>>();
11695        language_server_ids.sort();
11696        language_server_ids.dedup();
11697
11698        // let abs_path = worktree_handle.read(cx).abs_path();
11699        for server_id in &language_server_ids {
11700            if let Some(LanguageServerState::Running { server, .. }) =
11701                local.language_servers.get(server_id)
11702                && let Some(watched_paths) = local
11703                    .language_server_watched_paths
11704                    .get(server_id)
11705                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11706            {
11707                let params = lsp::DidChangeWatchedFilesParams {
11708                    changes: changes
11709                        .iter()
11710                        .filter_map(|(path, _, change)| {
11711                            if !watched_paths.is_match(path.as_std_path()) {
11712                                return None;
11713                            }
11714                            let typ = match change {
11715                                PathChange::Loaded => return None,
11716                                PathChange::Added => lsp::FileChangeType::CREATED,
11717                                PathChange::Removed => lsp::FileChangeType::DELETED,
11718                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11719                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11720                            };
11721                            let uri = lsp::Uri::from_file_path(
11722                                worktree_handle.read(cx).absolutize(&path),
11723                            )
11724                            .ok()?;
11725                            Some(lsp::FileEvent { uri, typ })
11726                        })
11727                        .collect(),
11728                };
11729                if !params.changes.is_empty() {
11730                    server
11731                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11732                        .ok();
11733                }
11734            }
11735        }
11736        for (path, _, _) in changes {
11737            if let Some(file_name) = path.file_name()
11738                && local.watched_manifest_filenames.contains(file_name)
11739            {
11740                self.request_workspace_config_refresh();
11741                break;
11742            }
11743        }
11744    }
11745
11746    pub fn wait_for_remote_buffer(
11747        &mut self,
11748        id: BufferId,
11749        cx: &mut Context<Self>,
11750    ) -> Task<Result<Entity<Buffer>>> {
11751        self.buffer_store.update(cx, |buffer_store, cx| {
11752            buffer_store.wait_for_remote_buffer(id, cx)
11753        })
11754    }
11755
11756    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11757        let mut result = proto::Symbol {
11758            language_server_name: symbol.language_server_name.0.to_string(),
11759            source_worktree_id: symbol.source_worktree_id.to_proto(),
11760            language_server_id: symbol.source_language_server_id.to_proto(),
11761            name: symbol.name.clone(),
11762            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11763            start: Some(proto::PointUtf16 {
11764                row: symbol.range.start.0.row,
11765                column: symbol.range.start.0.column,
11766            }),
11767            end: Some(proto::PointUtf16 {
11768                row: symbol.range.end.0.row,
11769                column: symbol.range.end.0.column,
11770            }),
11771            worktree_id: Default::default(),
11772            path: Default::default(),
11773            signature: Default::default(),
11774            container_name: symbol.container_name.clone(),
11775        };
11776        match &symbol.path {
11777            SymbolLocation::InProject(path) => {
11778                result.worktree_id = path.worktree_id.to_proto();
11779                result.path = path.path.to_proto();
11780            }
11781            SymbolLocation::OutsideProject {
11782                abs_path,
11783                signature,
11784            } => {
11785                result.path = abs_path.to_string_lossy().into_owned();
11786                result.signature = signature.to_vec();
11787            }
11788        }
11789        result
11790    }
11791
11792    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11793        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11794        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11795        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11796
11797        let path = if serialized_symbol.signature.is_empty() {
11798            SymbolLocation::InProject(ProjectPath {
11799                worktree_id,
11800                path: RelPath::from_proto(&serialized_symbol.path)
11801                    .context("invalid symbol path")?,
11802            })
11803        } else {
11804            SymbolLocation::OutsideProject {
11805                abs_path: Path::new(&serialized_symbol.path).into(),
11806                signature: serialized_symbol
11807                    .signature
11808                    .try_into()
11809                    .map_err(|_| anyhow!("invalid signature"))?,
11810            }
11811        };
11812
11813        let start = serialized_symbol.start.context("invalid start")?;
11814        let end = serialized_symbol.end.context("invalid end")?;
11815        Ok(CoreSymbol {
11816            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11817            source_worktree_id,
11818            source_language_server_id: LanguageServerId::from_proto(
11819                serialized_symbol.language_server_id,
11820            ),
11821            path,
11822            name: serialized_symbol.name,
11823            range: Unclipped(PointUtf16::new(start.row, start.column))
11824                ..Unclipped(PointUtf16::new(end.row, end.column)),
11825            kind,
11826            container_name: serialized_symbol.container_name,
11827        })
11828    }
11829
11830    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11831        let mut serialized_completion = proto::Completion {
11832            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11833            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11834            new_text: completion.new_text.clone(),
11835            ..proto::Completion::default()
11836        };
11837        match &completion.source {
11838            CompletionSource::Lsp {
11839                insert_range,
11840                server_id,
11841                lsp_completion,
11842                lsp_defaults,
11843                resolved,
11844            } => {
11845                let (old_insert_start, old_insert_end) = insert_range
11846                    .as_ref()
11847                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11848                    .unzip();
11849
11850                serialized_completion.old_insert_start = old_insert_start;
11851                serialized_completion.old_insert_end = old_insert_end;
11852                serialized_completion.source = proto::completion::Source::Lsp as i32;
11853                serialized_completion.server_id = server_id.0 as u64;
11854                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11855                serialized_completion.lsp_defaults = lsp_defaults
11856                    .as_deref()
11857                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11858                serialized_completion.resolved = *resolved;
11859            }
11860            CompletionSource::BufferWord {
11861                word_range,
11862                resolved,
11863            } => {
11864                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11865                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11866                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11867                serialized_completion.resolved = *resolved;
11868            }
11869            CompletionSource::Custom => {
11870                serialized_completion.source = proto::completion::Source::Custom as i32;
11871                serialized_completion.resolved = true;
11872            }
11873            CompletionSource::Dap { sort_text } => {
11874                serialized_completion.source = proto::completion::Source::Dap as i32;
11875                serialized_completion.sort_text = Some(sort_text.clone());
11876            }
11877        }
11878
11879        serialized_completion
11880    }
11881
11882    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11883        let old_replace_start = completion
11884            .old_replace_start
11885            .and_then(deserialize_anchor)
11886            .context("invalid old start")?;
11887        let old_replace_end = completion
11888            .old_replace_end
11889            .and_then(deserialize_anchor)
11890            .context("invalid old end")?;
11891        let insert_range = {
11892            match completion.old_insert_start.zip(completion.old_insert_end) {
11893                Some((start, end)) => {
11894                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11895                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11896                    Some(start..end)
11897                }
11898                None => None,
11899            }
11900        };
11901        Ok(CoreCompletion {
11902            replace_range: old_replace_start..old_replace_end,
11903            new_text: completion.new_text,
11904            source: match proto::completion::Source::from_i32(completion.source) {
11905                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11906                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11907                    insert_range,
11908                    server_id: LanguageServerId::from_proto(completion.server_id),
11909                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11910                    lsp_defaults: completion
11911                        .lsp_defaults
11912                        .as_deref()
11913                        .map(serde_json::from_slice)
11914                        .transpose()?,
11915                    resolved: completion.resolved,
11916                },
11917                Some(proto::completion::Source::BufferWord) => {
11918                    let word_range = completion
11919                        .buffer_word_start
11920                        .and_then(deserialize_anchor)
11921                        .context("invalid buffer word start")?
11922                        ..completion
11923                            .buffer_word_end
11924                            .and_then(deserialize_anchor)
11925                            .context("invalid buffer word end")?;
11926                    CompletionSource::BufferWord {
11927                        word_range,
11928                        resolved: completion.resolved,
11929                    }
11930                }
11931                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11932                    sort_text: completion
11933                        .sort_text
11934                        .context("expected sort text to exist")?,
11935                },
11936                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11937            },
11938        })
11939    }
11940
11941    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11942        let (kind, lsp_action) = match &action.lsp_action {
11943            LspAction::Action(code_action) => (
11944                proto::code_action::Kind::Action as i32,
11945                serde_json::to_vec(code_action).unwrap(),
11946            ),
11947            LspAction::Command(command) => (
11948                proto::code_action::Kind::Command as i32,
11949                serde_json::to_vec(command).unwrap(),
11950            ),
11951            LspAction::CodeLens(code_lens) => (
11952                proto::code_action::Kind::CodeLens as i32,
11953                serde_json::to_vec(code_lens).unwrap(),
11954            ),
11955        };
11956
11957        proto::CodeAction {
11958            server_id: action.server_id.0 as u64,
11959            start: Some(serialize_anchor(&action.range.start)),
11960            end: Some(serialize_anchor(&action.range.end)),
11961            lsp_action,
11962            kind,
11963            resolved: action.resolved,
11964        }
11965    }
11966
11967    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11968        let start = action
11969            .start
11970            .and_then(deserialize_anchor)
11971            .context("invalid start")?;
11972        let end = action
11973            .end
11974            .and_then(deserialize_anchor)
11975            .context("invalid end")?;
11976        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11977            Some(proto::code_action::Kind::Action) => {
11978                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11979            }
11980            Some(proto::code_action::Kind::Command) => {
11981                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11982            }
11983            Some(proto::code_action::Kind::CodeLens) => {
11984                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11985            }
11986            None => anyhow::bail!("Unknown action kind {}", action.kind),
11987        };
11988        Ok(CodeAction {
11989            server_id: LanguageServerId(action.server_id as usize),
11990            range: start..end,
11991            resolved: action.resolved,
11992            lsp_action,
11993        })
11994    }
11995
11996    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11997        match &formatting_result {
11998            Ok(_) => self.last_formatting_failure = None,
11999            Err(error) => {
12000                let error_string = format!("{error:#}");
12001                log::error!("Formatting failed: {error_string}");
12002                self.last_formatting_failure
12003                    .replace(error_string.lines().join(" "));
12004            }
12005        }
12006    }
12007
12008    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12009        self.lsp_server_capabilities.remove(&for_server);
12010        self.semantic_token_config.remove_server_data(for_server);
12011        for lsp_data in self.lsp_data.values_mut() {
12012            lsp_data.remove_server_data(for_server);
12013        }
12014        if let Some(local) = self.as_local_mut() {
12015            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12016            local
12017                .workspace_pull_diagnostics_result_ids
12018                .remove(&for_server);
12019            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12020                buffer_servers.remove(&for_server);
12021            }
12022        }
12023    }
12024
12025    pub fn result_id_for_buffer_pull(
12026        &self,
12027        server_id: LanguageServerId,
12028        buffer_id: BufferId,
12029        registration_id: &Option<SharedString>,
12030        cx: &App,
12031    ) -> Option<SharedString> {
12032        let abs_path = self
12033            .buffer_store
12034            .read(cx)
12035            .get(buffer_id)
12036            .and_then(|b| File::from_dyn(b.read(cx).file()))
12037            .map(|f| f.abs_path(cx))?;
12038        self.as_local()?
12039            .buffer_pull_diagnostics_result_ids
12040            .get(&server_id)?
12041            .get(registration_id)?
12042            .get(&abs_path)?
12043            .clone()
12044    }
12045
12046    /// Gets all result_ids for a workspace diagnostics pull request.
12047    /// 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.
12048    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12049    pub fn result_ids_for_workspace_refresh(
12050        &self,
12051        server_id: LanguageServerId,
12052        registration_id: &Option<SharedString>,
12053    ) -> HashMap<PathBuf, SharedString> {
12054        let Some(local) = self.as_local() else {
12055            return HashMap::default();
12056        };
12057        local
12058            .workspace_pull_diagnostics_result_ids
12059            .get(&server_id)
12060            .into_iter()
12061            .filter_map(|diagnostics| diagnostics.get(registration_id))
12062            .flatten()
12063            .filter_map(|(abs_path, result_id)| {
12064                let result_id = local
12065                    .buffer_pull_diagnostics_result_ids
12066                    .get(&server_id)
12067                    .and_then(|buffer_ids_result_ids| {
12068                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12069                    })
12070                    .cloned()
12071                    .flatten()
12072                    .or_else(|| result_id.clone())?;
12073                Some((abs_path.clone(), result_id))
12074            })
12075            .collect()
12076    }
12077
12078    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12079        if let Some(LanguageServerState::Running {
12080            workspace_diagnostics_refresh_tasks,
12081            ..
12082        }) = self
12083            .as_local_mut()
12084            .and_then(|local| local.language_servers.get_mut(&server_id))
12085        {
12086            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12087                diagnostics.refresh_tx.try_send(()).ok();
12088            }
12089        }
12090    }
12091
12092    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12093    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12094    /// which requires refreshing both workspace and document diagnostics.
12095    pub fn pull_document_diagnostics_for_server(
12096        &mut self,
12097        server_id: LanguageServerId,
12098        source_buffer_id: Option<BufferId>,
12099        cx: &mut Context<Self>,
12100    ) -> Shared<Task<()>> {
12101        let Some(local) = self.as_local_mut() else {
12102            return Task::ready(()).shared();
12103        };
12104        let mut buffers_to_refresh = HashSet::default();
12105        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12106            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12107                buffers_to_refresh.insert(*buffer_id);
12108            }
12109        }
12110
12111        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12112    }
12113
12114    pub fn pull_document_diagnostics_for_buffer_edit(
12115        &mut self,
12116        buffer_id: BufferId,
12117        cx: &mut Context<Self>,
12118    ) {
12119        let Some(local) = self.as_local_mut() else {
12120            return;
12121        };
12122        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12123        else {
12124            return;
12125        };
12126        for server_id in languages_servers {
12127            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12128        }
12129    }
12130
12131    fn apply_workspace_diagnostic_report(
12132        &mut self,
12133        server_id: LanguageServerId,
12134        report: lsp::WorkspaceDiagnosticReportResult,
12135        registration_id: Option<SharedString>,
12136        cx: &mut Context<Self>,
12137    ) {
12138        let mut workspace_diagnostics =
12139            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12140                report,
12141                server_id,
12142                registration_id,
12143            );
12144        workspace_diagnostics.retain(|d| match &d.diagnostics {
12145            LspPullDiagnostics::Response {
12146                server_id,
12147                registration_id,
12148                ..
12149            } => self.diagnostic_registration_exists(*server_id, registration_id),
12150            LspPullDiagnostics::Default => false,
12151        });
12152        let mut unchanged_buffers = HashMap::default();
12153        let workspace_diagnostics_updates = workspace_diagnostics
12154            .into_iter()
12155            .filter_map(
12156                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12157                    LspPullDiagnostics::Response {
12158                        server_id,
12159                        uri,
12160                        diagnostics,
12161                        registration_id,
12162                    } => Some((
12163                        server_id,
12164                        uri,
12165                        diagnostics,
12166                        workspace_diagnostics.version,
12167                        registration_id,
12168                    )),
12169                    LspPullDiagnostics::Default => None,
12170                },
12171            )
12172            .fold(
12173                HashMap::default(),
12174                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12175                    let (result_id, diagnostics) = match diagnostics {
12176                        PulledDiagnostics::Unchanged { result_id } => {
12177                            unchanged_buffers
12178                                .entry(new_registration_id.clone())
12179                                .or_insert_with(HashSet::default)
12180                                .insert(uri.clone());
12181                            (Some(result_id), Vec::new())
12182                        }
12183                        PulledDiagnostics::Changed {
12184                            result_id,
12185                            diagnostics,
12186                        } => (result_id, diagnostics),
12187                    };
12188                    let disk_based_sources = Cow::Owned(
12189                        self.language_server_adapter_for_id(server_id)
12190                            .as_ref()
12191                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12192                            .unwrap_or(&[])
12193                            .to_vec(),
12194                    );
12195
12196                    let Some(abs_path) = uri.to_file_path().ok() else {
12197                        return acc;
12198                    };
12199                    let Some((worktree, relative_path)) =
12200                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12201                    else {
12202                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12203                        return acc;
12204                    };
12205                    let worktree_id = worktree.read(cx).id();
12206                    let project_path = ProjectPath {
12207                        worktree_id,
12208                        path: relative_path,
12209                    };
12210                    if let Some(local_lsp_store) = self.as_local_mut() {
12211                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12212                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12213                    }
12214                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12215                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12216                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12217                        acc.entry(server_id)
12218                            .or_insert_with(HashMap::default)
12219                            .entry(new_registration_id.clone())
12220                            .or_insert_with(Vec::new)
12221                            .push(DocumentDiagnosticsUpdate {
12222                                server_id,
12223                                diagnostics: lsp::PublishDiagnosticsParams {
12224                                    uri,
12225                                    diagnostics,
12226                                    version,
12227                                },
12228                                result_id: result_id.map(SharedString::new),
12229                                disk_based_sources,
12230                                registration_id: new_registration_id,
12231                            });
12232                    }
12233                    acc
12234                },
12235            );
12236
12237        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12238            for (registration_id, diagnostic_updates) in diagnostic_updates {
12239                self.merge_lsp_diagnostics(
12240                    DiagnosticSourceKind::Pulled,
12241                    diagnostic_updates,
12242                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12243                        DiagnosticSourceKind::Pulled => {
12244                            old_diagnostic.registration_id != registration_id
12245                                || unchanged_buffers
12246                                    .get(&old_diagnostic.registration_id)
12247                                    .is_some_and(|unchanged_buffers| {
12248                                        unchanged_buffers.contains(&document_uri)
12249                                    })
12250                        }
12251                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12252                    },
12253                    cx,
12254                )
12255                .log_err();
12256            }
12257        }
12258    }
12259
12260    fn register_server_capabilities(
12261        &mut self,
12262        server_id: LanguageServerId,
12263        params: lsp::RegistrationParams,
12264        cx: &mut Context<Self>,
12265    ) -> anyhow::Result<()> {
12266        let server = self
12267            .language_server_for_id(server_id)
12268            .with_context(|| format!("no server {server_id} found"))?;
12269        for reg in params.registrations {
12270            match reg.method.as_str() {
12271                "workspace/didChangeWatchedFiles" => {
12272                    if let Some(options) = reg.register_options {
12273                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12274                            let caps = serde_json::from_value(options)?;
12275                            local_lsp_store
12276                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12277                            true
12278                        } else {
12279                            false
12280                        };
12281                        if notify {
12282                            notify_server_capabilities_updated(&server, cx);
12283                        }
12284                    }
12285                }
12286                "workspace/didChangeConfiguration" => {
12287                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12288                }
12289                "workspace/didChangeWorkspaceFolders" => {
12290                    // In this case register options is an empty object, we can ignore it
12291                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12292                        supported: Some(true),
12293                        change_notifications: Some(OneOf::Right(reg.id)),
12294                    };
12295                    server.update_capabilities(|capabilities| {
12296                        capabilities
12297                            .workspace
12298                            .get_or_insert_default()
12299                            .workspace_folders = Some(caps);
12300                    });
12301                    notify_server_capabilities_updated(&server, cx);
12302                }
12303                "workspace/symbol" => {
12304                    let options = parse_register_capabilities(reg)?;
12305                    server.update_capabilities(|capabilities| {
12306                        capabilities.workspace_symbol_provider = Some(options);
12307                    });
12308                    notify_server_capabilities_updated(&server, cx);
12309                }
12310                "workspace/fileOperations" => {
12311                    if let Some(options) = reg.register_options {
12312                        let caps = serde_json::from_value(options)?;
12313                        server.update_capabilities(|capabilities| {
12314                            capabilities
12315                                .workspace
12316                                .get_or_insert_default()
12317                                .file_operations = Some(caps);
12318                        });
12319                        notify_server_capabilities_updated(&server, cx);
12320                    }
12321                }
12322                "workspace/executeCommand" => {
12323                    if let Some(options) = reg.register_options {
12324                        let options = serde_json::from_value(options)?;
12325                        server.update_capabilities(|capabilities| {
12326                            capabilities.execute_command_provider = Some(options);
12327                        });
12328                        notify_server_capabilities_updated(&server, cx);
12329                    }
12330                }
12331                "textDocument/rangeFormatting" => {
12332                    let options = parse_register_capabilities(reg)?;
12333                    server.update_capabilities(|capabilities| {
12334                        capabilities.document_range_formatting_provider = Some(options);
12335                    });
12336                    notify_server_capabilities_updated(&server, cx);
12337                }
12338                "textDocument/onTypeFormatting" => {
12339                    if let Some(options) = reg
12340                        .register_options
12341                        .map(serde_json::from_value)
12342                        .transpose()?
12343                    {
12344                        server.update_capabilities(|capabilities| {
12345                            capabilities.document_on_type_formatting_provider = Some(options);
12346                        });
12347                        notify_server_capabilities_updated(&server, cx);
12348                    }
12349                }
12350                "textDocument/formatting" => {
12351                    let options = parse_register_capabilities(reg)?;
12352                    server.update_capabilities(|capabilities| {
12353                        capabilities.document_formatting_provider = Some(options);
12354                    });
12355                    notify_server_capabilities_updated(&server, cx);
12356                }
12357                "textDocument/rename" => {
12358                    let options = parse_register_capabilities(reg)?;
12359                    server.update_capabilities(|capabilities| {
12360                        capabilities.rename_provider = Some(options);
12361                    });
12362                    notify_server_capabilities_updated(&server, cx);
12363                }
12364                "textDocument/inlayHint" => {
12365                    let options = parse_register_capabilities(reg)?;
12366                    server.update_capabilities(|capabilities| {
12367                        capabilities.inlay_hint_provider = Some(options);
12368                    });
12369                    notify_server_capabilities_updated(&server, cx);
12370                }
12371                "textDocument/documentSymbol" => {
12372                    let options = parse_register_capabilities(reg)?;
12373                    server.update_capabilities(|capabilities| {
12374                        capabilities.document_symbol_provider = Some(options);
12375                    });
12376                    notify_server_capabilities_updated(&server, cx);
12377                }
12378                "textDocument/codeAction" => {
12379                    let options = parse_register_capabilities(reg)?;
12380                    let provider = match options {
12381                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12382                        OneOf::Right(caps) => caps,
12383                    };
12384                    server.update_capabilities(|capabilities| {
12385                        capabilities.code_action_provider = Some(provider);
12386                    });
12387                    notify_server_capabilities_updated(&server, cx);
12388                }
12389                "textDocument/definition" => {
12390                    let options = parse_register_capabilities(reg)?;
12391                    server.update_capabilities(|capabilities| {
12392                        capabilities.definition_provider = Some(options);
12393                    });
12394                    notify_server_capabilities_updated(&server, cx);
12395                }
12396                "textDocument/completion" => {
12397                    if let Some(caps) = reg
12398                        .register_options
12399                        .map(serde_json::from_value::<CompletionOptions>)
12400                        .transpose()?
12401                    {
12402                        server.update_capabilities(|capabilities| {
12403                            capabilities.completion_provider = Some(caps.clone());
12404                        });
12405
12406                        if let Some(local) = self.as_local() {
12407                            let mut buffers_with_language_server = Vec::new();
12408                            for handle in self.buffer_store.read(cx).buffers() {
12409                                let buffer_id = handle.read(cx).remote_id();
12410                                if local
12411                                    .buffers_opened_in_servers
12412                                    .get(&buffer_id)
12413                                    .filter(|s| s.contains(&server_id))
12414                                    .is_some()
12415                                {
12416                                    buffers_with_language_server.push(handle);
12417                                }
12418                            }
12419                            let triggers = caps
12420                                .trigger_characters
12421                                .unwrap_or_default()
12422                                .into_iter()
12423                                .collect::<BTreeSet<_>>();
12424                            for handle in buffers_with_language_server {
12425                                let triggers = triggers.clone();
12426                                let _ = handle.update(cx, move |buffer, cx| {
12427                                    buffer.set_completion_triggers(server_id, triggers, cx);
12428                                });
12429                            }
12430                        }
12431                        notify_server_capabilities_updated(&server, cx);
12432                    }
12433                }
12434                "textDocument/hover" => {
12435                    let options = parse_register_capabilities(reg)?;
12436                    let provider = match options {
12437                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12438                        OneOf::Right(caps) => caps,
12439                    };
12440                    server.update_capabilities(|capabilities| {
12441                        capabilities.hover_provider = Some(provider);
12442                    });
12443                    notify_server_capabilities_updated(&server, cx);
12444                }
12445                "textDocument/signatureHelp" => {
12446                    if let Some(caps) = reg
12447                        .register_options
12448                        .map(serde_json::from_value)
12449                        .transpose()?
12450                    {
12451                        server.update_capabilities(|capabilities| {
12452                            capabilities.signature_help_provider = Some(caps);
12453                        });
12454                        notify_server_capabilities_updated(&server, cx);
12455                    }
12456                }
12457                "textDocument/didChange" => {
12458                    if let Some(sync_kind) = reg
12459                        .register_options
12460                        .and_then(|opts| opts.get("syncKind").cloned())
12461                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12462                        .transpose()?
12463                    {
12464                        server.update_capabilities(|capabilities| {
12465                            let mut sync_options =
12466                                Self::take_text_document_sync_options(capabilities);
12467                            sync_options.change = Some(sync_kind);
12468                            capabilities.text_document_sync =
12469                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12470                        });
12471                        notify_server_capabilities_updated(&server, cx);
12472                    }
12473                }
12474                "textDocument/didSave" => {
12475                    if let Some(include_text) = reg
12476                        .register_options
12477                        .map(|opts| {
12478                            let transpose = opts
12479                                .get("includeText")
12480                                .cloned()
12481                                .map(serde_json::from_value::<Option<bool>>)
12482                                .transpose();
12483                            match transpose {
12484                                Ok(value) => Ok(value.flatten()),
12485                                Err(e) => Err(e),
12486                            }
12487                        })
12488                        .transpose()?
12489                    {
12490                        server.update_capabilities(|capabilities| {
12491                            let mut sync_options =
12492                                Self::take_text_document_sync_options(capabilities);
12493                            sync_options.save =
12494                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12495                                    include_text,
12496                                }));
12497                            capabilities.text_document_sync =
12498                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12499                        });
12500                        notify_server_capabilities_updated(&server, cx);
12501                    }
12502                }
12503                "textDocument/codeLens" => {
12504                    if let Some(caps) = reg
12505                        .register_options
12506                        .map(serde_json::from_value)
12507                        .transpose()?
12508                    {
12509                        server.update_capabilities(|capabilities| {
12510                            capabilities.code_lens_provider = Some(caps);
12511                        });
12512                        notify_server_capabilities_updated(&server, cx);
12513                    }
12514                }
12515                "textDocument/diagnostic" => {
12516                    if let Some(caps) = reg
12517                        .register_options
12518                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12519                        .transpose()?
12520                    {
12521                        let local = self
12522                            .as_local_mut()
12523                            .context("Expected LSP Store to be local")?;
12524                        let state = local
12525                            .language_servers
12526                            .get_mut(&server_id)
12527                            .context("Could not obtain Language Servers state")?;
12528                        local
12529                            .language_server_dynamic_registrations
12530                            .entry(server_id)
12531                            .or_default()
12532                            .diagnostics
12533                            .insert(Some(reg.id.clone()), caps.clone());
12534
12535                        let supports_workspace_diagnostics =
12536                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12537                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12538                                    diagnostic_options.workspace_diagnostics
12539                                }
12540                                DiagnosticServerCapabilities::RegistrationOptions(
12541                                    diagnostic_registration_options,
12542                                ) => {
12543                                    diagnostic_registration_options
12544                                        .diagnostic_options
12545                                        .workspace_diagnostics
12546                                }
12547                            };
12548
12549                        if supports_workspace_diagnostics(&caps) {
12550                            if let LanguageServerState::Running {
12551                                workspace_diagnostics_refresh_tasks,
12552                                ..
12553                            } = state
12554                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12555                                    Some(reg.id.clone()),
12556                                    caps.clone(),
12557                                    server.clone(),
12558                                    cx,
12559                                )
12560                            {
12561                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12562                            }
12563                        }
12564
12565                        server.update_capabilities(|capabilities| {
12566                            capabilities.diagnostic_provider = Some(caps);
12567                        });
12568
12569                        notify_server_capabilities_updated(&server, cx);
12570
12571                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12572                    }
12573                }
12574                "textDocument/documentColor" => {
12575                    let options = parse_register_capabilities(reg)?;
12576                    let provider = match options {
12577                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12578                        OneOf::Right(caps) => caps,
12579                    };
12580                    server.update_capabilities(|capabilities| {
12581                        capabilities.color_provider = Some(provider);
12582                    });
12583                    notify_server_capabilities_updated(&server, cx);
12584                }
12585                "textDocument/foldingRange" => {
12586                    let options = parse_register_capabilities(reg)?;
12587                    let provider = match options {
12588                        OneOf::Left(value) => lsp::FoldingRangeProviderCapability::Simple(value),
12589                        OneOf::Right(caps) => caps,
12590                    };
12591                    server.update_capabilities(|capabilities| {
12592                        capabilities.folding_range_provider = Some(provider);
12593                    });
12594                    notify_server_capabilities_updated(&server, cx);
12595                }
12596                _ => log::warn!("unhandled capability registration: {reg:?}"),
12597            }
12598        }
12599
12600        Ok(())
12601    }
12602
12603    fn unregister_server_capabilities(
12604        &mut self,
12605        server_id: LanguageServerId,
12606        params: lsp::UnregistrationParams,
12607        cx: &mut Context<Self>,
12608    ) -> anyhow::Result<()> {
12609        let server = self
12610            .language_server_for_id(server_id)
12611            .with_context(|| format!("no server {server_id} found"))?;
12612        for unreg in params.unregisterations.iter() {
12613            match unreg.method.as_str() {
12614                "workspace/didChangeWatchedFiles" => {
12615                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12616                        local_lsp_store
12617                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12618                        true
12619                    } else {
12620                        false
12621                    };
12622                    if notify {
12623                        notify_server_capabilities_updated(&server, cx);
12624                    }
12625                }
12626                "workspace/didChangeConfiguration" => {
12627                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12628                }
12629                "workspace/didChangeWorkspaceFolders" => {
12630                    server.update_capabilities(|capabilities| {
12631                        capabilities
12632                            .workspace
12633                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12634                                workspace_folders: None,
12635                                file_operations: None,
12636                            })
12637                            .workspace_folders = None;
12638                    });
12639                    notify_server_capabilities_updated(&server, cx);
12640                }
12641                "workspace/symbol" => {
12642                    server.update_capabilities(|capabilities| {
12643                        capabilities.workspace_symbol_provider = None
12644                    });
12645                    notify_server_capabilities_updated(&server, cx);
12646                }
12647                "workspace/fileOperations" => {
12648                    server.update_capabilities(|capabilities| {
12649                        capabilities
12650                            .workspace
12651                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12652                                workspace_folders: None,
12653                                file_operations: None,
12654                            })
12655                            .file_operations = None;
12656                    });
12657                    notify_server_capabilities_updated(&server, cx);
12658                }
12659                "workspace/executeCommand" => {
12660                    server.update_capabilities(|capabilities| {
12661                        capabilities.execute_command_provider = None;
12662                    });
12663                    notify_server_capabilities_updated(&server, cx);
12664                }
12665                "textDocument/rangeFormatting" => {
12666                    server.update_capabilities(|capabilities| {
12667                        capabilities.document_range_formatting_provider = None
12668                    });
12669                    notify_server_capabilities_updated(&server, cx);
12670                }
12671                "textDocument/onTypeFormatting" => {
12672                    server.update_capabilities(|capabilities| {
12673                        capabilities.document_on_type_formatting_provider = None;
12674                    });
12675                    notify_server_capabilities_updated(&server, cx);
12676                }
12677                "textDocument/formatting" => {
12678                    server.update_capabilities(|capabilities| {
12679                        capabilities.document_formatting_provider = None;
12680                    });
12681                    notify_server_capabilities_updated(&server, cx);
12682                }
12683                "textDocument/rename" => {
12684                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12685                    notify_server_capabilities_updated(&server, cx);
12686                }
12687                "textDocument/codeAction" => {
12688                    server.update_capabilities(|capabilities| {
12689                        capabilities.code_action_provider = None;
12690                    });
12691                    notify_server_capabilities_updated(&server, cx);
12692                }
12693                "textDocument/definition" => {
12694                    server.update_capabilities(|capabilities| {
12695                        capabilities.definition_provider = None;
12696                    });
12697                    notify_server_capabilities_updated(&server, cx);
12698                }
12699                "textDocument/completion" => {
12700                    server.update_capabilities(|capabilities| {
12701                        capabilities.completion_provider = None;
12702                    });
12703                    notify_server_capabilities_updated(&server, cx);
12704                }
12705                "textDocument/hover" => {
12706                    server.update_capabilities(|capabilities| {
12707                        capabilities.hover_provider = None;
12708                    });
12709                    notify_server_capabilities_updated(&server, cx);
12710                }
12711                "textDocument/signatureHelp" => {
12712                    server.update_capabilities(|capabilities| {
12713                        capabilities.signature_help_provider = None;
12714                    });
12715                    notify_server_capabilities_updated(&server, cx);
12716                }
12717                "textDocument/didChange" => {
12718                    server.update_capabilities(|capabilities| {
12719                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12720                        sync_options.change = None;
12721                        capabilities.text_document_sync =
12722                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12723                    });
12724                    notify_server_capabilities_updated(&server, cx);
12725                }
12726                "textDocument/didSave" => {
12727                    server.update_capabilities(|capabilities| {
12728                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12729                        sync_options.save = None;
12730                        capabilities.text_document_sync =
12731                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12732                    });
12733                    notify_server_capabilities_updated(&server, cx);
12734                }
12735                "textDocument/codeLens" => {
12736                    server.update_capabilities(|capabilities| {
12737                        capabilities.code_lens_provider = None;
12738                    });
12739                    notify_server_capabilities_updated(&server, cx);
12740                }
12741                "textDocument/diagnostic" => {
12742                    let local = self
12743                        .as_local_mut()
12744                        .context("Expected LSP Store to be local")?;
12745
12746                    let state = local
12747                        .language_servers
12748                        .get_mut(&server_id)
12749                        .context("Could not obtain Language Servers state")?;
12750                    let registrations = local
12751                        .language_server_dynamic_registrations
12752                        .get_mut(&server_id)
12753                        .with_context(|| {
12754                            format!("Expected dynamic registration to exist for server {server_id}")
12755                        })?;
12756                    registrations.diagnostics
12757                        .remove(&Some(unreg.id.clone()))
12758                        .with_context(|| format!(
12759                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12760                            unreg.id)
12761                        )?;
12762                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12763
12764                    if let LanguageServerState::Running {
12765                        workspace_diagnostics_refresh_tasks,
12766                        ..
12767                    } = state
12768                    {
12769                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12770                    }
12771
12772                    self.clear_unregistered_diagnostics(
12773                        server_id,
12774                        SharedString::from(unreg.id.clone()),
12775                        cx,
12776                    )?;
12777
12778                    if removed_last_diagnostic_provider {
12779                        server.update_capabilities(|capabilities| {
12780                            debug_assert!(capabilities.diagnostic_provider.is_some());
12781                            capabilities.diagnostic_provider = None;
12782                        });
12783                    }
12784
12785                    notify_server_capabilities_updated(&server, cx);
12786                }
12787                "textDocument/documentColor" => {
12788                    server.update_capabilities(|capabilities| {
12789                        capabilities.color_provider = None;
12790                    });
12791                    notify_server_capabilities_updated(&server, cx);
12792                }
12793                "textDocument/foldingRange" => {
12794                    server.update_capabilities(|capabilities| {
12795                        capabilities.folding_range_provider = None;
12796                    });
12797                    notify_server_capabilities_updated(&server, cx);
12798                }
12799                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12800            }
12801        }
12802
12803        Ok(())
12804    }
12805
12806    fn clear_unregistered_diagnostics(
12807        &mut self,
12808        server_id: LanguageServerId,
12809        cleared_registration_id: SharedString,
12810        cx: &mut Context<Self>,
12811    ) -> anyhow::Result<()> {
12812        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12813
12814        self.buffer_store.update(cx, |buffer_store, cx| {
12815            for buffer_handle in buffer_store.buffers() {
12816                let buffer = buffer_handle.read(cx);
12817                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12818                let Some(abs_path) = abs_path else {
12819                    continue;
12820                };
12821                affected_abs_paths.insert(abs_path);
12822            }
12823        });
12824
12825        let local = self.as_local().context("Expected LSP Store to be local")?;
12826        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12827            let Some(worktree) = self
12828                .worktree_store
12829                .read(cx)
12830                .worktree_for_id(*worktree_id, cx)
12831            else {
12832                continue;
12833            };
12834
12835            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
12836                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
12837                    let has_matching_registration =
12838                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
12839                            entry.diagnostic.registration_id.as_ref()
12840                                == Some(&cleared_registration_id)
12841                        });
12842                    if has_matching_registration {
12843                        let abs_path = worktree.read(cx).absolutize(rel_path);
12844                        affected_abs_paths.insert(abs_path);
12845                    }
12846                }
12847            }
12848        }
12849
12850        if affected_abs_paths.is_empty() {
12851            return Ok(());
12852        }
12853
12854        // Send a fake diagnostic update which clears the state for the registration ID
12855        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
12856            affected_abs_paths
12857                .into_iter()
12858                .map(|abs_path| DocumentDiagnosticsUpdate {
12859                    diagnostics: DocumentDiagnostics {
12860                        diagnostics: Vec::new(),
12861                        document_abs_path: abs_path,
12862                        version: None,
12863                    },
12864                    result_id: None,
12865                    registration_id: Some(cleared_registration_id.clone()),
12866                    server_id,
12867                    disk_based_sources: Cow::Borrowed(&[]),
12868                })
12869                .collect();
12870
12871        let merge_registration_id = cleared_registration_id.clone();
12872        self.merge_diagnostic_entries(
12873            clears,
12874            move |_, diagnostic, _| {
12875                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
12876                    diagnostic.registration_id != Some(merge_registration_id.clone())
12877                } else {
12878                    true
12879                }
12880            },
12881            cx,
12882        )?;
12883
12884        Ok(())
12885    }
12886
12887    async fn deduplicate_range_based_lsp_requests<T>(
12888        lsp_store: &Entity<Self>,
12889        server_id: Option<LanguageServerId>,
12890        lsp_request_id: LspRequestId,
12891        proto_request: &T::ProtoRequest,
12892        range: Range<Anchor>,
12893        cx: &mut AsyncApp,
12894    ) -> Result<()>
12895    where
12896        T: LspCommand,
12897        T::ProtoRequest: proto::LspRequestMessage,
12898    {
12899        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12900        let version = deserialize_version(proto_request.buffer_version());
12901        let buffer = lsp_store.update(cx, |this, cx| {
12902            this.buffer_store.read(cx).get_existing(buffer_id)
12903        })?;
12904        buffer
12905            .update(cx, |buffer, _| buffer.wait_for_version(version))
12906            .await?;
12907        lsp_store.update(cx, |lsp_store, cx| {
12908            let buffer_snapshot = buffer.read(cx).snapshot();
12909            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12910            let chunks_queried_for = lsp_data
12911                .inlay_hints
12912                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
12913                .collect::<Vec<_>>();
12914            match chunks_queried_for.as_slice() {
12915                &[chunk] => {
12916                    let key = LspKey {
12917                        request_type: TypeId::of::<T>(),
12918                        server_queried: server_id,
12919                    };
12920                    let previous_request = lsp_data
12921                        .chunk_lsp_requests
12922                        .entry(key)
12923                        .or_default()
12924                        .insert(chunk, lsp_request_id);
12925                    if let Some((previous_request, running_requests)) =
12926                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12927                    {
12928                        running_requests.remove(&previous_request);
12929                    }
12930                }
12931                _ambiguous_chunks => {
12932                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12933                    // there, a buffer version-based check will be performed and outdated requests discarded.
12934                }
12935            }
12936            anyhow::Ok(())
12937        })?;
12938
12939        Ok(())
12940    }
12941
12942    async fn query_lsp_locally<T>(
12943        lsp_store: Entity<Self>,
12944        for_server_id: Option<LanguageServerId>,
12945        sender_id: proto::PeerId,
12946        lsp_request_id: LspRequestId,
12947        proto_request: T::ProtoRequest,
12948        position: Option<Anchor>,
12949        cx: &mut AsyncApp,
12950    ) -> Result<()>
12951    where
12952        T: LspCommand + Clone,
12953        T::ProtoRequest: proto::LspRequestMessage,
12954        <T::ProtoRequest as proto::RequestMessage>::Response:
12955            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12956    {
12957        let (buffer_version, buffer) =
12958            Self::wait_for_buffer_version::<T>(&lsp_store, &proto_request, cx).await?;
12959        let request =
12960            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12961        let key = LspKey {
12962            request_type: TypeId::of::<T>(),
12963            server_queried: for_server_id,
12964        };
12965        lsp_store.update(cx, |lsp_store, cx| {
12966            let request_task = match for_server_id {
12967                Some(server_id) => {
12968                    let server_task = lsp_store.request_lsp(
12969                        buffer.clone(),
12970                        LanguageServerToQuery::Other(server_id),
12971                        request.clone(),
12972                        cx,
12973                    );
12974                    cx.background_spawn(async move {
12975                        let mut responses = Vec::new();
12976                        match server_task.await {
12977                            Ok(response) => responses.push((server_id, response)),
12978                            // rust-analyzer likes to error with this when its still loading up
12979                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
12980                            Err(e) => log::error!(
12981                                "Error handling response for request {request:?}: {e:#}"
12982                            ),
12983                        }
12984                        responses
12985                    })
12986                }
12987                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12988            };
12989            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12990            if T::ProtoRequest::stop_previous_requests() {
12991                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12992                    lsp_requests.clear();
12993                }
12994            }
12995            lsp_data.lsp_requests.entry(key).or_default().insert(
12996                lsp_request_id,
12997                cx.spawn(async move |lsp_store, cx| {
12998                    let response = request_task.await;
12999                    lsp_store
13000                        .update(cx, |lsp_store, cx| {
13001                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13002                            {
13003                                let response = response
13004                                    .into_iter()
13005                                    .map(|(server_id, response)| {
13006                                        (
13007                                            server_id.to_proto(),
13008                                            T::response_to_proto(
13009                                                response,
13010                                                lsp_store,
13011                                                sender_id,
13012                                                &buffer_version,
13013                                                cx,
13014                                            )
13015                                            .into(),
13016                                        )
13017                                    })
13018                                    .collect::<HashMap<_, _>>();
13019                                match client.send_lsp_response::<T::ProtoRequest>(
13020                                    project_id,
13021                                    lsp_request_id,
13022                                    response,
13023                                ) {
13024                                    Ok(()) => {}
13025                                    Err(e) => {
13026                                        log::error!("Failed to send LSP response: {e:#}",)
13027                                    }
13028                                }
13029                            }
13030                        })
13031                        .ok();
13032                }),
13033            );
13034        });
13035        Ok(())
13036    }
13037
13038    async fn wait_for_buffer_version<T>(
13039        lsp_store: &Entity<Self>,
13040        proto_request: &T::ProtoRequest,
13041        cx: &mut AsyncApp,
13042    ) -> Result<(Global, Entity<Buffer>)>
13043    where
13044        T: LspCommand,
13045        T::ProtoRequest: proto::LspRequestMessage,
13046    {
13047        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13048        let version = deserialize_version(proto_request.buffer_version());
13049        let buffer = lsp_store.update(cx, |this, cx| {
13050            this.buffer_store.read(cx).get_existing(buffer_id)
13051        })?;
13052        buffer
13053            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13054            .await?;
13055        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13056        Ok((buffer_version, buffer))
13057    }
13058
13059    fn take_text_document_sync_options(
13060        capabilities: &mut lsp::ServerCapabilities,
13061    ) -> lsp::TextDocumentSyncOptions {
13062        match capabilities.text_document_sync.take() {
13063            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13064            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13065                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13066                sync_options.change = Some(sync_kind);
13067                sync_options
13068            }
13069            None => lsp::TextDocumentSyncOptions::default(),
13070        }
13071    }
13072
13073    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13074        self.downstream_client.clone()
13075    }
13076
13077    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13078        self.worktree_store.clone()
13079    }
13080
13081    /// Gets what's stored in the LSP data for the given buffer.
13082    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13083        self.lsp_data.get_mut(&buffer_id)
13084    }
13085
13086    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13087    /// new [`BufferLspData`] will be created to replace the previous state.
13088    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13089        let (buffer_id, buffer_version) =
13090            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13091        let lsp_data = self
13092            .lsp_data
13093            .entry(buffer_id)
13094            .or_insert_with(|| BufferLspData::new(buffer, cx));
13095        if buffer_version.changed_since(&lsp_data.buffer_version) {
13096            // To send delta requests for semantic tokens, the previous tokens
13097            // need to be kept between buffer changes.
13098            let semantic_tokens = lsp_data.semantic_tokens.take();
13099            *lsp_data = BufferLspData::new(buffer, cx);
13100            lsp_data.semantic_tokens = semantic_tokens;
13101        }
13102        lsp_data
13103    }
13104}
13105
13106// Registration with registerOptions as null, should fallback to true.
13107// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13108fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13109    reg: lsp::Registration,
13110) -> Result<OneOf<bool, T>> {
13111    Ok(match reg.register_options {
13112        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13113        None => OneOf::Left(true),
13114    })
13115}
13116
13117fn subscribe_to_binary_statuses(
13118    languages: &Arc<LanguageRegistry>,
13119    cx: &mut Context<'_, LspStore>,
13120) -> Task<()> {
13121    let mut server_statuses = languages.language_server_binary_statuses();
13122    cx.spawn(async move |lsp_store, cx| {
13123        while let Some((server_name, binary_status)) = server_statuses.next().await {
13124            if lsp_store
13125                .update(cx, |_, cx| {
13126                    let mut message = None;
13127                    let binary_status = match binary_status {
13128                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13129                        BinaryStatus::CheckingForUpdate => {
13130                            proto::ServerBinaryStatus::CheckingForUpdate
13131                        }
13132                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13133                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13134                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13135                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13136                        BinaryStatus::Failed { error } => {
13137                            message = Some(error);
13138                            proto::ServerBinaryStatus::Failed
13139                        }
13140                    };
13141                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13142                        // Binary updates are about the binary that might not have any language server id at that point.
13143                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13144                        language_server_id: LanguageServerId(0),
13145                        name: Some(server_name),
13146                        message: proto::update_language_server::Variant::StatusUpdate(
13147                            proto::StatusUpdate {
13148                                message,
13149                                status: Some(proto::status_update::Status::Binary(
13150                                    binary_status as i32,
13151                                )),
13152                            },
13153                        ),
13154                    });
13155                })
13156                .is_err()
13157            {
13158                break;
13159            }
13160        }
13161    })
13162}
13163
13164fn lsp_workspace_diagnostics_refresh(
13165    registration_id: Option<String>,
13166    options: DiagnosticServerCapabilities,
13167    server: Arc<LanguageServer>,
13168    cx: &mut Context<'_, LspStore>,
13169) -> Option<WorkspaceRefreshTask> {
13170    let identifier = workspace_diagnostic_identifier(&options)?;
13171    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13172
13173    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13174    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13175    refresh_tx.try_send(()).ok();
13176
13177    let request_timeout = ProjectSettings::get_global(cx)
13178        .global_lsp_settings
13179        .get_request_timeout();
13180
13181    // 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.
13182    // This allows users to increase the duration if need be
13183    let timeout = if request_timeout != Duration::ZERO {
13184        request_timeout.max(DEFAULT_LSP_REQUEST_TIMEOUT)
13185    } else {
13186        request_timeout
13187    };
13188
13189    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13190        let mut attempts = 0;
13191        let max_attempts = 50;
13192        let mut requests = 0;
13193
13194        loop {
13195            let Some(()) = refresh_rx.recv().await else {
13196                return;
13197            };
13198
13199            'request: loop {
13200                requests += 1;
13201                if attempts > max_attempts {
13202                    log::error!(
13203                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13204                    );
13205                    return;
13206                }
13207                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13208                cx.background_executor()
13209                    .timer(Duration::from_millis(backoff_millis))
13210                    .await;
13211                attempts += 1;
13212
13213                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13214                    lsp_store
13215                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13216                        .into_iter()
13217                        .filter_map(|(abs_path, result_id)| {
13218                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13219                            Some(lsp::PreviousResultId {
13220                                uri,
13221                                value: result_id.to_string(),
13222                            })
13223                        })
13224                        .collect()
13225                }) else {
13226                    return;
13227                };
13228
13229                let token = if let Some(registration_id) = &registration_id {
13230                    format!(
13231                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13232                        server.server_id(),
13233                    )
13234                } else {
13235                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13236                };
13237
13238                progress_rx.try_recv().ok();
13239                let timer = server.request_timer(timeout).fuse();
13240                let progress = pin!(progress_rx.recv().fuse());
13241                let response_result = server
13242                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13243                        lsp::WorkspaceDiagnosticParams {
13244                            previous_result_ids,
13245                            identifier: identifier.clone(),
13246                            work_done_progress_params: Default::default(),
13247                            partial_result_params: lsp::PartialResultParams {
13248                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13249                            },
13250                        },
13251                        select(timer, progress).then(|either| match either {
13252                            Either::Left((message, ..)) => ready(message).left_future(),
13253                            Either::Right(..) => pending::<String>().right_future(),
13254                        }),
13255                    )
13256                    .await;
13257
13258                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13259                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13260                match response_result {
13261                    ConnectionResult::Timeout => {
13262                        log::error!("Timeout during workspace diagnostics pull");
13263                        continue 'request;
13264                    }
13265                    ConnectionResult::ConnectionReset => {
13266                        log::error!("Server closed a workspace diagnostics pull request");
13267                        continue 'request;
13268                    }
13269                    ConnectionResult::Result(Err(e)) => {
13270                        log::error!("Error during workspace diagnostics pull: {e:#}");
13271                        break 'request;
13272                    }
13273                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13274                        attempts = 0;
13275                        if lsp_store
13276                            .update(cx, |lsp_store, cx| {
13277                                lsp_store.apply_workspace_diagnostic_report(
13278                                    server.server_id(),
13279                                    pulled_diagnostics,
13280                                    registration_id_shared.clone(),
13281                                    cx,
13282                                )
13283                            })
13284                            .is_err()
13285                        {
13286                            return;
13287                        }
13288                        break 'request;
13289                    }
13290                }
13291            }
13292        }
13293    });
13294
13295    Some(WorkspaceRefreshTask {
13296        refresh_tx,
13297        progress_tx,
13298        task: workspace_query_language_server,
13299    })
13300}
13301
13302fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<SharedString> {
13303    match &options {
13304        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => diagnostic_options
13305            .identifier
13306            .as_deref()
13307            .map(SharedString::new),
13308        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13309            let diagnostic_options = &registration_options.diagnostic_options;
13310            diagnostic_options
13311                .identifier
13312                .as_deref()
13313                .map(SharedString::new)
13314        }
13315    }
13316}
13317
13318fn workspace_diagnostic_identifier(
13319    options: &DiagnosticServerCapabilities,
13320) -> Option<Option<String>> {
13321    match &options {
13322        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13323            if !diagnostic_options.workspace_diagnostics {
13324                return None;
13325            }
13326            Some(diagnostic_options.identifier.clone())
13327        }
13328        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13329            let diagnostic_options = &registration_options.diagnostic_options;
13330            if !diagnostic_options.workspace_diagnostics {
13331                return None;
13332            }
13333            Some(diagnostic_options.identifier.clone())
13334        }
13335    }
13336}
13337
13338fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13339    let CompletionSource::BufferWord {
13340        word_range,
13341        resolved,
13342    } = &mut completion.source
13343    else {
13344        return;
13345    };
13346    if *resolved {
13347        return;
13348    }
13349
13350    if completion.new_text
13351        != snapshot
13352            .text_for_range(word_range.clone())
13353            .collect::<String>()
13354    {
13355        return;
13356    }
13357
13358    let mut offset = 0;
13359    for chunk in snapshot.chunks(word_range.clone(), true) {
13360        let end_offset = offset + chunk.text.len();
13361        if let Some(highlight_id) = chunk.syntax_highlight_id {
13362            completion
13363                .label
13364                .runs
13365                .push((offset..end_offset, highlight_id));
13366        }
13367        offset = end_offset;
13368    }
13369    *resolved = true;
13370}
13371
13372impl EventEmitter<LspStoreEvent> for LspStore {}
13373
13374fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13375    hover
13376        .contents
13377        .retain(|hover_block| !hover_block.text.trim().is_empty());
13378    if hover.contents.is_empty() {
13379        None
13380    } else {
13381        Some(hover)
13382    }
13383}
13384
13385async fn populate_labels_for_completions(
13386    new_completions: Vec<CoreCompletion>,
13387    language: Option<Arc<Language>>,
13388    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13389) -> Vec<Completion> {
13390    let lsp_completions = new_completions
13391        .iter()
13392        .filter_map(|new_completion| {
13393            new_completion
13394                .source
13395                .lsp_completion(true)
13396                .map(|lsp_completion| lsp_completion.into_owned())
13397        })
13398        .collect::<Vec<_>>();
13399
13400    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13401        lsp_adapter
13402            .labels_for_completions(&lsp_completions, language)
13403            .await
13404            .log_err()
13405            .unwrap_or_default()
13406    } else {
13407        Vec::new()
13408    }
13409    .into_iter()
13410    .fuse();
13411
13412    let mut completions = Vec::new();
13413    for completion in new_completions {
13414        match completion.source.lsp_completion(true) {
13415            Some(lsp_completion) => {
13416                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13417
13418                let mut label = labels.next().flatten().unwrap_or_else(|| {
13419                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13420                });
13421                ensure_uniform_list_compatible_label(&mut label);
13422                completions.push(Completion {
13423                    label,
13424                    documentation,
13425                    replace_range: completion.replace_range,
13426                    new_text: completion.new_text,
13427                    insert_text_mode: lsp_completion.insert_text_mode,
13428                    source: completion.source,
13429                    icon_path: None,
13430                    confirm: None,
13431                    match_start: None,
13432                    snippet_deduplication_key: None,
13433                });
13434            }
13435            None => {
13436                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13437                ensure_uniform_list_compatible_label(&mut label);
13438                completions.push(Completion {
13439                    label,
13440                    documentation: None,
13441                    replace_range: completion.replace_range,
13442                    new_text: completion.new_text,
13443                    source: completion.source,
13444                    insert_text_mode: None,
13445                    icon_path: None,
13446                    confirm: None,
13447                    match_start: None,
13448                    snippet_deduplication_key: None,
13449                });
13450            }
13451        }
13452    }
13453    completions
13454}
13455
13456#[derive(Debug)]
13457pub enum LanguageServerToQuery {
13458    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13459    FirstCapable,
13460    /// Query a specific language server.
13461    Other(LanguageServerId),
13462}
13463
13464#[derive(Default)]
13465struct RenamePathsWatchedForServer {
13466    did_rename: Vec<RenameActionPredicate>,
13467    will_rename: Vec<RenameActionPredicate>,
13468}
13469
13470impl RenamePathsWatchedForServer {
13471    fn with_did_rename_patterns(
13472        mut self,
13473        did_rename: Option<&FileOperationRegistrationOptions>,
13474    ) -> Self {
13475        if let Some(did_rename) = did_rename {
13476            self.did_rename = did_rename
13477                .filters
13478                .iter()
13479                .filter_map(|filter| filter.try_into().log_err())
13480                .collect();
13481        }
13482        self
13483    }
13484    fn with_will_rename_patterns(
13485        mut self,
13486        will_rename: Option<&FileOperationRegistrationOptions>,
13487    ) -> Self {
13488        if let Some(will_rename) = will_rename {
13489            self.will_rename = will_rename
13490                .filters
13491                .iter()
13492                .filter_map(|filter| filter.try_into().log_err())
13493                .collect();
13494        }
13495        self
13496    }
13497
13498    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13499        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13500    }
13501    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13502        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13503    }
13504}
13505
13506impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13507    type Error = globset::Error;
13508    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13509        Ok(Self {
13510            kind: ops.pattern.matches.clone(),
13511            glob: GlobBuilder::new(&ops.pattern.glob)
13512                .case_insensitive(
13513                    ops.pattern
13514                        .options
13515                        .as_ref()
13516                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13517                )
13518                .build()?
13519                .compile_matcher(),
13520        })
13521    }
13522}
13523struct RenameActionPredicate {
13524    glob: GlobMatcher,
13525    kind: Option<FileOperationPatternKind>,
13526}
13527
13528impl RenameActionPredicate {
13529    // Returns true if language server should be notified
13530    fn eval(&self, path: &str, is_dir: bool) -> bool {
13531        self.kind.as_ref().is_none_or(|kind| {
13532            let expected_kind = if is_dir {
13533                FileOperationPatternKind::Folder
13534            } else {
13535                FileOperationPatternKind::File
13536            };
13537            kind == &expected_kind
13538        }) && self.glob.is_match(path)
13539    }
13540}
13541
13542#[derive(Default)]
13543struct LanguageServerWatchedPaths {
13544    worktree_paths: HashMap<WorktreeId, GlobSet>,
13545    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13546}
13547
13548#[derive(Default)]
13549struct LanguageServerWatchedPathsBuilder {
13550    worktree_paths: HashMap<WorktreeId, GlobSet>,
13551    abs_paths: HashMap<Arc<Path>, GlobSet>,
13552}
13553
13554impl LanguageServerWatchedPathsBuilder {
13555    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13556        self.worktree_paths.insert(worktree_id, glob_set);
13557    }
13558    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13559        self.abs_paths.insert(path, glob_set);
13560    }
13561    fn build(
13562        self,
13563        fs: Arc<dyn Fs>,
13564        language_server_id: LanguageServerId,
13565        cx: &mut Context<LspStore>,
13566    ) -> LanguageServerWatchedPaths {
13567        let lsp_store = cx.weak_entity();
13568
13569        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13570        let abs_paths = self
13571            .abs_paths
13572            .into_iter()
13573            .map(|(abs_path, globset)| {
13574                let task = cx.spawn({
13575                    let abs_path = abs_path.clone();
13576                    let fs = fs.clone();
13577
13578                    let lsp_store = lsp_store.clone();
13579                    async move |_, cx| {
13580                        maybe!(async move {
13581                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13582                            while let Some(update) = push_updates.0.next().await {
13583                                let action = lsp_store
13584                                    .update(cx, |this, _| {
13585                                        let Some(local) = this.as_local() else {
13586                                            return ControlFlow::Break(());
13587                                        };
13588                                        let Some(watcher) = local
13589                                            .language_server_watched_paths
13590                                            .get(&language_server_id)
13591                                        else {
13592                                            return ControlFlow::Break(());
13593                                        };
13594                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13595                                            "Watched abs path is not registered with a watcher",
13596                                        );
13597                                        let matching_entries = update
13598                                            .into_iter()
13599                                            .filter(|event| globs.is_match(&event.path))
13600                                            .collect::<Vec<_>>();
13601                                        this.lsp_notify_abs_paths_changed(
13602                                            language_server_id,
13603                                            matching_entries,
13604                                        );
13605                                        ControlFlow::Continue(())
13606                                    })
13607                                    .ok()?;
13608
13609                                if action.is_break() {
13610                                    break;
13611                                }
13612                            }
13613                            Some(())
13614                        })
13615                        .await;
13616                    }
13617                });
13618                (abs_path, (globset, task))
13619            })
13620            .collect();
13621        LanguageServerWatchedPaths {
13622            worktree_paths: self.worktree_paths,
13623            abs_paths,
13624        }
13625    }
13626}
13627
13628struct LspBufferSnapshot {
13629    version: i32,
13630    snapshot: TextBufferSnapshot,
13631}
13632
13633/// A prompt requested by LSP server.
13634#[derive(Clone, Debug)]
13635pub struct LanguageServerPromptRequest {
13636    pub id: usize,
13637    pub level: PromptLevel,
13638    pub message: String,
13639    pub actions: Vec<MessageActionItem>,
13640    pub lsp_name: String,
13641    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13642}
13643
13644impl LanguageServerPromptRequest {
13645    pub fn new(
13646        level: PromptLevel,
13647        message: String,
13648        actions: Vec<MessageActionItem>,
13649        lsp_name: String,
13650        response_channel: smol::channel::Sender<MessageActionItem>,
13651    ) -> Self {
13652        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13653        LanguageServerPromptRequest {
13654            id,
13655            level,
13656            message,
13657            actions,
13658            lsp_name,
13659            response_channel,
13660        }
13661    }
13662    pub async fn respond(self, index: usize) -> Option<()> {
13663        if let Some(response) = self.actions.into_iter().nth(index) {
13664            self.response_channel.send(response).await.ok()
13665        } else {
13666            None
13667        }
13668    }
13669
13670    #[cfg(any(test, feature = "test-support"))]
13671    pub fn test(
13672        level: PromptLevel,
13673        message: String,
13674        actions: Vec<MessageActionItem>,
13675        lsp_name: String,
13676    ) -> Self {
13677        let (tx, _rx) = smol::channel::unbounded();
13678        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13679    }
13680}
13681impl PartialEq for LanguageServerPromptRequest {
13682    fn eq(&self, other: &Self) -> bool {
13683        self.message == other.message && self.actions == other.actions
13684    }
13685}
13686
13687#[derive(Clone, Debug, PartialEq)]
13688pub enum LanguageServerLogType {
13689    Log(MessageType),
13690    Trace { verbose_info: Option<String> },
13691    Rpc { received: bool },
13692}
13693
13694impl LanguageServerLogType {
13695    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13696        match self {
13697            Self::Log(log_type) => {
13698                use proto::log_message::LogLevel;
13699                let level = match *log_type {
13700                    MessageType::ERROR => LogLevel::Error,
13701                    MessageType::WARNING => LogLevel::Warning,
13702                    MessageType::INFO => LogLevel::Info,
13703                    MessageType::LOG => LogLevel::Log,
13704                    other => {
13705                        log::warn!("Unknown lsp log message type: {other:?}");
13706                        LogLevel::Log
13707                    }
13708                };
13709                proto::language_server_log::LogType::Log(proto::LogMessage {
13710                    level: level as i32,
13711                })
13712            }
13713            Self::Trace { verbose_info } => {
13714                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13715                    verbose_info: verbose_info.to_owned(),
13716                })
13717            }
13718            Self::Rpc { received } => {
13719                let kind = if *received {
13720                    proto::rpc_message::Kind::Received
13721                } else {
13722                    proto::rpc_message::Kind::Sent
13723                };
13724                let kind = kind as i32;
13725                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13726            }
13727        }
13728    }
13729
13730    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13731        use proto::log_message::LogLevel;
13732        use proto::rpc_message;
13733        match log_type {
13734            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13735                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13736                    LogLevel::Error => MessageType::ERROR,
13737                    LogLevel::Warning => MessageType::WARNING,
13738                    LogLevel::Info => MessageType::INFO,
13739                    LogLevel::Log => MessageType::LOG,
13740                },
13741            ),
13742            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13743                verbose_info: trace_message.verbose_info,
13744            },
13745            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13746                received: match rpc_message::Kind::from_i32(message.kind)
13747                    .unwrap_or(rpc_message::Kind::Received)
13748                {
13749                    rpc_message::Kind::Received => true,
13750                    rpc_message::Kind::Sent => false,
13751                },
13752            },
13753        }
13754    }
13755}
13756
13757pub struct WorkspaceRefreshTask {
13758    refresh_tx: mpsc::Sender<()>,
13759    progress_tx: mpsc::Sender<()>,
13760    #[allow(dead_code)]
13761    task: Task<()>,
13762}
13763
13764pub enum LanguageServerState {
13765    Starting {
13766        startup: Task<Option<Arc<LanguageServer>>>,
13767        /// List of language servers that will be added to the workspace once it's initialization completes.
13768        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13769    },
13770
13771    Running {
13772        adapter: Arc<CachedLspAdapter>,
13773        server: Arc<LanguageServer>,
13774        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13775        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13776    },
13777}
13778
13779impl LanguageServerState {
13780    fn add_workspace_folder(&self, uri: Uri) {
13781        match self {
13782            LanguageServerState::Starting {
13783                pending_workspace_folders,
13784                ..
13785            } => {
13786                pending_workspace_folders.lock().insert(uri);
13787            }
13788            LanguageServerState::Running { server, .. } => {
13789                server.add_workspace_folder(uri);
13790            }
13791        }
13792    }
13793    fn _remove_workspace_folder(&self, uri: Uri) {
13794        match self {
13795            LanguageServerState::Starting {
13796                pending_workspace_folders,
13797                ..
13798            } => {
13799                pending_workspace_folders.lock().remove(&uri);
13800            }
13801            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13802        }
13803    }
13804}
13805
13806impl std::fmt::Debug for LanguageServerState {
13807    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13808        match self {
13809            LanguageServerState::Starting { .. } => {
13810                f.debug_struct("LanguageServerState::Starting").finish()
13811            }
13812            LanguageServerState::Running { .. } => {
13813                f.debug_struct("LanguageServerState::Running").finish()
13814            }
13815        }
13816    }
13817}
13818
13819#[derive(Clone, Debug, Serialize)]
13820pub struct LanguageServerProgress {
13821    pub is_disk_based_diagnostics_progress: bool,
13822    pub is_cancellable: bool,
13823    pub title: Option<String>,
13824    pub message: Option<String>,
13825    pub percentage: Option<usize>,
13826    #[serde(skip_serializing)]
13827    pub last_update_at: Instant,
13828}
13829
13830#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13831pub struct DiagnosticSummary {
13832    pub error_count: usize,
13833    pub warning_count: usize,
13834}
13835
13836impl DiagnosticSummary {
13837    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13838        let mut this = Self {
13839            error_count: 0,
13840            warning_count: 0,
13841        };
13842
13843        for entry in diagnostics {
13844            if entry.diagnostic.is_primary {
13845                match entry.diagnostic.severity {
13846                    DiagnosticSeverity::ERROR => this.error_count += 1,
13847                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13848                    _ => {}
13849                }
13850            }
13851        }
13852
13853        this
13854    }
13855
13856    pub fn is_empty(&self) -> bool {
13857        self.error_count == 0 && self.warning_count == 0
13858    }
13859
13860    pub fn to_proto(
13861        self,
13862        language_server_id: LanguageServerId,
13863        path: &RelPath,
13864    ) -> proto::DiagnosticSummary {
13865        proto::DiagnosticSummary {
13866            path: path.to_proto(),
13867            language_server_id: language_server_id.0 as u64,
13868            error_count: self.error_count as u32,
13869            warning_count: self.warning_count as u32,
13870        }
13871    }
13872}
13873
13874#[derive(Clone, Debug)]
13875pub enum CompletionDocumentation {
13876    /// There is no documentation for this completion.
13877    Undocumented,
13878    /// A single line of documentation.
13879    SingleLine(SharedString),
13880    /// Multiple lines of plain text documentation.
13881    MultiLinePlainText(SharedString),
13882    /// Markdown documentation.
13883    MultiLineMarkdown(SharedString),
13884    /// Both single line and multiple lines of plain text documentation.
13885    SingleLineAndMultiLinePlainText {
13886        single_line: SharedString,
13887        plain_text: Option<SharedString>,
13888    },
13889}
13890
13891impl CompletionDocumentation {
13892    #[cfg(any(test, feature = "test-support"))]
13893    pub fn text(&self) -> SharedString {
13894        match self {
13895            CompletionDocumentation::Undocumented => "".into(),
13896            CompletionDocumentation::SingleLine(s) => s.clone(),
13897            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13898            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13899            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13900                single_line.clone()
13901            }
13902        }
13903    }
13904}
13905
13906impl From<lsp::Documentation> for CompletionDocumentation {
13907    fn from(docs: lsp::Documentation) -> Self {
13908        match docs {
13909            lsp::Documentation::String(text) => {
13910                if text.lines().count() <= 1 {
13911                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
13912                } else {
13913                    CompletionDocumentation::MultiLinePlainText(text.into())
13914                }
13915            }
13916
13917            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13918                lsp::MarkupKind::PlainText => {
13919                    if value.lines().count() <= 1 {
13920                        CompletionDocumentation::SingleLine(value.into())
13921                    } else {
13922                        CompletionDocumentation::MultiLinePlainText(value.into())
13923                    }
13924                }
13925
13926                lsp::MarkupKind::Markdown => {
13927                    CompletionDocumentation::MultiLineMarkdown(value.into())
13928                }
13929            },
13930        }
13931    }
13932}
13933
13934pub enum ResolvedHint {
13935    Resolved(InlayHint),
13936    Resolving(Shared<Task<()>>),
13937}
13938
13939pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
13940    glob.components()
13941        .take_while(|component| match component {
13942            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13943            _ => true,
13944        })
13945        .collect()
13946}
13947
13948pub struct SshLspAdapter {
13949    name: LanguageServerName,
13950    binary: LanguageServerBinary,
13951    initialization_options: Option<String>,
13952    code_action_kinds: Option<Vec<CodeActionKind>>,
13953}
13954
13955impl SshLspAdapter {
13956    pub fn new(
13957        name: LanguageServerName,
13958        binary: LanguageServerBinary,
13959        initialization_options: Option<String>,
13960        code_action_kinds: Option<String>,
13961    ) -> Self {
13962        Self {
13963            name,
13964            binary,
13965            initialization_options,
13966            code_action_kinds: code_action_kinds
13967                .as_ref()
13968                .and_then(|c| serde_json::from_str(c).ok()),
13969        }
13970    }
13971}
13972
13973impl LspInstaller for SshLspAdapter {
13974    type BinaryVersion = ();
13975    async fn check_if_user_installed(
13976        &self,
13977        _: &dyn LspAdapterDelegate,
13978        _: Option<Toolchain>,
13979        _: &AsyncApp,
13980    ) -> Option<LanguageServerBinary> {
13981        Some(self.binary.clone())
13982    }
13983
13984    async fn cached_server_binary(
13985        &self,
13986        _: PathBuf,
13987        _: &dyn LspAdapterDelegate,
13988    ) -> Option<LanguageServerBinary> {
13989        None
13990    }
13991
13992    async fn fetch_latest_server_version(
13993        &self,
13994        _: &dyn LspAdapterDelegate,
13995        _: bool,
13996        _: &mut AsyncApp,
13997    ) -> Result<()> {
13998        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13999    }
14000
14001    async fn fetch_server_binary(
14002        &self,
14003        _: (),
14004        _: PathBuf,
14005        _: &dyn LspAdapterDelegate,
14006    ) -> Result<LanguageServerBinary> {
14007        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14008    }
14009}
14010
14011#[async_trait(?Send)]
14012impl LspAdapter for SshLspAdapter {
14013    fn name(&self) -> LanguageServerName {
14014        self.name.clone()
14015    }
14016
14017    async fn initialization_options(
14018        self: Arc<Self>,
14019        _: &Arc<dyn LspAdapterDelegate>,
14020        _: &mut AsyncApp,
14021    ) -> Result<Option<serde_json::Value>> {
14022        let Some(options) = &self.initialization_options else {
14023            return Ok(None);
14024        };
14025        let result = serde_json::from_str(options)?;
14026        Ok(result)
14027    }
14028
14029    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14030        self.code_action_kinds.clone()
14031    }
14032}
14033
14034pub fn language_server_settings<'a>(
14035    delegate: &'a dyn LspAdapterDelegate,
14036    language: &LanguageServerName,
14037    cx: &'a App,
14038) -> Option<&'a LspSettings> {
14039    language_server_settings_for(
14040        SettingsLocation {
14041            worktree_id: delegate.worktree_id(),
14042            path: RelPath::empty(),
14043        },
14044        language,
14045        cx,
14046    )
14047}
14048
14049pub fn language_server_settings_for<'a>(
14050    location: SettingsLocation<'a>,
14051    language: &LanguageServerName,
14052    cx: &'a App,
14053) -> Option<&'a LspSettings> {
14054    ProjectSettings::get(Some(location), cx).lsp.get(language)
14055}
14056
14057pub struct LocalLspAdapterDelegate {
14058    lsp_store: WeakEntity<LspStore>,
14059    worktree: worktree::Snapshot,
14060    fs: Arc<dyn Fs>,
14061    http_client: Arc<dyn HttpClient>,
14062    language_registry: Arc<LanguageRegistry>,
14063    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14064}
14065
14066impl LocalLspAdapterDelegate {
14067    pub fn new(
14068        language_registry: Arc<LanguageRegistry>,
14069        environment: &Entity<ProjectEnvironment>,
14070        lsp_store: WeakEntity<LspStore>,
14071        worktree: &Entity<Worktree>,
14072        http_client: Arc<dyn HttpClient>,
14073        fs: Arc<dyn Fs>,
14074        cx: &mut App,
14075    ) -> Arc<Self> {
14076        let load_shell_env_task =
14077            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14078
14079        Arc::new(Self {
14080            lsp_store,
14081            worktree: worktree.read(cx).snapshot(),
14082            fs,
14083            http_client,
14084            language_registry,
14085            load_shell_env_task,
14086        })
14087    }
14088
14089    pub fn from_local_lsp(
14090        local: &LocalLspStore,
14091        worktree: &Entity<Worktree>,
14092        cx: &mut App,
14093    ) -> Arc<Self> {
14094        Self::new(
14095            local.languages.clone(),
14096            &local.environment,
14097            local.weak.clone(),
14098            worktree,
14099            local.http_client.clone(),
14100            local.fs.clone(),
14101            cx,
14102        )
14103    }
14104}
14105
14106#[async_trait]
14107impl LspAdapterDelegate for LocalLspAdapterDelegate {
14108    fn show_notification(&self, message: &str, cx: &mut App) {
14109        self.lsp_store
14110            .update(cx, |_, cx| {
14111                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14112            })
14113            .ok();
14114    }
14115
14116    fn http_client(&self) -> Arc<dyn HttpClient> {
14117        self.http_client.clone()
14118    }
14119
14120    fn worktree_id(&self) -> WorktreeId {
14121        self.worktree.id()
14122    }
14123
14124    fn worktree_root_path(&self) -> &Path {
14125        self.worktree.abs_path().as_ref()
14126    }
14127
14128    fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
14129        self.worktree.resolve_relative_path(path)
14130    }
14131
14132    async fn shell_env(&self) -> HashMap<String, String> {
14133        let task = self.load_shell_env_task.clone();
14134        task.await.unwrap_or_default()
14135    }
14136
14137    async fn npm_package_installed_version(
14138        &self,
14139        package_name: &str,
14140    ) -> Result<Option<(PathBuf, Version)>> {
14141        let local_package_directory = self.worktree_root_path();
14142        let node_modules_directory = local_package_directory.join("node_modules");
14143
14144        if let Some(version) =
14145            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14146        {
14147            return Ok(Some((node_modules_directory, version)));
14148        }
14149        let Some(npm) = self.which("npm".as_ref()).await else {
14150            log::warn!(
14151                "Failed to find npm executable for {:?}",
14152                local_package_directory
14153            );
14154            return Ok(None);
14155        };
14156
14157        let env = self.shell_env().await;
14158        let output = util::command::new_command(&npm)
14159            .args(["root", "-g"])
14160            .envs(env)
14161            .current_dir(local_package_directory)
14162            .output()
14163            .await?;
14164        let global_node_modules =
14165            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14166
14167        if let Some(version) =
14168            read_package_installed_version(global_node_modules.clone(), package_name).await?
14169        {
14170            return Ok(Some((global_node_modules, version)));
14171        }
14172        return Ok(None);
14173    }
14174
14175    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14176        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14177        if self.fs.is_file(&worktree_abs_path).await {
14178            worktree_abs_path.pop();
14179        }
14180
14181        let env = self.shell_env().await;
14182
14183        let shell_path = env.get("PATH").cloned();
14184
14185        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14186    }
14187
14188    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14189        let mut working_dir = self.worktree_root_path().to_path_buf();
14190        if self.fs.is_file(&working_dir).await {
14191            working_dir.pop();
14192        }
14193        let output = util::command::new_command(&command.path)
14194            .args(command.arguments)
14195            .envs(command.env.clone().unwrap_or_default())
14196            .current_dir(working_dir)
14197            .output()
14198            .await?;
14199
14200        anyhow::ensure!(
14201            output.status.success(),
14202            "{}, stdout: {:?}, stderr: {:?}",
14203            output.status,
14204            String::from_utf8_lossy(&output.stdout),
14205            String::from_utf8_lossy(&output.stderr)
14206        );
14207        Ok(())
14208    }
14209
14210    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14211        self.language_registry
14212            .update_lsp_binary_status(server_name, status);
14213    }
14214
14215    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14216        self.language_registry
14217            .all_lsp_adapters()
14218            .into_iter()
14219            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14220            .collect()
14221    }
14222
14223    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14224        let dir = self.language_registry.language_server_download_dir(name)?;
14225
14226        if !dir.exists() {
14227            smol::fs::create_dir_all(&dir)
14228                .await
14229                .context("failed to create container directory")
14230                .log_err()?;
14231        }
14232
14233        Some(dir)
14234    }
14235
14236    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14237        let entry = self
14238            .worktree
14239            .entry_for_path(path)
14240            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14241        let abs_path = self.worktree.absolutize(&entry.path);
14242        self.fs.load(&abs_path).await
14243    }
14244}
14245
14246async fn populate_labels_for_symbols(
14247    symbols: Vec<CoreSymbol>,
14248    language_registry: &Arc<LanguageRegistry>,
14249    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14250    output: &mut Vec<Symbol>,
14251) {
14252    #[allow(clippy::mutable_key_type)]
14253    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14254
14255    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14256    for symbol in symbols {
14257        let Some(file_name) = symbol.path.file_name() else {
14258            continue;
14259        };
14260        let language = language_registry
14261            .load_language_for_file_path(Path::new(file_name))
14262            .await
14263            .ok()
14264            .or_else(|| {
14265                unknown_paths.insert(file_name.into());
14266                None
14267            });
14268        symbols_by_language
14269            .entry(language)
14270            .or_default()
14271            .push(symbol);
14272    }
14273
14274    for unknown_path in unknown_paths {
14275        log::info!("no language found for symbol in file {unknown_path:?}");
14276    }
14277
14278    let mut label_params = Vec::new();
14279    for (language, mut symbols) in symbols_by_language {
14280        label_params.clear();
14281        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14282            name: mem::take(&mut symbol.name),
14283            kind: symbol.kind,
14284            container_name: symbol.container_name.take(),
14285        }));
14286
14287        let mut labels = Vec::new();
14288        if let Some(language) = language {
14289            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14290                language_registry
14291                    .lsp_adapters(&language.name())
14292                    .first()
14293                    .cloned()
14294            });
14295            if let Some(lsp_adapter) = lsp_adapter {
14296                labels = lsp_adapter
14297                    .labels_for_symbols(&label_params, &language)
14298                    .await
14299                    .log_err()
14300                    .unwrap_or_default();
14301            }
14302        }
14303
14304        for (
14305            (
14306                symbol,
14307                language::Symbol {
14308                    name,
14309                    container_name,
14310                    ..
14311                },
14312            ),
14313            label,
14314        ) in symbols
14315            .into_iter()
14316            .zip(label_params.drain(..))
14317            .zip(labels.into_iter().chain(iter::repeat(None)))
14318        {
14319            output.push(Symbol {
14320                language_server_name: symbol.language_server_name,
14321                source_worktree_id: symbol.source_worktree_id,
14322                source_language_server_id: symbol.source_language_server_id,
14323                path: symbol.path,
14324                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14325                name,
14326                kind: symbol.kind,
14327                range: symbol.range,
14328                container_name,
14329            });
14330        }
14331    }
14332}
14333
14334pub(crate) fn collapse_newlines(text: &str, separator: &str) -> String {
14335    text.lines()
14336        .map(|line| line.trim())
14337        .filter(|line| !line.is_empty())
14338        .join(separator)
14339}
14340
14341fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14342    match server.capabilities().text_document_sync.as_ref()? {
14343        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14344            // Server wants didSave but didn't specify includeText.
14345            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14346            // Server doesn't want didSave at all.
14347            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14348            // Server provided SaveOptions.
14349            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14350                Some(save_options.include_text.unwrap_or(false))
14351            }
14352        },
14353        // We do not have any save info. Kind affects didChange only.
14354        lsp::TextDocumentSyncCapability::Kind(_) => None,
14355    }
14356}
14357
14358/// Completion items are displayed in a `UniformList`.
14359/// Usually, those items are single-line strings, but in LSP responses,
14360/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14361/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14362/// 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,
14363/// breaking the completions menu presentation.
14364///
14365/// 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.
14366pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14367    let mut new_text = String::with_capacity(label.text.len());
14368    let mut offset_map = vec![0; label.text.len() + 1];
14369    let mut last_char_was_space = false;
14370    let mut new_idx = 0;
14371    let chars = label.text.char_indices().fuse();
14372    let mut newlines_removed = false;
14373
14374    for (idx, c) in chars {
14375        offset_map[idx] = new_idx;
14376
14377        match c {
14378            '\n' if last_char_was_space => {
14379                newlines_removed = true;
14380            }
14381            '\t' | ' ' if last_char_was_space => {}
14382            '\n' if !last_char_was_space => {
14383                new_text.push(' ');
14384                new_idx += 1;
14385                last_char_was_space = true;
14386                newlines_removed = true;
14387            }
14388            ' ' | '\t' => {
14389                new_text.push(' ');
14390                new_idx += 1;
14391                last_char_was_space = true;
14392            }
14393            _ => {
14394                new_text.push(c);
14395                new_idx += c.len_utf8();
14396                last_char_was_space = false;
14397            }
14398        }
14399    }
14400    offset_map[label.text.len()] = new_idx;
14401
14402    // Only modify the label if newlines were removed.
14403    if !newlines_removed {
14404        return;
14405    }
14406
14407    let last_index = new_idx;
14408    let mut run_ranges_errors = Vec::new();
14409    label.runs.retain_mut(|(range, _)| {
14410        match offset_map.get(range.start) {
14411            Some(&start) => range.start = start,
14412            None => {
14413                run_ranges_errors.push(range.clone());
14414                return false;
14415            }
14416        }
14417
14418        match offset_map.get(range.end) {
14419            Some(&end) => range.end = end,
14420            None => {
14421                run_ranges_errors.push(range.clone());
14422                range.end = last_index;
14423            }
14424        }
14425        true
14426    });
14427    if !run_ranges_errors.is_empty() {
14428        log::error!(
14429            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14430            label.text
14431        );
14432    }
14433
14434    let mut wrong_filter_range = None;
14435    if label.filter_range == (0..label.text.len()) {
14436        label.filter_range = 0..new_text.len();
14437    } else {
14438        let mut original_filter_range = Some(label.filter_range.clone());
14439        match offset_map.get(label.filter_range.start) {
14440            Some(&start) => label.filter_range.start = start,
14441            None => {
14442                wrong_filter_range = original_filter_range.take();
14443                label.filter_range.start = last_index;
14444            }
14445        }
14446
14447        match offset_map.get(label.filter_range.end) {
14448            Some(&end) => label.filter_range.end = end,
14449            None => {
14450                wrong_filter_range = original_filter_range.take();
14451                label.filter_range.end = last_index;
14452            }
14453        }
14454    }
14455    if let Some(wrong_filter_range) = wrong_filter_range {
14456        log::error!(
14457            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14458            label.text
14459        );
14460    }
14461
14462    label.text = new_text;
14463}