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                    )
  552                    .await?;
  553
  554                    match (&mut initialization_options, override_options) {
  555                        (Some(initialization_options), Some(override_options)) => {
  556                            merge_json_value_into(override_options, initialization_options);
  557                        }
  558                        (None, override_options) => initialization_options = override_options,
  559                        _ => {}
  560                    }
  561
  562                    let initialization_params = cx.update(|cx| {
  563                        let mut params = language_server.default_initialize_params(
  564                            pull_diagnostics,
  565                            augments_syntax_tokens,
  566                            cx,
  567                        );
  568                        params.initialization_options = initialization_options;
  569                        adapter.adapter.prepare_initialize_params(params, cx)
  570                    })?;
  571
  572                    Self::setup_lsp_messages(
  573                        lsp_store.clone(),
  574                        &language_server,
  575                        delegate.clone(),
  576                        adapter.clone(),
  577                    );
  578
  579                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  580                        settings: workspace_config,
  581                    };
  582                    let language_server = cx
  583                        .update(|cx| {
  584                            let request_timeout = ProjectSettings::get_global(cx)
  585                                .global_lsp_settings
  586                                .get_request_timeout();
  587
  588                            language_server.initialize(
  589                                initialization_params,
  590                                Arc::new(did_change_configuration_params.clone()),
  591                                request_timeout,
  592                                cx,
  593                            )
  594                        })
  595                        .await
  596                        .inspect_err(|_| {
  597                            if let Some(lsp_store) = lsp_store.upgrade() {
  598                                lsp_store.update(cx, |lsp_store, cx| {
  599                                    lsp_store.cleanup_lsp_data(server_id);
  600                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  601                                });
  602                            }
  603                        })?;
  604
  605                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  606                        did_change_configuration_params,
  607                    )?;
  608
  609                    anyhow::Ok(language_server)
  610                }
  611                .await;
  612
  613                match result {
  614                    Ok(server) => {
  615                        lsp_store
  616                            .update(cx, |lsp_store, cx| {
  617                                lsp_store.insert_newly_running_language_server(
  618                                    adapter,
  619                                    server.clone(),
  620                                    server_id,
  621                                    key,
  622                                    pending_workspace_folders,
  623                                    cx,
  624                                );
  625                            })
  626                            .ok();
  627                        stderr_capture.lock().take();
  628                        Some(server)
  629                    }
  630
  631                    Err(err) => {
  632                        let log = stderr_capture.lock().take().unwrap_or_default();
  633                        delegate.update_status(
  634                            adapter.name(),
  635                            BinaryStatus::Failed {
  636                                error: if log.is_empty() {
  637                                    format!("{err:#}")
  638                                } else {
  639                                    format!("{err:#}\n-- stderr --\n{log}")
  640                                },
  641                            },
  642                        );
  643                        log::error!(
  644                            "Failed to start language server {server_name:?}: {}",
  645                            redact_command(&format!("{err:?}"))
  646                        );
  647                        if !log.is_empty() {
  648                            log::error!("server stderr: {}", redact_command(&log));
  649                        }
  650                        None
  651                    }
  652                }
  653            })
  654        };
  655        let state = LanguageServerState::Starting {
  656            startup,
  657            pending_workspace_folders,
  658        };
  659
  660        if update_binary_status {
  661            self.languages
  662                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  663        }
  664
  665        self.language_servers.insert(server_id, state);
  666        self.language_server_ids
  667            .entry(key)
  668            .or_insert(UnifiedLanguageServer {
  669                id: server_id,
  670                project_roots: Default::default(),
  671            });
  672        server_id
  673    }
  674
  675    fn get_language_server_binary(
  676        &self,
  677        worktree_abs_path: Arc<Path>,
  678        adapter: Arc<CachedLspAdapter>,
  679        settings: Arc<LspSettings>,
  680        toolchain: Option<Toolchain>,
  681        delegate: Arc<dyn LspAdapterDelegate>,
  682        allow_binary_download: bool,
  683        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  684        cx: &mut App,
  685    ) -> Task<Result<LanguageServerBinary>> {
  686        if let Some(settings) = &settings.binary
  687            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  688        {
  689            let settings = settings.clone();
  690            let languages = self.languages.clone();
  691            return cx.background_spawn(async move {
  692                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  693                    let already_trusted =  *wait_until_worktree_trust.borrow();
  694                    if !already_trusted {
  695                        log::info!(
  696                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  697                            adapter.name(),
  698                        );
  699                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  700                            if worktree_trusted {
  701                                break;
  702                            }
  703                        }
  704                        log::info!(
  705                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  706                            adapter.name(),
  707                        );
  708                    }
  709                    languages
  710                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  711                }
  712                let mut env = delegate.shell_env().await;
  713                env.extend(settings.env.unwrap_or_default());
  714
  715                Ok(LanguageServerBinary {
  716                    path: delegate.resolve_relative_path(path),
  717                    env: Some(env),
  718                    arguments: settings
  719                        .arguments
  720                        .unwrap_or_default()
  721                        .iter()
  722                        .map(Into::into)
  723                        .collect(),
  724                })
  725            });
  726        }
  727        let lsp_binary_options = LanguageServerBinaryOptions {
  728            allow_path_lookup: !settings
  729                .binary
  730                .as_ref()
  731                .and_then(|b| b.ignore_system_version)
  732                .unwrap_or_default(),
  733            allow_binary_download,
  734            pre_release: settings
  735                .fetch
  736                .as_ref()
  737                .and_then(|f| f.pre_release)
  738                .unwrap_or(false),
  739        };
  740
  741        cx.spawn(async move |cx| {
  742            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  743                let already_trusted =  *wait_until_worktree_trust.borrow();
  744                if !already_trusted {
  745                    log::info!(
  746                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  747                        adapter.name(),
  748                    );
  749                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  750                        if worktree_trusted {
  751                            break;
  752                        }
  753                    }
  754                    log::info!(
  755                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  756                            adapter.name(),
  757                    );
  758                }
  759            }
  760
  761            let (existing_binary, maybe_download_binary) = adapter
  762                .clone()
  763                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  764                .await
  765                .await;
  766
  767            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  768
  769            let mut binary = match (existing_binary, maybe_download_binary) {
  770                (binary, None) => binary?,
  771                (Err(_), Some(downloader)) => downloader.await?,
  772                (Ok(existing_binary), Some(downloader)) => {
  773                    let mut download_timeout = cx
  774                        .background_executor()
  775                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  776                        .fuse();
  777                    let mut downloader = downloader.fuse();
  778                    futures::select! {
  779                        _ = download_timeout => {
  780                            // Return existing binary and kick the existing work to the background.
  781                            cx.spawn(async move |_| downloader.await).detach();
  782                            Ok(existing_binary)
  783                        },
  784                        downloaded_or_existing_binary = downloader => {
  785                            // If download fails, this results in the existing binary.
  786                            downloaded_or_existing_binary
  787                        }
  788                    }?
  789                }
  790            };
  791            let mut shell_env = delegate.shell_env().await;
  792
  793            shell_env.extend(binary.env.unwrap_or_default());
  794
  795            if let Some(settings) = settings.binary.as_ref() {
  796                if let Some(arguments) = &settings.arguments {
  797                    binary.arguments = arguments.iter().map(Into::into).collect();
  798                }
  799                if let Some(env) = &settings.env {
  800                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  801                }
  802            }
  803
  804            binary.env = Some(shell_env);
  805            Ok(binary)
  806        })
  807    }
  808
  809    fn setup_lsp_messages(
  810        lsp_store: WeakEntity<LspStore>,
  811        language_server: &LanguageServer,
  812        delegate: Arc<dyn LspAdapterDelegate>,
  813        adapter: Arc<CachedLspAdapter>,
  814    ) {
  815        let name = language_server.name();
  816        let server_id = language_server.server_id();
  817        language_server
  818            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  819                let adapter = adapter.clone();
  820                let this = lsp_store.clone();
  821                move |mut params, cx| {
  822                    let adapter = adapter.clone();
  823                    if let Some(this) = this.upgrade() {
  824                        this.update(cx, |this, cx| {
  825                            {
  826                                let buffer = params
  827                                    .uri
  828                                    .to_file_path()
  829                                    .map(|file_path| this.get_buffer(&file_path, cx))
  830                                    .ok()
  831                                    .flatten();
  832                                adapter.process_diagnostics(&mut params, server_id, buffer);
  833                            }
  834
  835                            this.merge_lsp_diagnostics(
  836                                DiagnosticSourceKind::Pushed,
  837                                vec![DocumentDiagnosticsUpdate {
  838                                    server_id,
  839                                    diagnostics: params,
  840                                    result_id: None,
  841                                    disk_based_sources: Cow::Borrowed(
  842                                        &adapter.disk_based_diagnostic_sources,
  843                                    ),
  844                                    registration_id: None,
  845                                }],
  846                                |_, diagnostic, cx| match diagnostic.source_kind {
  847                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  848                                        adapter.retain_old_diagnostic(diagnostic, cx)
  849                                    }
  850                                    DiagnosticSourceKind::Pulled => true,
  851                                },
  852                                cx,
  853                            )
  854                            .log_err();
  855                        });
  856                    }
  857                }
  858            })
  859            .detach();
  860        language_server
  861            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  862                let adapter = adapter.adapter.clone();
  863                let delegate = delegate.clone();
  864                let this = lsp_store.clone();
  865                move |params, cx| {
  866                    let adapter = adapter.clone();
  867                    let delegate = delegate.clone();
  868                    let this = this.clone();
  869                    let mut cx = cx.clone();
  870                    async move {
  871                        let toolchain_for_id = this
  872                            .update(&mut cx, |this, _| {
  873                                this.as_local()?.language_server_ids.iter().find_map(
  874                                    |(seed, value)| {
  875                                        (value.id == server_id).then(|| seed.toolchain.clone())
  876                                    },
  877                                )
  878                            })?
  879                            .context("Expected the LSP store to be in a local mode")?;
  880
  881                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  882                        for item in &params.items {
  883                            let scope_uri = item.scope_uri.clone();
  884                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  885                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  886                            else {
  887                                // We've already queried workspace configuration of this URI.
  888                                continue;
  889                            };
  890                            let workspace_config = Self::workspace_configuration_for_adapter(
  891                                adapter.clone(),
  892                                &delegate,
  893                                toolchain_for_id.clone(),
  894                                scope_uri,
  895                                &mut cx,
  896                            )
  897                            .await?;
  898                            new_scope_uri.insert(workspace_config);
  899                        }
  900
  901                        Ok(params
  902                            .items
  903                            .into_iter()
  904                            .filter_map(|item| {
  905                                let workspace_config =
  906                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  907                                if let Some(section) = &item.section {
  908                                    Some(
  909                                        workspace_config
  910                                            .get(section)
  911                                            .cloned()
  912                                            .unwrap_or(serde_json::Value::Null),
  913                                    )
  914                                } else {
  915                                    Some(workspace_config.clone())
  916                                }
  917                            })
  918                            .collect())
  919                    }
  920                }
  921            })
  922            .detach();
  923
  924        language_server
  925            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  926                let this = lsp_store.clone();
  927                move |_, cx| {
  928                    let this = this.clone();
  929                    let cx = cx.clone();
  930                    async move {
  931                        let Some(server) =
  932                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  933                        else {
  934                            return Ok(None);
  935                        };
  936                        let root = server.workspace_folders();
  937                        Ok(Some(
  938                            root.into_iter()
  939                                .map(|uri| WorkspaceFolder {
  940                                    uri,
  941                                    name: Default::default(),
  942                                })
  943                                .collect(),
  944                        ))
  945                    }
  946                }
  947            })
  948            .detach();
  949        // Even though we don't have handling for these requests, respond to them to
  950        // avoid stalling any language server like `gopls` which waits for a response
  951        // to these requests when initializing.
  952        language_server
  953            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  954                let this = lsp_store.clone();
  955                move |params, cx| {
  956                    let this = this.clone();
  957                    let mut cx = cx.clone();
  958                    async move {
  959                        this.update(&mut cx, |this, _| {
  960                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  961                            {
  962                                status
  963                                    .progress_tokens
  964                                    .insert(ProgressToken::from_lsp(params.token));
  965                            }
  966                        })?;
  967
  968                        Ok(())
  969                    }
  970                }
  971            })
  972            .detach();
  973
  974        language_server
  975            .on_request::<lsp::request::RegisterCapability, _, _>({
  976                let lsp_store = lsp_store.clone();
  977                move |params, cx| {
  978                    let lsp_store = lsp_store.clone();
  979                    let mut cx = cx.clone();
  980                    async move {
  981                        lsp_store
  982                            .update(&mut cx, |lsp_store, cx| {
  983                                if lsp_store.as_local().is_some() {
  984                                    match lsp_store
  985                                        .register_server_capabilities(server_id, params, cx)
  986                                    {
  987                                        Ok(()) => {}
  988                                        Err(e) => {
  989                                            log::error!(
  990                                                "Failed to register server capabilities: {e:#}"
  991                                            );
  992                                        }
  993                                    };
  994                                }
  995                            })
  996                            .ok();
  997                        Ok(())
  998                    }
  999                }
 1000            })
 1001            .detach();
 1002
 1003        language_server
 1004            .on_request::<lsp::request::UnregisterCapability, _, _>({
 1005                let lsp_store = lsp_store.clone();
 1006                move |params, cx| {
 1007                    let lsp_store = lsp_store.clone();
 1008                    let mut cx = cx.clone();
 1009                    async move {
 1010                        lsp_store
 1011                            .update(&mut cx, |lsp_store, cx| {
 1012                                if lsp_store.as_local().is_some() {
 1013                                    match lsp_store
 1014                                        .unregister_server_capabilities(server_id, params, cx)
 1015                                    {
 1016                                        Ok(()) => {}
 1017                                        Err(e) => {
 1018                                            log::error!(
 1019                                                "Failed to unregister server capabilities: {e:#}"
 1020                                            );
 1021                                        }
 1022                                    }
 1023                                }
 1024                            })
 1025                            .ok();
 1026                        Ok(())
 1027                    }
 1028                }
 1029            })
 1030            .detach();
 1031
 1032        language_server
 1033            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
 1034                let this = lsp_store.clone();
 1035                move |params, cx| {
 1036                    let mut cx = cx.clone();
 1037                    let this = this.clone();
 1038                    async move {
 1039                        LocalLspStore::on_lsp_workspace_edit(
 1040                            this.clone(),
 1041                            params,
 1042                            server_id,
 1043                            &mut cx,
 1044                        )
 1045                        .await
 1046                    }
 1047                }
 1048            })
 1049            .detach();
 1050
 1051        language_server
 1052            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1053                let lsp_store = lsp_store.clone();
 1054                let request_id = Arc::new(AtomicUsize::new(0));
 1055                move |(), cx| {
 1056                    let lsp_store = lsp_store.clone();
 1057                    let request_id = request_id.clone();
 1058                    let mut cx = cx.clone();
 1059                    async move {
 1060                        lsp_store
 1061                            .update(&mut cx, |lsp_store, cx| {
 1062                                let request_id =
 1063                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1064                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1065                                    server_id,
 1066                                    request_id,
 1067                                });
 1068                                lsp_store
 1069                                    .downstream_client
 1070                                    .as_ref()
 1071                                    .map(|(client, project_id)| {
 1072                                        client.send(proto::RefreshInlayHints {
 1073                                            project_id: *project_id,
 1074                                            server_id: server_id.to_proto(),
 1075                                            request_id: request_id.map(|id| id as u64),
 1076                                        })
 1077                                    })
 1078                            })?
 1079                            .transpose()?;
 1080                        Ok(())
 1081                    }
 1082                }
 1083            })
 1084            .detach();
 1085
 1086        language_server
 1087            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1088                let this = lsp_store.clone();
 1089                move |(), cx| {
 1090                    let this = this.clone();
 1091                    let mut cx = cx.clone();
 1092                    async move {
 1093                        this.update(&mut cx, |this, cx| {
 1094                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1095                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1096                                client.send(proto::RefreshCodeLens {
 1097                                    project_id: *project_id,
 1098                                })
 1099                            })
 1100                        })?
 1101                        .transpose()?;
 1102                        Ok(())
 1103                    }
 1104                }
 1105            })
 1106            .detach();
 1107
 1108        language_server
 1109            .on_request::<lsp::request::SemanticTokensRefresh, _, _>({
 1110                let lsp_store = lsp_store.clone();
 1111                let request_id = Arc::new(AtomicUsize::new(0));
 1112                move |(), cx| {
 1113                    let lsp_store = lsp_store.clone();
 1114                    let request_id = request_id.clone();
 1115                    let mut cx = cx.clone();
 1116                    async move {
 1117                        lsp_store
 1118                            .update(&mut cx, |lsp_store, cx| {
 1119                                let request_id =
 1120                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1121                                cx.emit(LspStoreEvent::RefreshSemanticTokens {
 1122                                    server_id,
 1123                                    request_id,
 1124                                });
 1125                                lsp_store
 1126                                    .downstream_client
 1127                                    .as_ref()
 1128                                    .map(|(client, project_id)| {
 1129                                        client.send(proto::RefreshSemanticTokens {
 1130                                            project_id: *project_id,
 1131                                            server_id: server_id.to_proto(),
 1132                                            request_id: request_id.map(|id| id as u64),
 1133                                        })
 1134                                    })
 1135                            })?
 1136                            .transpose()?;
 1137                        Ok(())
 1138                    }
 1139                }
 1140            })
 1141            .detach();
 1142
 1143        language_server
 1144            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1145                let this = lsp_store.clone();
 1146                move |(), cx| {
 1147                    let this = this.clone();
 1148                    let mut cx = cx.clone();
 1149                    async move {
 1150                        this.update(&mut cx, |lsp_store, cx| {
 1151                            lsp_store.pull_workspace_diagnostics(server_id);
 1152                            lsp_store
 1153                                .downstream_client
 1154                                .as_ref()
 1155                                .map(|(client, project_id)| {
 1156                                    client.send(proto::PullWorkspaceDiagnostics {
 1157                                        project_id: *project_id,
 1158                                        server_id: server_id.to_proto(),
 1159                                    })
 1160                                })
 1161                                .transpose()?;
 1162                            anyhow::Ok(
 1163                                lsp_store.pull_document_diagnostics_for_server(server_id, None, cx),
 1164                            )
 1165                        })??
 1166                        .await;
 1167                        Ok(())
 1168                    }
 1169                }
 1170            })
 1171            .detach();
 1172
 1173        language_server
 1174            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1175                let this = lsp_store.clone();
 1176                let name = name.to_string();
 1177                let adapter = adapter.clone();
 1178                move |params, cx| {
 1179                    let this = this.clone();
 1180                    let name = name.to_string();
 1181                    let adapter = adapter.clone();
 1182                    let mut cx = cx.clone();
 1183                    async move {
 1184                        let actions = params.actions.unwrap_or_default();
 1185                        let message = params.message.clone();
 1186                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1187                        let level = match params.typ {
 1188                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1189                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1190                            _ => PromptLevel::Info,
 1191                        };
 1192                        let request = LanguageServerPromptRequest::new(
 1193                            level,
 1194                            params.message,
 1195                            actions,
 1196                            name.clone(),
 1197                            tx,
 1198                        );
 1199
 1200                        let did_update = this
 1201                            .update(&mut cx, |_, cx| {
 1202                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1203                            })
 1204                            .is_ok();
 1205                        if did_update {
 1206                            let response = rx.recv().await.ok();
 1207                            if let Some(ref selected_action) = response {
 1208                                let context = language::PromptResponseContext {
 1209                                    message,
 1210                                    selected_action: selected_action.clone(),
 1211                                };
 1212                                adapter.process_prompt_response(&context, &mut cx)
 1213                            }
 1214
 1215                            Ok(response)
 1216                        } else {
 1217                            Ok(None)
 1218                        }
 1219                    }
 1220                }
 1221            })
 1222            .detach();
 1223        language_server
 1224            .on_notification::<lsp::notification::ShowMessage, _>({
 1225                let this = lsp_store.clone();
 1226                let name = name.to_string();
 1227                move |params, cx| {
 1228                    let this = this.clone();
 1229                    let name = name.to_string();
 1230                    let mut cx = cx.clone();
 1231
 1232                    let (tx, _) = smol::channel::bounded(1);
 1233                    let level = match params.typ {
 1234                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1235                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1236                        _ => PromptLevel::Info,
 1237                    };
 1238                    let request =
 1239                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1240
 1241                    let _ = this.update(&mut cx, |_, cx| {
 1242                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1243                    });
 1244                }
 1245            })
 1246            .detach();
 1247
 1248        let disk_based_diagnostics_progress_token =
 1249            adapter.disk_based_diagnostics_progress_token.clone();
 1250
 1251        language_server
 1252            .on_notification::<lsp::notification::Progress, _>({
 1253                let this = lsp_store.clone();
 1254                move |params, cx| {
 1255                    if let Some(this) = this.upgrade() {
 1256                        this.update(cx, |this, cx| {
 1257                            this.on_lsp_progress(
 1258                                params,
 1259                                server_id,
 1260                                disk_based_diagnostics_progress_token.clone(),
 1261                                cx,
 1262                            );
 1263                        });
 1264                    }
 1265                }
 1266            })
 1267            .detach();
 1268
 1269        language_server
 1270            .on_notification::<lsp::notification::LogMessage, _>({
 1271                let this = lsp_store.clone();
 1272                move |params, cx| {
 1273                    if let Some(this) = this.upgrade() {
 1274                        this.update(cx, |_, cx| {
 1275                            cx.emit(LspStoreEvent::LanguageServerLog(
 1276                                server_id,
 1277                                LanguageServerLogType::Log(params.typ),
 1278                                params.message,
 1279                            ));
 1280                        });
 1281                    }
 1282                }
 1283            })
 1284            .detach();
 1285
 1286        language_server
 1287            .on_notification::<lsp::notification::LogTrace, _>({
 1288                let this = lsp_store.clone();
 1289                move |params, cx| {
 1290                    let mut cx = cx.clone();
 1291                    if let Some(this) = this.upgrade() {
 1292                        this.update(&mut cx, |_, cx| {
 1293                            cx.emit(LspStoreEvent::LanguageServerLog(
 1294                                server_id,
 1295                                LanguageServerLogType::Trace {
 1296                                    verbose_info: params.verbose,
 1297                                },
 1298                                params.message,
 1299                            ));
 1300                        });
 1301                    }
 1302                }
 1303            })
 1304            .detach();
 1305
 1306        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1307        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1308        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1309        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1310    }
 1311
 1312    fn shutdown_language_servers_on_quit(&mut self) -> impl Future<Output = ()> + use<> {
 1313        let shutdown_futures = self
 1314            .language_servers
 1315            .drain()
 1316            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1317            .collect::<Vec<_>>();
 1318
 1319        async move {
 1320            join_all(shutdown_futures).await;
 1321        }
 1322    }
 1323
 1324    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1325        match server_state {
 1326            LanguageServerState::Running { server, .. } => {
 1327                if let Some(shutdown) = server.shutdown() {
 1328                    shutdown.await;
 1329                }
 1330            }
 1331            LanguageServerState::Starting { startup, .. } => {
 1332                if let Some(server) = startup.await
 1333                    && let Some(shutdown) = server.shutdown()
 1334                {
 1335                    shutdown.await;
 1336                }
 1337            }
 1338        }
 1339        Ok(())
 1340    }
 1341
 1342    fn language_servers_for_worktree(
 1343        &self,
 1344        worktree_id: WorktreeId,
 1345    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1346        self.language_server_ids
 1347            .iter()
 1348            .filter_map(move |(seed, state)| {
 1349                if seed.worktree_id != worktree_id {
 1350                    return None;
 1351                }
 1352
 1353                if let Some(LanguageServerState::Running { server, .. }) =
 1354                    self.language_servers.get(&state.id)
 1355                {
 1356                    Some(server)
 1357                } else {
 1358                    None
 1359                }
 1360            })
 1361    }
 1362
 1363    fn language_server_ids_for_project_path(
 1364        &self,
 1365        project_path: ProjectPath,
 1366        language: &Language,
 1367        cx: &mut App,
 1368    ) -> Vec<LanguageServerId> {
 1369        let Some(worktree) = self
 1370            .worktree_store
 1371            .read(cx)
 1372            .worktree_for_id(project_path.worktree_id, cx)
 1373        else {
 1374            return Vec::new();
 1375        };
 1376        let delegate: Arc<dyn ManifestDelegate> =
 1377            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1378
 1379        self.lsp_tree
 1380            .get(
 1381                project_path,
 1382                language.name(),
 1383                language.manifest(),
 1384                &delegate,
 1385                cx,
 1386            )
 1387            .collect::<Vec<_>>()
 1388    }
 1389
 1390    fn language_server_ids_for_buffer(
 1391        &self,
 1392        buffer: &Buffer,
 1393        cx: &mut App,
 1394    ) -> Vec<LanguageServerId> {
 1395        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1396            let worktree_id = file.worktree_id(cx);
 1397
 1398            let path: Arc<RelPath> = file
 1399                .path()
 1400                .parent()
 1401                .map(Arc::from)
 1402                .unwrap_or_else(|| file.path().clone());
 1403            let worktree_path = ProjectPath { worktree_id, path };
 1404            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1405        } else {
 1406            Vec::new()
 1407        }
 1408    }
 1409
 1410    fn language_servers_for_buffer<'a>(
 1411        &'a self,
 1412        buffer: &'a Buffer,
 1413        cx: &'a mut App,
 1414    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1415        self.language_server_ids_for_buffer(buffer, cx)
 1416            .into_iter()
 1417            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1418                LanguageServerState::Running {
 1419                    adapter, server, ..
 1420                } => Some((adapter, server)),
 1421                _ => None,
 1422            })
 1423    }
 1424
 1425    async fn execute_code_action_kind_locally(
 1426        lsp_store: WeakEntity<LspStore>,
 1427        mut buffers: Vec<Entity<Buffer>>,
 1428        kind: CodeActionKind,
 1429        push_to_history: bool,
 1430        cx: &mut AsyncApp,
 1431    ) -> anyhow::Result<ProjectTransaction> {
 1432        // Do not allow multiple concurrent code actions requests for the
 1433        // same buffer.
 1434        lsp_store.update(cx, |this, cx| {
 1435            let this = this.as_local_mut().unwrap();
 1436            buffers.retain(|buffer| {
 1437                this.buffers_being_formatted
 1438                    .insert(buffer.read(cx).remote_id())
 1439            });
 1440        })?;
 1441        let _cleanup = defer({
 1442            let this = lsp_store.clone();
 1443            let mut cx = cx.clone();
 1444            let buffers = &buffers;
 1445            move || {
 1446                this.update(&mut cx, |this, cx| {
 1447                    let this = this.as_local_mut().unwrap();
 1448                    for buffer in buffers {
 1449                        this.buffers_being_formatted
 1450                            .remove(&buffer.read(cx).remote_id());
 1451                    }
 1452                })
 1453                .ok();
 1454            }
 1455        });
 1456        let mut project_transaction = ProjectTransaction::default();
 1457
 1458        for buffer in &buffers {
 1459            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1460                buffer.update(cx, |buffer, cx| {
 1461                    lsp_store
 1462                        .as_local()
 1463                        .unwrap()
 1464                        .language_servers_for_buffer(buffer, cx)
 1465                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1466                        .collect::<Vec<_>>()
 1467                })
 1468            })?;
 1469            for (_, language_server) in adapters_and_servers.iter() {
 1470                let actions = Self::get_server_code_actions_from_action_kinds(
 1471                    &lsp_store,
 1472                    language_server.server_id(),
 1473                    vec![kind.clone()],
 1474                    buffer,
 1475                    cx,
 1476                )
 1477                .await?;
 1478                Self::execute_code_actions_on_server(
 1479                    &lsp_store,
 1480                    language_server,
 1481                    actions,
 1482                    push_to_history,
 1483                    &mut project_transaction,
 1484                    cx,
 1485                )
 1486                .await?;
 1487            }
 1488        }
 1489        Ok(project_transaction)
 1490    }
 1491
 1492    async fn format_locally(
 1493        lsp_store: WeakEntity<LspStore>,
 1494        mut buffers: Vec<FormattableBuffer>,
 1495        push_to_history: bool,
 1496        trigger: FormatTrigger,
 1497        logger: zlog::Logger,
 1498        cx: &mut AsyncApp,
 1499    ) -> anyhow::Result<ProjectTransaction> {
 1500        // Do not allow multiple concurrent formatting requests for the
 1501        // same buffer.
 1502        lsp_store.update(cx, |this, cx| {
 1503            let this = this.as_local_mut().unwrap();
 1504            buffers.retain(|buffer| {
 1505                this.buffers_being_formatted
 1506                    .insert(buffer.handle.read(cx).remote_id())
 1507            });
 1508        })?;
 1509
 1510        let _cleanup = defer({
 1511            let this = lsp_store.clone();
 1512            let mut cx = cx.clone();
 1513            let buffers = &buffers;
 1514            move || {
 1515                this.update(&mut cx, |this, cx| {
 1516                    let this = this.as_local_mut().unwrap();
 1517                    for buffer in buffers {
 1518                        this.buffers_being_formatted
 1519                            .remove(&buffer.handle.read(cx).remote_id());
 1520                    }
 1521                })
 1522                .ok();
 1523            }
 1524        });
 1525
 1526        let mut project_transaction = ProjectTransaction::default();
 1527
 1528        for buffer in &buffers {
 1529            zlog::debug!(
 1530                logger =>
 1531                "formatting buffer '{:?}'",
 1532                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1533            );
 1534            // Create an empty transaction to hold all of the formatting edits.
 1535            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1536                // ensure no transactions created while formatting are
 1537                // grouped with the previous transaction in the history
 1538                // based on the transaction group interval
 1539                buffer.finalize_last_transaction();
 1540                buffer
 1541                    .start_transaction()
 1542                    .context("transaction already open")?;
 1543                buffer.end_transaction(cx);
 1544                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1545                buffer.finalize_last_transaction();
 1546                anyhow::Ok(transaction_id)
 1547            })?;
 1548
 1549            let result = Self::format_buffer_locally(
 1550                lsp_store.clone(),
 1551                buffer,
 1552                formatting_transaction_id,
 1553                trigger,
 1554                logger,
 1555                cx,
 1556            )
 1557            .await;
 1558
 1559            buffer.handle.update(cx, |buffer, cx| {
 1560                let Some(formatting_transaction) =
 1561                    buffer.get_transaction(formatting_transaction_id).cloned()
 1562                else {
 1563                    zlog::warn!(logger => "no formatting transaction");
 1564                    return;
 1565                };
 1566                if formatting_transaction.edit_ids.is_empty() {
 1567                    zlog::debug!(logger => "no changes made while formatting");
 1568                    buffer.forget_transaction(formatting_transaction_id);
 1569                    return;
 1570                }
 1571                if !push_to_history {
 1572                    zlog::trace!(logger => "forgetting format transaction");
 1573                    buffer.forget_transaction(formatting_transaction.id);
 1574                }
 1575                project_transaction
 1576                    .0
 1577                    .insert(cx.entity(), formatting_transaction);
 1578            });
 1579
 1580            result?;
 1581        }
 1582
 1583        Ok(project_transaction)
 1584    }
 1585
 1586    async fn format_buffer_locally(
 1587        lsp_store: WeakEntity<LspStore>,
 1588        buffer: &FormattableBuffer,
 1589        formatting_transaction_id: clock::Lamport,
 1590        trigger: FormatTrigger,
 1591        logger: zlog::Logger,
 1592        cx: &mut AsyncApp,
 1593    ) -> Result<()> {
 1594        let (adapters_and_servers, settings, request_timeout) =
 1595            lsp_store.update(cx, |lsp_store, cx| {
 1596                buffer.handle.update(cx, |buffer, cx| {
 1597                    let adapters_and_servers = lsp_store
 1598                        .as_local()
 1599                        .unwrap()
 1600                        .language_servers_for_buffer(buffer, cx)
 1601                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1602                        .collect::<Vec<_>>();
 1603                    let settings =
 1604                        language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1605                            .into_owned();
 1606                    let request_timeout = ProjectSettings::get_global(cx)
 1607                        .global_lsp_settings
 1608                        .get_request_timeout();
 1609                    (adapters_and_servers, settings, request_timeout)
 1610                })
 1611            })?;
 1612
 1613        /// Apply edits to the buffer that will become part of the formatting transaction.
 1614        /// Fails if the buffer has been edited since the start of that transaction.
 1615        fn extend_formatting_transaction(
 1616            buffer: &FormattableBuffer,
 1617            formatting_transaction_id: text::TransactionId,
 1618            cx: &mut AsyncApp,
 1619            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1620        ) -> anyhow::Result<()> {
 1621            buffer.handle.update(cx, |buffer, cx| {
 1622                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1623                if last_transaction_id != Some(formatting_transaction_id) {
 1624                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1625                }
 1626                buffer.start_transaction();
 1627                operation(buffer, cx);
 1628                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1629                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1630                }
 1631                Ok(())
 1632            })
 1633        }
 1634
 1635        // handle whitespace formatting
 1636        if settings.remove_trailing_whitespace_on_save {
 1637            zlog::trace!(logger => "removing trailing whitespace");
 1638            let diff = buffer
 1639                .handle
 1640                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1641                .await;
 1642            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1643                buffer.apply_diff(diff, cx);
 1644            })?;
 1645        }
 1646
 1647        if settings.ensure_final_newline_on_save {
 1648            zlog::trace!(logger => "ensuring final newline");
 1649            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1650                buffer.ensure_final_newline(cx);
 1651            })?;
 1652        }
 1653
 1654        // Formatter for `code_actions_on_format` that runs before
 1655        // the rest of the formatters
 1656        let mut code_actions_on_format_formatters = None;
 1657        let should_run_code_actions_on_format = !matches!(
 1658            (trigger, &settings.format_on_save),
 1659            (FormatTrigger::Save, &FormatOnSave::Off)
 1660        );
 1661        if should_run_code_actions_on_format {
 1662            let have_code_actions_to_run_on_format = settings
 1663                .code_actions_on_format
 1664                .values()
 1665                .any(|enabled| *enabled);
 1666            if have_code_actions_to_run_on_format {
 1667                zlog::trace!(logger => "going to run code actions on format");
 1668                code_actions_on_format_formatters = Some(
 1669                    settings
 1670                        .code_actions_on_format
 1671                        .iter()
 1672                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1673                        .cloned()
 1674                        .map(Formatter::CodeAction)
 1675                        .collect::<Vec<_>>(),
 1676                );
 1677            }
 1678        }
 1679
 1680        let formatters = match (trigger, &settings.format_on_save) {
 1681            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1682            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1683                settings.formatter.as_ref()
 1684            }
 1685        };
 1686
 1687        let formatters = code_actions_on_format_formatters
 1688            .iter()
 1689            .flatten()
 1690            .chain(formatters);
 1691
 1692        for formatter in formatters {
 1693            let formatter = if formatter == &Formatter::Auto {
 1694                if settings.prettier.allowed {
 1695                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1696                    &Formatter::Prettier
 1697                } else {
 1698                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1699                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1700                }
 1701            } else {
 1702                formatter
 1703            };
 1704            match formatter {
 1705                Formatter::Auto => unreachable!("Auto resolved above"),
 1706                Formatter::Prettier => {
 1707                    let logger = zlog::scoped!(logger => "prettier");
 1708                    zlog::trace!(logger => "formatting");
 1709                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1710
 1711                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1712                        lsp_store.prettier_store().unwrap().downgrade()
 1713                    })?;
 1714                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1715                        .await
 1716                        .transpose()?;
 1717                    let Some(diff) = diff else {
 1718                        zlog::trace!(logger => "No changes");
 1719                        continue;
 1720                    };
 1721
 1722                    extend_formatting_transaction(
 1723                        buffer,
 1724                        formatting_transaction_id,
 1725                        cx,
 1726                        |buffer, cx| {
 1727                            buffer.apply_diff(diff, cx);
 1728                        },
 1729                    )?;
 1730                }
 1731                Formatter::External { command, arguments } => {
 1732                    let logger = zlog::scoped!(logger => "command");
 1733                    zlog::trace!(logger => "formatting");
 1734                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1735
 1736                    let diff = Self::format_via_external_command(
 1737                        buffer,
 1738                        &command,
 1739                        arguments.as_deref(),
 1740                        cx,
 1741                    )
 1742                    .await
 1743                    .with_context(|| {
 1744                        format!("Failed to format buffer via external command: {}", command)
 1745                    })?;
 1746                    let Some(diff) = diff else {
 1747                        zlog::trace!(logger => "No changes");
 1748                        continue;
 1749                    };
 1750
 1751                    extend_formatting_transaction(
 1752                        buffer,
 1753                        formatting_transaction_id,
 1754                        cx,
 1755                        |buffer, cx| {
 1756                            buffer.apply_diff(diff, cx);
 1757                        },
 1758                    )?;
 1759                }
 1760                Formatter::LanguageServer(specifier) => {
 1761                    let logger = zlog::scoped!(logger => "language-server");
 1762                    zlog::trace!(logger => "formatting");
 1763                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1764
 1765                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1766                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1767                        continue;
 1768                    };
 1769
 1770                    let language_server = match specifier {
 1771                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1772                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1773                                if adapter.name.0.as_ref() == name {
 1774                                    Some(server.clone())
 1775                                } else {
 1776                                    None
 1777                                }
 1778                            })
 1779                        }
 1780                        settings::LanguageServerFormatterSpecifier::Current => {
 1781                            adapters_and_servers.first().map(|e| e.1.clone())
 1782                        }
 1783                    };
 1784
 1785                    let Some(language_server) = language_server else {
 1786                        log::debug!(
 1787                            "No language server found to format buffer '{:?}'. Skipping",
 1788                            buffer_path_abs.as_path().to_string_lossy()
 1789                        );
 1790                        continue;
 1791                    };
 1792
 1793                    zlog::trace!(
 1794                        logger =>
 1795                        "Formatting buffer '{:?}' using language server '{:?}'",
 1796                        buffer_path_abs.as_path().to_string_lossy(),
 1797                        language_server.name()
 1798                    );
 1799
 1800                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1801                        zlog::trace!(logger => "formatting ranges");
 1802                        Self::format_ranges_via_lsp(
 1803                            &lsp_store,
 1804                            &buffer.handle,
 1805                            ranges,
 1806                            buffer_path_abs,
 1807                            &language_server,
 1808                            &settings,
 1809                            cx,
 1810                        )
 1811                        .await
 1812                        .context("Failed to format ranges via language server")?
 1813                    } else {
 1814                        zlog::trace!(logger => "formatting full");
 1815                        Self::format_via_lsp(
 1816                            &lsp_store,
 1817                            &buffer.handle,
 1818                            buffer_path_abs,
 1819                            &language_server,
 1820                            &settings,
 1821                            cx,
 1822                        )
 1823                        .await
 1824                        .context("failed to format via language server")?
 1825                    };
 1826
 1827                    if edits.is_empty() {
 1828                        zlog::trace!(logger => "No changes");
 1829                        continue;
 1830                    }
 1831                    extend_formatting_transaction(
 1832                        buffer,
 1833                        formatting_transaction_id,
 1834                        cx,
 1835                        |buffer, cx| {
 1836                            buffer.edit(edits, None, cx);
 1837                        },
 1838                    )?;
 1839                }
 1840                Formatter::CodeAction(code_action_name) => {
 1841                    let logger = zlog::scoped!(logger => "code-actions");
 1842                    zlog::trace!(logger => "formatting");
 1843                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1844
 1845                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1846                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1847                        continue;
 1848                    };
 1849
 1850                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1851                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1852
 1853                    let mut actions_and_servers = Vec::new();
 1854
 1855                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1856                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1857                            &lsp_store,
 1858                            language_server.server_id(),
 1859                            vec![code_action_kind.clone()],
 1860                            &buffer.handle,
 1861                            cx,
 1862                        )
 1863                        .await
 1864                        .with_context(|| {
 1865                            format!(
 1866                                "Failed to resolve code action {:?} with language server {}",
 1867                                code_action_kind,
 1868                                language_server.name()
 1869                            )
 1870                        });
 1871                        let Ok(actions) = actions_result else {
 1872                            // note: it may be better to set result to the error and break formatters here
 1873                            // but for now we try to execute the actions that we can resolve and skip the rest
 1874                            zlog::error!(
 1875                                logger =>
 1876                                "Failed to resolve code action {:?} with language server {}",
 1877                                code_action_kind,
 1878                                language_server.name()
 1879                            );
 1880                            continue;
 1881                        };
 1882                        for action in actions {
 1883                            actions_and_servers.push((action, index));
 1884                        }
 1885                    }
 1886
 1887                    if actions_and_servers.is_empty() {
 1888                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1889                        continue;
 1890                    }
 1891
 1892                    'actions: for (mut action, server_index) in actions_and_servers {
 1893                        let server = &adapters_and_servers[server_index].1;
 1894
 1895                        let describe_code_action = |action: &CodeAction| {
 1896                            format!(
 1897                                "code action '{}' with title \"{}\" on server {}",
 1898                                action
 1899                                    .lsp_action
 1900                                    .action_kind()
 1901                                    .unwrap_or("unknown".into())
 1902                                    .as_str(),
 1903                                action.lsp_action.title(),
 1904                                server.name(),
 1905                            )
 1906                        };
 1907
 1908                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1909
 1910                        if let Err(err) =
 1911                            Self::try_resolve_code_action(server, &mut action, request_timeout)
 1912                                .await
 1913                        {
 1914                            zlog::error!(
 1915                                logger =>
 1916                                "Failed to resolve {}. Error: {}",
 1917                                describe_code_action(&action),
 1918                                err
 1919                            );
 1920                            continue;
 1921                        }
 1922
 1923                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1924                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1925                            // but filters out and logs warnings for code actions that require unreasonably
 1926                            // difficult handling on our part, such as:
 1927                            // - applying edits that call commands
 1928                            //   which can result in arbitrary workspace edits being sent from the server that
 1929                            //   have no way of being tied back to the command that initiated them (i.e. we
 1930                            //   can't know which edits are part of the format request, or if the server is done sending
 1931                            //   actions in response to the command)
 1932                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1933                            //   as we then would need to handle such changes correctly in the local history as well
 1934                            //   as the remote history through the ProjectTransaction
 1935                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1936                            // Supporting these actions is not impossible, but not supported as of yet.
 1937                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1938                                zlog::trace!(
 1939                                    logger =>
 1940                                    "No changes for code action. Skipping {}",
 1941                                    describe_code_action(&action),
 1942                                );
 1943                                continue;
 1944                            }
 1945
 1946                            let mut operations = Vec::new();
 1947                            if let Some(document_changes) = edit.document_changes {
 1948                                match document_changes {
 1949                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1950                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1951                                    ),
 1952                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1953                                }
 1954                            } else if let Some(changes) = edit.changes {
 1955                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1956                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1957                                        text_document:
 1958                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1959                                                uri,
 1960                                                version: None,
 1961                                            },
 1962                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1963                                    })
 1964                                }));
 1965                            }
 1966
 1967                            let mut edits = Vec::with_capacity(operations.len());
 1968
 1969                            if operations.is_empty() {
 1970                                zlog::trace!(
 1971                                    logger =>
 1972                                    "No changes for code action. Skipping {}",
 1973                                    describe_code_action(&action),
 1974                                );
 1975                                continue;
 1976                            }
 1977                            for operation in operations {
 1978                                let op = match operation {
 1979                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1980                                    lsp::DocumentChangeOperation::Op(_) => {
 1981                                        zlog::warn!(
 1982                                            logger =>
 1983                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1984                                            describe_code_action(&action),
 1985                                        );
 1986                                        continue 'actions;
 1987                                    }
 1988                                };
 1989                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1990                                    zlog::warn!(
 1991                                        logger =>
 1992                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1993                                        &op.text_document.uri,
 1994                                        describe_code_action(&action),
 1995                                    );
 1996                                    continue 'actions;
 1997                                };
 1998                                if &file_path != buffer_path_abs {
 1999                                    zlog::warn!(
 2000                                        logger =>
 2001                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 2002                                        file_path,
 2003                                        buffer_path_abs,
 2004                                        describe_code_action(&action),
 2005                                    );
 2006                                    continue 'actions;
 2007                                }
 2008
 2009                                let mut lsp_edits = Vec::new();
 2010                                for edit in op.edits {
 2011                                    match edit {
 2012                                        Edit::Plain(edit) => {
 2013                                            if !lsp_edits.contains(&edit) {
 2014                                                lsp_edits.push(edit);
 2015                                            }
 2016                                        }
 2017                                        Edit::Annotated(edit) => {
 2018                                            if !lsp_edits.contains(&edit.text_edit) {
 2019                                                lsp_edits.push(edit.text_edit);
 2020                                            }
 2021                                        }
 2022                                        Edit::Snippet(_) => {
 2023                                            zlog::warn!(
 2024                                                logger =>
 2025                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 2026                                                describe_code_action(&action),
 2027                                            );
 2028                                            continue 'actions;
 2029                                        }
 2030                                    }
 2031                                }
 2032                                let edits_result = lsp_store
 2033                                    .update(cx, |lsp_store, cx| {
 2034                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 2035                                            &buffer.handle,
 2036                                            lsp_edits,
 2037                                            server.server_id(),
 2038                                            op.text_document.version,
 2039                                            cx,
 2040                                        )
 2041                                    })?
 2042                                    .await;
 2043                                let Ok(resolved_edits) = edits_result else {
 2044                                    zlog::warn!(
 2045                                        logger =>
 2046                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 2047                                        buffer_path_abs.as_path(),
 2048                                        describe_code_action(&action),
 2049                                    );
 2050                                    continue 'actions;
 2051                                };
 2052                                edits.extend(resolved_edits);
 2053                            }
 2054
 2055                            if edits.is_empty() {
 2056                                zlog::warn!(logger => "No edits resolved from LSP");
 2057                                continue;
 2058                            }
 2059
 2060                            extend_formatting_transaction(
 2061                                buffer,
 2062                                formatting_transaction_id,
 2063                                cx,
 2064                                |buffer, cx| {
 2065                                    zlog::info!(
 2066                                        "Applying edits {edits:?}. Content: {:?}",
 2067                                        buffer.text()
 2068                                    );
 2069                                    buffer.edit(edits, None, cx);
 2070                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 2071                                },
 2072                            )?;
 2073                        }
 2074
 2075                        // bail early if command is invalid
 2076                        let Some(command) = action.lsp_action.command() else {
 2077                            continue;
 2078                        };
 2079
 2080                        zlog::warn!(
 2081                            logger =>
 2082                            "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 2083                            &command.command,
 2084                        );
 2085
 2086                        let server_capabilities = server.capabilities();
 2087                        let available_commands = server_capabilities
 2088                            .execute_command_provider
 2089                            .as_ref()
 2090                            .map(|options| options.commands.as_slice())
 2091                            .unwrap_or_default();
 2092                        if !available_commands.contains(&command.command) {
 2093                            zlog::warn!(
 2094                                logger =>
 2095                                "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2096                                command.command,
 2097                                server.name(),
 2098                            );
 2099                            continue;
 2100                        }
 2101
 2102                        // noop so we just ensure buffer hasn't been edited since resolving code actions
 2103                        extend_formatting_transaction(
 2104                            buffer,
 2105                            formatting_transaction_id,
 2106                            cx,
 2107                            |_, _| {},
 2108                        )?;
 2109                        zlog::info!(logger => "Executing command {}", &command.command);
 2110
 2111                        lsp_store.update(cx, |this, _| {
 2112                            this.as_local_mut()
 2113                                .unwrap()
 2114                                .last_workspace_edits_by_language_server
 2115                                .remove(&server.server_id());
 2116                        })?;
 2117
 2118                        let execute_command_result = server
 2119                            .request::<lsp::request::ExecuteCommand>(
 2120                                lsp::ExecuteCommandParams {
 2121                                    command: command.command.clone(),
 2122                                    arguments: command.arguments.clone().unwrap_or_default(),
 2123                                    ..Default::default()
 2124                                },
 2125                                request_timeout,
 2126                            )
 2127                            .await
 2128                            .into_response();
 2129
 2130                        if execute_command_result.is_err() {
 2131                            zlog::error!(
 2132                                logger =>
 2133                                "Failed to execute command '{}' as part of {}",
 2134                                &command.command,
 2135                                describe_code_action(&action),
 2136                            );
 2137                            continue 'actions;
 2138                        }
 2139
 2140                        let mut project_transaction_command = lsp_store.update(cx, |this, _| {
 2141                            this.as_local_mut()
 2142                                .unwrap()
 2143                                .last_workspace_edits_by_language_server
 2144                                .remove(&server.server_id())
 2145                                .unwrap_or_default()
 2146                        })?;
 2147
 2148                        if let Some(transaction) =
 2149                            project_transaction_command.0.remove(&buffer.handle)
 2150                        {
 2151                            zlog::trace!(
 2152                                logger =>
 2153                                "Successfully captured {} edits that resulted from command {}",
 2154                                transaction.edit_ids.len(),
 2155                                &command.command,
 2156                            );
 2157                            let transaction_id_project_transaction = transaction.id;
 2158                            buffer.handle.update(cx, |buffer, _| {
 2159                                // it may have been removed from history if push_to_history was
 2160                                // false in deserialize_workspace_edit. If so push it so we
 2161                                // can merge it with the format transaction
 2162                                // and pop the combined transaction off the history stack
 2163                                // later if push_to_history is false
 2164                                if buffer.get_transaction(transaction.id).is_none() {
 2165                                    buffer.push_transaction(transaction, Instant::now());
 2166                                }
 2167                                buffer.merge_transactions(
 2168                                    transaction_id_project_transaction,
 2169                                    formatting_transaction_id,
 2170                                );
 2171                            });
 2172                        }
 2173
 2174                        if project_transaction_command.0.is_empty() {
 2175                            continue;
 2176                        }
 2177
 2178                        let mut extra_buffers = String::new();
 2179                        for buffer in project_transaction_command.0.keys() {
 2180                            buffer.read_with(cx, |b, cx| {
 2181                                let Some(path) = b.project_path(cx) else {
 2182                                    return;
 2183                                };
 2184
 2185                                if !extra_buffers.is_empty() {
 2186                                    extra_buffers.push_str(", ");
 2187                                }
 2188                                extra_buffers.push_str(path.path.as_unix_str());
 2189                            });
 2190                        }
 2191                        zlog::warn!(
 2192                            logger =>
 2193                            "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2194                            &command.command,
 2195                            extra_buffers,
 2196                        );
 2197                        // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2198                        // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2199                        // add it so it's included, and merge it into the format transaction when its created later
 2200                    }
 2201                }
 2202            }
 2203        }
 2204
 2205        Ok(())
 2206    }
 2207
 2208    pub async fn format_ranges_via_lsp(
 2209        this: &WeakEntity<LspStore>,
 2210        buffer_handle: &Entity<Buffer>,
 2211        ranges: &[Range<Anchor>],
 2212        abs_path: &Path,
 2213        language_server: &Arc<LanguageServer>,
 2214        settings: &LanguageSettings,
 2215        cx: &mut AsyncApp,
 2216    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2217        let capabilities = &language_server.capabilities();
 2218        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2219        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2220            anyhow::bail!(
 2221                "{} language server does not support range formatting",
 2222                language_server.name()
 2223            );
 2224        }
 2225
 2226        let uri = file_path_to_lsp_url(abs_path)?;
 2227        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2228
 2229        let request_timeout = cx.update(|app| {
 2230            ProjectSettings::get_global(app)
 2231                .global_lsp_settings
 2232                .get_request_timeout()
 2233        });
 2234        let lsp_edits = {
 2235            let mut lsp_ranges = Vec::new();
 2236            this.update(cx, |_this, cx| {
 2237                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2238                // not have been sent to the language server. This seems like a fairly systemic
 2239                // issue, though, the resolution probably is not specific to formatting.
 2240                //
 2241                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2242                // LSP.
 2243                let snapshot = buffer_handle.read(cx).snapshot();
 2244                for range in ranges {
 2245                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2246                }
 2247                anyhow::Ok(())
 2248            })??;
 2249
 2250            let mut edits = None;
 2251            for range in lsp_ranges {
 2252                if let Some(mut edit) = language_server
 2253                    .request::<lsp::request::RangeFormatting>(
 2254                        lsp::DocumentRangeFormattingParams {
 2255                            text_document: text_document.clone(),
 2256                            range,
 2257                            options: lsp_command::lsp_formatting_options(settings),
 2258                            work_done_progress_params: Default::default(),
 2259                        },
 2260                        request_timeout,
 2261                    )
 2262                    .await
 2263                    .into_response()?
 2264                {
 2265                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2266                }
 2267            }
 2268            edits
 2269        };
 2270
 2271        if let Some(lsp_edits) = lsp_edits {
 2272            this.update(cx, |this, cx| {
 2273                this.as_local_mut().unwrap().edits_from_lsp(
 2274                    buffer_handle,
 2275                    lsp_edits,
 2276                    language_server.server_id(),
 2277                    None,
 2278                    cx,
 2279                )
 2280            })?
 2281            .await
 2282        } else {
 2283            Ok(Vec::with_capacity(0))
 2284        }
 2285    }
 2286
 2287    async fn format_via_lsp(
 2288        this: &WeakEntity<LspStore>,
 2289        buffer: &Entity<Buffer>,
 2290        abs_path: &Path,
 2291        language_server: &Arc<LanguageServer>,
 2292        settings: &LanguageSettings,
 2293        cx: &mut AsyncApp,
 2294    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2295        let logger = zlog::scoped!("lsp_format");
 2296        zlog::debug!(logger => "Formatting via LSP");
 2297
 2298        let uri = file_path_to_lsp_url(abs_path)?;
 2299        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2300        let capabilities = &language_server.capabilities();
 2301
 2302        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2303        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2304
 2305        let request_timeout = cx.update(|app| {
 2306            ProjectSettings::get_global(app)
 2307                .global_lsp_settings
 2308                .get_request_timeout()
 2309        });
 2310
 2311        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2312            let _timer = zlog::time!(logger => "format-full");
 2313            language_server
 2314                .request::<lsp::request::Formatting>(
 2315                    lsp::DocumentFormattingParams {
 2316                        text_document,
 2317                        options: lsp_command::lsp_formatting_options(settings),
 2318                        work_done_progress_params: Default::default(),
 2319                    },
 2320                    request_timeout,
 2321                )
 2322                .await
 2323                .into_response()?
 2324        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2325            let _timer = zlog::time!(logger => "format-range");
 2326            let buffer_start = lsp::Position::new(0, 0);
 2327            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2328            language_server
 2329                .request::<lsp::request::RangeFormatting>(
 2330                    lsp::DocumentRangeFormattingParams {
 2331                        text_document: text_document.clone(),
 2332                        range: lsp::Range::new(buffer_start, buffer_end),
 2333                        options: lsp_command::lsp_formatting_options(settings),
 2334                        work_done_progress_params: Default::default(),
 2335                    },
 2336                    request_timeout,
 2337                )
 2338                .await
 2339                .into_response()?
 2340        } else {
 2341            None
 2342        };
 2343
 2344        if let Some(lsp_edits) = lsp_edits {
 2345            this.update(cx, |this, cx| {
 2346                this.as_local_mut().unwrap().edits_from_lsp(
 2347                    buffer,
 2348                    lsp_edits,
 2349                    language_server.server_id(),
 2350                    None,
 2351                    cx,
 2352                )
 2353            })?
 2354            .await
 2355        } else {
 2356            Ok(Vec::with_capacity(0))
 2357        }
 2358    }
 2359
 2360    async fn format_via_external_command(
 2361        buffer: &FormattableBuffer,
 2362        command: &str,
 2363        arguments: Option<&[String]>,
 2364        cx: &mut AsyncApp,
 2365    ) -> Result<Option<Diff>> {
 2366        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2367            let file = File::from_dyn(buffer.file())?;
 2368            let worktree = file.worktree.read(cx);
 2369            let mut worktree_path = worktree.abs_path().to_path_buf();
 2370            if worktree.root_entry()?.is_file() {
 2371                worktree_path.pop();
 2372            }
 2373            Some(worktree_path)
 2374        });
 2375
 2376        let mut child = util::command::new_smol_command(command);
 2377
 2378        if let Some(buffer_env) = buffer.env.as_ref() {
 2379            child.envs(buffer_env);
 2380        }
 2381
 2382        if let Some(working_dir_path) = working_dir_path {
 2383            child.current_dir(working_dir_path);
 2384        }
 2385
 2386        if let Some(arguments) = arguments {
 2387            child.args(arguments.iter().map(|arg| {
 2388                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2389                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2390                } else {
 2391                    arg.replace("{buffer_path}", "Untitled")
 2392                }
 2393            }));
 2394        }
 2395
 2396        let mut child = child
 2397            .stdin(smol::process::Stdio::piped())
 2398            .stdout(smol::process::Stdio::piped())
 2399            .stderr(smol::process::Stdio::piped())
 2400            .spawn()?;
 2401
 2402        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2403        let text = buffer
 2404            .handle
 2405            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2406        for chunk in text.chunks() {
 2407            stdin.write_all(chunk.as_bytes()).await?;
 2408        }
 2409        stdin.flush().await?;
 2410
 2411        let output = child.output().await?;
 2412        anyhow::ensure!(
 2413            output.status.success(),
 2414            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2415            output.status.code(),
 2416            String::from_utf8_lossy(&output.stdout),
 2417            String::from_utf8_lossy(&output.stderr),
 2418        );
 2419
 2420        let stdout = String::from_utf8(output.stdout)?;
 2421        Ok(Some(
 2422            buffer
 2423                .handle
 2424                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2425                .await,
 2426        ))
 2427    }
 2428
 2429    async fn try_resolve_code_action(
 2430        lang_server: &LanguageServer,
 2431        action: &mut CodeAction,
 2432        request_timeout: Duration,
 2433    ) -> anyhow::Result<()> {
 2434        match &mut action.lsp_action {
 2435            LspAction::Action(lsp_action) => {
 2436                if !action.resolved
 2437                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2438                    && lsp_action.data.is_some()
 2439                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2440                {
 2441                    **lsp_action = lang_server
 2442                        .request::<lsp::request::CodeActionResolveRequest>(
 2443                            *lsp_action.clone(),
 2444                            request_timeout,
 2445                        )
 2446                        .await
 2447                        .into_response()?;
 2448                }
 2449            }
 2450            LspAction::CodeLens(lens) => {
 2451                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2452                    *lens = lang_server
 2453                        .request::<lsp::request::CodeLensResolve>(lens.clone(), request_timeout)
 2454                        .await
 2455                        .into_response()?;
 2456                }
 2457            }
 2458            LspAction::Command(_) => {}
 2459        }
 2460
 2461        action.resolved = true;
 2462        anyhow::Ok(())
 2463    }
 2464
 2465    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2466        let buffer = buffer_handle.read(cx);
 2467
 2468        let file = buffer.file().cloned();
 2469
 2470        let Some(file) = File::from_dyn(file.as_ref()) else {
 2471            return;
 2472        };
 2473        if !file.is_local() {
 2474            return;
 2475        }
 2476        let path = ProjectPath::from_file(file, cx);
 2477        let worktree_id = file.worktree_id(cx);
 2478        let language = buffer.language().cloned();
 2479
 2480        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2481            for (server_id, diagnostics) in
 2482                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2483            {
 2484                self.update_buffer_diagnostics(
 2485                    buffer_handle,
 2486                    server_id,
 2487                    None,
 2488                    None,
 2489                    None,
 2490                    Vec::new(),
 2491                    diagnostics,
 2492                    cx,
 2493                )
 2494                .log_err();
 2495            }
 2496        }
 2497        let Some(language) = language else {
 2498            return;
 2499        };
 2500        let Some(snapshot) = self
 2501            .worktree_store
 2502            .read(cx)
 2503            .worktree_for_id(worktree_id, cx)
 2504            .map(|worktree| worktree.read(cx).snapshot())
 2505        else {
 2506            return;
 2507        };
 2508        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2509
 2510        for server_id in
 2511            self.lsp_tree
 2512                .get(path, language.name(), language.manifest(), &delegate, cx)
 2513        {
 2514            let server = self
 2515                .language_servers
 2516                .get(&server_id)
 2517                .and_then(|server_state| {
 2518                    if let LanguageServerState::Running { server, .. } = server_state {
 2519                        Some(server.clone())
 2520                    } else {
 2521                        None
 2522                    }
 2523                });
 2524            let server = match server {
 2525                Some(server) => server,
 2526                None => continue,
 2527            };
 2528
 2529            buffer_handle.update(cx, |buffer, cx| {
 2530                buffer.set_completion_triggers(
 2531                    server.server_id(),
 2532                    server
 2533                        .capabilities()
 2534                        .completion_provider
 2535                        .as_ref()
 2536                        .and_then(|provider| {
 2537                            provider
 2538                                .trigger_characters
 2539                                .as_ref()
 2540                                .map(|characters| characters.iter().cloned().collect())
 2541                        })
 2542                        .unwrap_or_default(),
 2543                    cx,
 2544                );
 2545            });
 2546        }
 2547    }
 2548
 2549    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2550        buffer.update(cx, |buffer, cx| {
 2551            let Some(language) = buffer.language() else {
 2552                return;
 2553            };
 2554            let path = ProjectPath {
 2555                worktree_id: old_file.worktree_id(cx),
 2556                path: old_file.path.clone(),
 2557            };
 2558            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2559                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2560                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2561            }
 2562        });
 2563    }
 2564
 2565    fn update_buffer_diagnostics(
 2566        &mut self,
 2567        buffer: &Entity<Buffer>,
 2568        server_id: LanguageServerId,
 2569        registration_id: Option<Option<SharedString>>,
 2570        result_id: Option<SharedString>,
 2571        version: Option<i32>,
 2572        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2573        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2574        cx: &mut Context<LspStore>,
 2575    ) -> Result<()> {
 2576        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2577            Ordering::Equal
 2578                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2579                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2580                .then_with(|| a.severity.cmp(&b.severity))
 2581                .then_with(|| a.message.cmp(&b.message))
 2582        }
 2583
 2584        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2585        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2586        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2587
 2588        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2589            Ordering::Equal
 2590                .then_with(|| a.range.start.cmp(&b.range.start))
 2591                .then_with(|| b.range.end.cmp(&a.range.end))
 2592                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2593        });
 2594
 2595        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2596
 2597        let edits_since_save = std::cell::LazyCell::new(|| {
 2598            let saved_version = buffer.read(cx).saved_version();
 2599            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2600        });
 2601
 2602        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2603
 2604        for (new_diagnostic, entry) in diagnostics {
 2605            let start;
 2606            let end;
 2607            if new_diagnostic && entry.diagnostic.is_disk_based {
 2608                // Some diagnostics are based on files on disk instead of buffers'
 2609                // current contents. Adjust these diagnostics' ranges to reflect
 2610                // any unsaved edits.
 2611                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2612                // and were properly adjusted on reuse.
 2613                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2614                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2615            } else {
 2616                start = entry.range.start;
 2617                end = entry.range.end;
 2618            }
 2619
 2620            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2621                ..snapshot.clip_point_utf16(end, Bias::Right);
 2622
 2623            // Expand empty ranges by one codepoint
 2624            if range.start == range.end {
 2625                // This will be go to the next boundary when being clipped
 2626                range.end.column += 1;
 2627                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2628                if range.start == range.end && range.end.column > 0 {
 2629                    range.start.column -= 1;
 2630                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2631                }
 2632            }
 2633
 2634            sanitized_diagnostics.push(DiagnosticEntry {
 2635                range,
 2636                diagnostic: entry.diagnostic,
 2637            });
 2638        }
 2639        drop(edits_since_save);
 2640
 2641        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2642        buffer.update(cx, |buffer, cx| {
 2643            if let Some(registration_id) = registration_id {
 2644                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2645                    self.buffer_pull_diagnostics_result_ids
 2646                        .entry(server_id)
 2647                        .or_default()
 2648                        .entry(registration_id)
 2649                        .or_default()
 2650                        .insert(abs_path, result_id);
 2651                }
 2652            }
 2653
 2654            buffer.update_diagnostics(server_id, set, cx)
 2655        });
 2656
 2657        Ok(())
 2658    }
 2659
 2660    fn register_language_server_for_invisible_worktree(
 2661        &mut self,
 2662        worktree: &Entity<Worktree>,
 2663        language_server_id: LanguageServerId,
 2664        cx: &mut App,
 2665    ) {
 2666        let worktree = worktree.read(cx);
 2667        let worktree_id = worktree.id();
 2668        debug_assert!(!worktree.is_visible());
 2669        let Some(mut origin_seed) = self
 2670            .language_server_ids
 2671            .iter()
 2672            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2673        else {
 2674            return;
 2675        };
 2676        origin_seed.worktree_id = worktree_id;
 2677        self.language_server_ids
 2678            .entry(origin_seed)
 2679            .or_insert_with(|| UnifiedLanguageServer {
 2680                id: language_server_id,
 2681                project_roots: Default::default(),
 2682            });
 2683    }
 2684
 2685    fn register_buffer_with_language_servers(
 2686        &mut self,
 2687        buffer_handle: &Entity<Buffer>,
 2688        only_register_servers: HashSet<LanguageServerSelector>,
 2689        cx: &mut Context<LspStore>,
 2690    ) {
 2691        let buffer = buffer_handle.read(cx);
 2692        let buffer_id = buffer.remote_id();
 2693
 2694        let Some(file) = File::from_dyn(buffer.file()) else {
 2695            return;
 2696        };
 2697        if !file.is_local() {
 2698            return;
 2699        }
 2700
 2701        let abs_path = file.abs_path(cx);
 2702        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2703            return;
 2704        };
 2705        let initial_snapshot = buffer.text_snapshot();
 2706        let worktree_id = file.worktree_id(cx);
 2707
 2708        let Some(language) = buffer.language().cloned() else {
 2709            return;
 2710        };
 2711        let path: Arc<RelPath> = file
 2712            .path()
 2713            .parent()
 2714            .map(Arc::from)
 2715            .unwrap_or_else(|| file.path().clone());
 2716        let Some(worktree) = self
 2717            .worktree_store
 2718            .read(cx)
 2719            .worktree_for_id(worktree_id, cx)
 2720        else {
 2721            return;
 2722        };
 2723        let language_name = language.name();
 2724        let (reused, delegate, servers) = self
 2725            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2726            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2727            .unwrap_or_else(|| {
 2728                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2729                let delegate: Arc<dyn ManifestDelegate> =
 2730                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2731
 2732                let servers = self
 2733                    .lsp_tree
 2734                    .walk(
 2735                        ProjectPath { worktree_id, path },
 2736                        language.name(),
 2737                        language.manifest(),
 2738                        &delegate,
 2739                        cx,
 2740                    )
 2741                    .collect::<Vec<_>>();
 2742                (false, lsp_delegate, servers)
 2743            });
 2744        let servers_and_adapters = servers
 2745            .into_iter()
 2746            .filter_map(|server_node| {
 2747                if reused && server_node.server_id().is_none() {
 2748                    return None;
 2749                }
 2750                if !only_register_servers.is_empty() {
 2751                    if let Some(server_id) = server_node.server_id()
 2752                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2753                    {
 2754                        return None;
 2755                    }
 2756                    if let Some(name) = server_node.name()
 2757                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2758                    {
 2759                        return None;
 2760                    }
 2761                }
 2762
 2763                let server_id = server_node.server_id_or_init(|disposition| {
 2764                    let path = &disposition.path;
 2765
 2766                    {
 2767                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2768
 2769                        let server_id = self.get_or_insert_language_server(
 2770                            &worktree,
 2771                            delegate.clone(),
 2772                            disposition,
 2773                            &language_name,
 2774                            cx,
 2775                        );
 2776
 2777                        if let Some(state) = self.language_servers.get(&server_id)
 2778                            && let Ok(uri) = uri
 2779                        {
 2780                            state.add_workspace_folder(uri);
 2781                        };
 2782                        server_id
 2783                    }
 2784                })?;
 2785                let server_state = self.language_servers.get(&server_id)?;
 2786                if let LanguageServerState::Running {
 2787                    server, adapter, ..
 2788                } = server_state
 2789                {
 2790                    Some((server.clone(), adapter.clone()))
 2791                } else {
 2792                    None
 2793                }
 2794            })
 2795            .collect::<Vec<_>>();
 2796        for (server, adapter) in servers_and_adapters {
 2797            buffer_handle.update(cx, |buffer, cx| {
 2798                buffer.set_completion_triggers(
 2799                    server.server_id(),
 2800                    server
 2801                        .capabilities()
 2802                        .completion_provider
 2803                        .as_ref()
 2804                        .and_then(|provider| {
 2805                            provider
 2806                                .trigger_characters
 2807                                .as_ref()
 2808                                .map(|characters| characters.iter().cloned().collect())
 2809                        })
 2810                        .unwrap_or_default(),
 2811                    cx,
 2812                );
 2813            });
 2814
 2815            let snapshot = LspBufferSnapshot {
 2816                version: 0,
 2817                snapshot: initial_snapshot.clone(),
 2818            };
 2819
 2820            let mut registered = false;
 2821            self.buffer_snapshots
 2822                .entry(buffer_id)
 2823                .or_default()
 2824                .entry(server.server_id())
 2825                .or_insert_with(|| {
 2826                    registered = true;
 2827                    server.register_buffer(
 2828                        uri.clone(),
 2829                        adapter.language_id(&language.name()),
 2830                        0,
 2831                        initial_snapshot.text(),
 2832                    );
 2833
 2834                    vec![snapshot]
 2835                });
 2836
 2837            self.buffers_opened_in_servers
 2838                .entry(buffer_id)
 2839                .or_default()
 2840                .insert(server.server_id());
 2841            if registered {
 2842                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2843                    language_server_id: server.server_id(),
 2844                    name: None,
 2845                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2846                        proto::RegisteredForBuffer {
 2847                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2848                            buffer_id: buffer_id.to_proto(),
 2849                        },
 2850                    ),
 2851                });
 2852            }
 2853        }
 2854    }
 2855
 2856    fn reuse_existing_language_server<'lang_name>(
 2857        &self,
 2858        server_tree: &LanguageServerTree,
 2859        worktree: &Entity<Worktree>,
 2860        language_name: &'lang_name LanguageName,
 2861        cx: &mut App,
 2862    ) -> Option<(
 2863        Arc<LocalLspAdapterDelegate>,
 2864        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2865    )> {
 2866        if worktree.read(cx).is_visible() {
 2867            return None;
 2868        }
 2869
 2870        let worktree_store = self.worktree_store.read(cx);
 2871        let servers = server_tree
 2872            .instances
 2873            .iter()
 2874            .filter(|(worktree_id, _)| {
 2875                worktree_store
 2876                    .worktree_for_id(**worktree_id, cx)
 2877                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2878            })
 2879            .flat_map(|(worktree_id, servers)| {
 2880                servers
 2881                    .roots
 2882                    .iter()
 2883                    .flat_map(|(_, language_servers)| language_servers)
 2884                    .map(move |(_, (server_node, server_languages))| {
 2885                        (worktree_id, server_node, server_languages)
 2886                    })
 2887                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2888                    .map(|(worktree_id, server_node, _)| {
 2889                        (
 2890                            *worktree_id,
 2891                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2892                        )
 2893                    })
 2894            })
 2895            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2896                acc.entry(worktree_id)
 2897                    .or_insert_with(Vec::new)
 2898                    .push(server_node);
 2899                acc
 2900            })
 2901            .into_values()
 2902            .max_by_key(|servers| servers.len())?;
 2903
 2904        let worktree_id = worktree.read(cx).id();
 2905        let apply = move |tree: &mut LanguageServerTree| {
 2906            for server_node in &servers {
 2907                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2908            }
 2909            servers
 2910        };
 2911
 2912        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2913        Some((delegate, apply))
 2914    }
 2915
 2916    pub(crate) fn unregister_old_buffer_from_language_servers(
 2917        &mut self,
 2918        buffer: &Entity<Buffer>,
 2919        old_file: &File,
 2920        cx: &mut App,
 2921    ) {
 2922        let old_path = match old_file.as_local() {
 2923            Some(local) => local.abs_path(cx),
 2924            None => return,
 2925        };
 2926
 2927        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2928            debug_panic!("{old_path:?} is not parseable as an URI");
 2929            return;
 2930        };
 2931        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2932    }
 2933
 2934    pub(crate) fn unregister_buffer_from_language_servers(
 2935        &mut self,
 2936        buffer: &Entity<Buffer>,
 2937        file_url: &lsp::Uri,
 2938        cx: &mut App,
 2939    ) {
 2940        buffer.update(cx, |buffer, cx| {
 2941            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2942
 2943            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2944                if snapshots
 2945                    .as_mut()
 2946                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2947                {
 2948                    language_server.unregister_buffer(file_url.clone());
 2949                }
 2950            }
 2951        });
 2952    }
 2953
 2954    fn buffer_snapshot_for_lsp_version(
 2955        &mut self,
 2956        buffer: &Entity<Buffer>,
 2957        server_id: LanguageServerId,
 2958        version: Option<i32>,
 2959        cx: &App,
 2960    ) -> Result<TextBufferSnapshot> {
 2961        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2962
 2963        if let Some(version) = version {
 2964            let buffer_id = buffer.read(cx).remote_id();
 2965            let snapshots = if let Some(snapshots) = self
 2966                .buffer_snapshots
 2967                .get_mut(&buffer_id)
 2968                .and_then(|m| m.get_mut(&server_id))
 2969            {
 2970                snapshots
 2971            } else if version == 0 {
 2972                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2973                // We detect this case and treat it as if the version was `None`.
 2974                return Ok(buffer.read(cx).text_snapshot());
 2975            } else {
 2976                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2977            };
 2978
 2979            let found_snapshot = snapshots
 2980                    .binary_search_by_key(&version, |e| e.version)
 2981                    .map(|ix| snapshots[ix].snapshot.clone())
 2982                    .map_err(|_| {
 2983                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2984                    })?;
 2985
 2986            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2987            Ok(found_snapshot)
 2988        } else {
 2989            Ok((buffer.read(cx)).text_snapshot())
 2990        }
 2991    }
 2992
 2993    async fn get_server_code_actions_from_action_kinds(
 2994        lsp_store: &WeakEntity<LspStore>,
 2995        language_server_id: LanguageServerId,
 2996        code_action_kinds: Vec<lsp::CodeActionKind>,
 2997        buffer: &Entity<Buffer>,
 2998        cx: &mut AsyncApp,
 2999    ) -> Result<Vec<CodeAction>> {
 3000        let actions = lsp_store
 3001            .update(cx, move |this, cx| {
 3002                let request = GetCodeActions {
 3003                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 3004                    kinds: Some(code_action_kinds),
 3005                };
 3006                let server = LanguageServerToQuery::Other(language_server_id);
 3007                this.request_lsp(buffer.clone(), server, request, cx)
 3008            })?
 3009            .await?;
 3010        Ok(actions)
 3011    }
 3012
 3013    pub async fn execute_code_actions_on_server(
 3014        lsp_store: &WeakEntity<LspStore>,
 3015        language_server: &Arc<LanguageServer>,
 3016        actions: Vec<CodeAction>,
 3017        push_to_history: bool,
 3018        project_transaction: &mut ProjectTransaction,
 3019        cx: &mut AsyncApp,
 3020    ) -> anyhow::Result<()> {
 3021        let request_timeout = cx.update(|app| {
 3022            ProjectSettings::get_global(app)
 3023                .global_lsp_settings
 3024                .get_request_timeout()
 3025        });
 3026
 3027        for mut action in actions {
 3028            Self::try_resolve_code_action(language_server, &mut action, request_timeout)
 3029                .await
 3030                .context("resolving a formatting code action")?;
 3031
 3032            if let Some(edit) = action.lsp_action.edit() {
 3033                if edit.changes.is_none() && edit.document_changes.is_none() {
 3034                    continue;
 3035                }
 3036
 3037                let new = Self::deserialize_workspace_edit(
 3038                    lsp_store.upgrade().context("project dropped")?,
 3039                    edit.clone(),
 3040                    push_to_history,
 3041                    language_server.clone(),
 3042                    cx,
 3043                )
 3044                .await?;
 3045                project_transaction.0.extend(new.0);
 3046            }
 3047
 3048            let Some(command) = action.lsp_action.command() else {
 3049                continue;
 3050            };
 3051
 3052            let server_capabilities = language_server.capabilities();
 3053            let available_commands = server_capabilities
 3054                .execute_command_provider
 3055                .as_ref()
 3056                .map(|options| options.commands.as_slice())
 3057                .unwrap_or_default();
 3058            if !available_commands.contains(&command.command) {
 3059                log::warn!(
 3060                    "Cannot execute a command {} not listed in the language server capabilities",
 3061                    command.command
 3062                );
 3063                continue;
 3064            }
 3065
 3066            lsp_store.update(cx, |lsp_store, _| {
 3067                if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 3068                    mode.last_workspace_edits_by_language_server
 3069                        .remove(&language_server.server_id());
 3070                }
 3071            })?;
 3072
 3073            language_server
 3074                .request::<lsp::request::ExecuteCommand>(
 3075                    lsp::ExecuteCommandParams {
 3076                        command: command.command.clone(),
 3077                        arguments: command.arguments.clone().unwrap_or_default(),
 3078                        ..Default::default()
 3079                    },
 3080                    request_timeout,
 3081                )
 3082                .await
 3083                .into_response()
 3084                .context("execute command")?;
 3085
 3086            lsp_store.update(cx, |this, _| {
 3087                if let LspStoreMode::Local(mode) = &mut this.mode {
 3088                    project_transaction.0.extend(
 3089                        mode.last_workspace_edits_by_language_server
 3090                            .remove(&language_server.server_id())
 3091                            .unwrap_or_default()
 3092                            .0,
 3093                    )
 3094                }
 3095            })?;
 3096        }
 3097        Ok(())
 3098    }
 3099
 3100    pub async fn deserialize_text_edits(
 3101        this: Entity<LspStore>,
 3102        buffer_to_edit: Entity<Buffer>,
 3103        edits: Vec<lsp::TextEdit>,
 3104        push_to_history: bool,
 3105        _: Arc<CachedLspAdapter>,
 3106        language_server: Arc<LanguageServer>,
 3107        cx: &mut AsyncApp,
 3108    ) -> Result<Option<Transaction>> {
 3109        let edits = this
 3110            .update(cx, |this, cx| {
 3111                this.as_local_mut().unwrap().edits_from_lsp(
 3112                    &buffer_to_edit,
 3113                    edits,
 3114                    language_server.server_id(),
 3115                    None,
 3116                    cx,
 3117                )
 3118            })
 3119            .await?;
 3120
 3121        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3122            buffer.finalize_last_transaction();
 3123            buffer.start_transaction();
 3124            for (range, text) in edits {
 3125                buffer.edit([(range, text)], None, cx);
 3126            }
 3127
 3128            if buffer.end_transaction(cx).is_some() {
 3129                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3130                if !push_to_history {
 3131                    buffer.forget_transaction(transaction.id);
 3132                }
 3133                Some(transaction)
 3134            } else {
 3135                None
 3136            }
 3137        });
 3138
 3139        Ok(transaction)
 3140    }
 3141
 3142    #[allow(clippy::type_complexity)]
 3143    pub fn edits_from_lsp(
 3144        &mut self,
 3145        buffer: &Entity<Buffer>,
 3146        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3147        server_id: LanguageServerId,
 3148        version: Option<i32>,
 3149        cx: &mut Context<LspStore>,
 3150    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3151        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3152        cx.background_spawn(async move {
 3153            let snapshot = snapshot?;
 3154            let mut lsp_edits = lsp_edits
 3155                .into_iter()
 3156                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3157                .collect::<Vec<_>>();
 3158
 3159            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 3160
 3161            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3162            let mut edits = Vec::new();
 3163            while let Some((range, mut new_text)) = lsp_edits.next() {
 3164                // Clip invalid ranges provided by the language server.
 3165                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3166                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3167
 3168                // Combine any LSP edits that are adjacent.
 3169                //
 3170                // Also, combine LSP edits that are separated from each other by only
 3171                // a newline. This is important because for some code actions,
 3172                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3173                // are separated by unchanged newline characters.
 3174                //
 3175                // In order for the diffing logic below to work properly, any edits that
 3176                // cancel each other out must be combined into one.
 3177                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3178                    if next_range.start.0 > range.end {
 3179                        if next_range.start.0.row > range.end.row + 1
 3180                            || next_range.start.0.column > 0
 3181                            || snapshot.clip_point_utf16(
 3182                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3183                                Bias::Left,
 3184                            ) > range.end
 3185                        {
 3186                            break;
 3187                        }
 3188                        new_text.push('\n');
 3189                    }
 3190                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3191                    new_text.push_str(next_text);
 3192                    lsp_edits.next();
 3193                }
 3194
 3195                // For multiline edits, perform a diff of the old and new text so that
 3196                // we can identify the changes more precisely, preserving the locations
 3197                // of any anchors positioned in the unchanged regions.
 3198                if range.end.row > range.start.row {
 3199                    let offset = range.start.to_offset(&snapshot);
 3200                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3201                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3202                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3203                        (
 3204                            snapshot.anchor_after(offset + range.start)
 3205                                ..snapshot.anchor_before(offset + range.end),
 3206                            replacement,
 3207                        )
 3208                    }));
 3209                } else if range.end == range.start {
 3210                    let anchor = snapshot.anchor_after(range.start);
 3211                    edits.push((anchor..anchor, new_text.into()));
 3212                } else {
 3213                    let edit_start = snapshot.anchor_after(range.start);
 3214                    let edit_end = snapshot.anchor_before(range.end);
 3215                    edits.push((edit_start..edit_end, new_text.into()));
 3216                }
 3217            }
 3218
 3219            Ok(edits)
 3220        })
 3221    }
 3222
 3223    pub(crate) async fn deserialize_workspace_edit(
 3224        this: Entity<LspStore>,
 3225        edit: lsp::WorkspaceEdit,
 3226        push_to_history: bool,
 3227        language_server: Arc<LanguageServer>,
 3228        cx: &mut AsyncApp,
 3229    ) -> Result<ProjectTransaction> {
 3230        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3231
 3232        let mut operations = Vec::new();
 3233        if let Some(document_changes) = edit.document_changes {
 3234            match document_changes {
 3235                lsp::DocumentChanges::Edits(edits) => {
 3236                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3237                }
 3238                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3239            }
 3240        } else if let Some(changes) = edit.changes {
 3241            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3242                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3243                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3244                        uri,
 3245                        version: None,
 3246                    },
 3247                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3248                })
 3249            }));
 3250        }
 3251
 3252        let mut project_transaction = ProjectTransaction::default();
 3253        for operation in operations {
 3254            match operation {
 3255                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3256                    let abs_path = op
 3257                        .uri
 3258                        .to_file_path()
 3259                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3260
 3261                    if let Some(parent_path) = abs_path.parent() {
 3262                        fs.create_dir(parent_path).await?;
 3263                    }
 3264                    if abs_path.ends_with("/") {
 3265                        fs.create_dir(&abs_path).await?;
 3266                    } else {
 3267                        fs.create_file(
 3268                            &abs_path,
 3269                            op.options
 3270                                .map(|options| fs::CreateOptions {
 3271                                    overwrite: options.overwrite.unwrap_or(false),
 3272                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3273                                })
 3274                                .unwrap_or_default(),
 3275                        )
 3276                        .await?;
 3277                    }
 3278                }
 3279
 3280                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3281                    let source_abs_path = op
 3282                        .old_uri
 3283                        .to_file_path()
 3284                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3285                    let target_abs_path = op
 3286                        .new_uri
 3287                        .to_file_path()
 3288                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3289
 3290                    let options = fs::RenameOptions {
 3291                        overwrite: op
 3292                            .options
 3293                            .as_ref()
 3294                            .and_then(|options| options.overwrite)
 3295                            .unwrap_or(false),
 3296                        ignore_if_exists: op
 3297                            .options
 3298                            .as_ref()
 3299                            .and_then(|options| options.ignore_if_exists)
 3300                            .unwrap_or(false),
 3301                        create_parents: true,
 3302                    };
 3303
 3304                    fs.rename(&source_abs_path, &target_abs_path, options)
 3305                        .await?;
 3306                }
 3307
 3308                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3309                    let abs_path = op
 3310                        .uri
 3311                        .to_file_path()
 3312                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3313                    let options = op
 3314                        .options
 3315                        .map(|options| fs::RemoveOptions {
 3316                            recursive: options.recursive.unwrap_or(false),
 3317                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3318                        })
 3319                        .unwrap_or_default();
 3320                    if abs_path.ends_with("/") {
 3321                        fs.remove_dir(&abs_path, options).await?;
 3322                    } else {
 3323                        fs.remove_file(&abs_path, options).await?;
 3324                    }
 3325                }
 3326
 3327                lsp::DocumentChangeOperation::Edit(op) => {
 3328                    let buffer_to_edit = this
 3329                        .update(cx, |this, cx| {
 3330                            this.open_local_buffer_via_lsp(
 3331                                op.text_document.uri.clone(),
 3332                                language_server.server_id(),
 3333                                cx,
 3334                            )
 3335                        })
 3336                        .await?;
 3337
 3338                    let edits = this
 3339                        .update(cx, |this, cx| {
 3340                            let path = buffer_to_edit.read(cx).project_path(cx);
 3341                            let active_entry = this.active_entry;
 3342                            let is_active_entry = path.is_some_and(|project_path| {
 3343                                this.worktree_store
 3344                                    .read(cx)
 3345                                    .entry_for_path(&project_path, cx)
 3346                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3347                            });
 3348                            let local = this.as_local_mut().unwrap();
 3349
 3350                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3351                            for edit in op.edits {
 3352                                match edit {
 3353                                    Edit::Plain(edit) => {
 3354                                        if !edits.contains(&edit) {
 3355                                            edits.push(edit)
 3356                                        }
 3357                                    }
 3358                                    Edit::Annotated(edit) => {
 3359                                        if !edits.contains(&edit.text_edit) {
 3360                                            edits.push(edit.text_edit)
 3361                                        }
 3362                                    }
 3363                                    Edit::Snippet(edit) => {
 3364                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3365                                        else {
 3366                                            continue;
 3367                                        };
 3368
 3369                                        if is_active_entry {
 3370                                            snippet_edits.push((edit.range, snippet));
 3371                                        } else {
 3372                                            // Since this buffer is not focused, apply a normal edit.
 3373                                            let new_edit = TextEdit {
 3374                                                range: edit.range,
 3375                                                new_text: snippet.text,
 3376                                            };
 3377                                            if !edits.contains(&new_edit) {
 3378                                                edits.push(new_edit);
 3379                                            }
 3380                                        }
 3381                                    }
 3382                                }
 3383                            }
 3384                            if !snippet_edits.is_empty() {
 3385                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3386                                let version = if let Some(buffer_version) = op.text_document.version
 3387                                {
 3388                                    local
 3389                                        .buffer_snapshot_for_lsp_version(
 3390                                            &buffer_to_edit,
 3391                                            language_server.server_id(),
 3392                                            Some(buffer_version),
 3393                                            cx,
 3394                                        )
 3395                                        .ok()
 3396                                        .map(|snapshot| snapshot.version)
 3397                                } else {
 3398                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3399                                };
 3400
 3401                                let most_recent_edit =
 3402                                    version.and_then(|version| version.most_recent());
 3403                                // Check if the edit that triggered that edit has been made by this participant.
 3404
 3405                                if let Some(most_recent_edit) = most_recent_edit {
 3406                                    cx.emit(LspStoreEvent::SnippetEdit {
 3407                                        buffer_id,
 3408                                        edits: snippet_edits,
 3409                                        most_recent_edit,
 3410                                    });
 3411                                }
 3412                            }
 3413
 3414                            local.edits_from_lsp(
 3415                                &buffer_to_edit,
 3416                                edits,
 3417                                language_server.server_id(),
 3418                                op.text_document.version,
 3419                                cx,
 3420                            )
 3421                        })
 3422                        .await?;
 3423
 3424                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3425                        buffer.finalize_last_transaction();
 3426                        buffer.start_transaction();
 3427                        for (range, text) in edits {
 3428                            buffer.edit([(range, text)], None, cx);
 3429                        }
 3430
 3431                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3432                            if push_to_history {
 3433                                buffer.finalize_last_transaction();
 3434                                buffer.get_transaction(transaction_id).cloned()
 3435                            } else {
 3436                                buffer.forget_transaction(transaction_id)
 3437                            }
 3438                        })
 3439                    });
 3440                    if let Some(transaction) = transaction {
 3441                        project_transaction.0.insert(buffer_to_edit, transaction);
 3442                    }
 3443                }
 3444            }
 3445        }
 3446
 3447        Ok(project_transaction)
 3448    }
 3449
 3450    async fn on_lsp_workspace_edit(
 3451        this: WeakEntity<LspStore>,
 3452        params: lsp::ApplyWorkspaceEditParams,
 3453        server_id: LanguageServerId,
 3454        cx: &mut AsyncApp,
 3455    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3456        let this = this.upgrade().context("project project closed")?;
 3457        let language_server = this
 3458            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3459            .context("language server not found")?;
 3460        let transaction = Self::deserialize_workspace_edit(
 3461            this.clone(),
 3462            params.edit,
 3463            true,
 3464            language_server.clone(),
 3465            cx,
 3466        )
 3467        .await
 3468        .log_err();
 3469        this.update(cx, |this, cx| {
 3470            if let Some(transaction) = transaction {
 3471                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3472
 3473                this.as_local_mut()
 3474                    .unwrap()
 3475                    .last_workspace_edits_by_language_server
 3476                    .insert(server_id, transaction);
 3477            }
 3478        });
 3479        Ok(lsp::ApplyWorkspaceEditResponse {
 3480            applied: true,
 3481            failed_change: None,
 3482            failure_reason: None,
 3483        })
 3484    }
 3485
 3486    fn remove_worktree(
 3487        &mut self,
 3488        id_to_remove: WorktreeId,
 3489        cx: &mut Context<LspStore>,
 3490    ) -> Vec<LanguageServerId> {
 3491        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3492        self.diagnostics.remove(&id_to_remove);
 3493        self.prettier_store.update(cx, |prettier_store, cx| {
 3494            prettier_store.remove_worktree(id_to_remove, cx);
 3495        });
 3496
 3497        let mut servers_to_remove = BTreeSet::default();
 3498        let mut servers_to_preserve = HashSet::default();
 3499        for (seed, state) in &self.language_server_ids {
 3500            if seed.worktree_id == id_to_remove {
 3501                servers_to_remove.insert(state.id);
 3502            } else {
 3503                servers_to_preserve.insert(state.id);
 3504            }
 3505        }
 3506        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3507        self.language_server_ids
 3508            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3509        for server_id_to_remove in &servers_to_remove {
 3510            self.language_server_watched_paths
 3511                .remove(server_id_to_remove);
 3512            self.language_server_paths_watched_for_rename
 3513                .remove(server_id_to_remove);
 3514            self.last_workspace_edits_by_language_server
 3515                .remove(server_id_to_remove);
 3516            self.language_servers.remove(server_id_to_remove);
 3517            self.buffer_pull_diagnostics_result_ids
 3518                .remove(server_id_to_remove);
 3519            self.workspace_pull_diagnostics_result_ids
 3520                .remove(server_id_to_remove);
 3521            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3522                buffer_servers.remove(server_id_to_remove);
 3523            }
 3524            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3525        }
 3526        servers_to_remove.into_iter().collect()
 3527    }
 3528
 3529    fn rebuild_watched_paths_inner<'a>(
 3530        &'a self,
 3531        language_server_id: LanguageServerId,
 3532        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3533        cx: &mut Context<LspStore>,
 3534    ) -> LanguageServerWatchedPathsBuilder {
 3535        let worktrees = self
 3536            .worktree_store
 3537            .read(cx)
 3538            .worktrees()
 3539            .filter_map(|worktree| {
 3540                self.language_servers_for_worktree(worktree.read(cx).id())
 3541                    .find(|server| server.server_id() == language_server_id)
 3542                    .map(|_| worktree)
 3543            })
 3544            .collect::<Vec<_>>();
 3545
 3546        let mut worktree_globs = HashMap::default();
 3547        let mut abs_globs = HashMap::default();
 3548        log::trace!(
 3549            "Processing new watcher paths for language server with id {}",
 3550            language_server_id
 3551        );
 3552
 3553        for watcher in watchers {
 3554            if let Some((worktree, literal_prefix, pattern)) =
 3555                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3556            {
 3557                worktree.update(cx, |worktree, _| {
 3558                    if let Some((tree, glob)) =
 3559                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3560                    {
 3561                        tree.add_path_prefix_to_scan(literal_prefix);
 3562                        worktree_globs
 3563                            .entry(tree.id())
 3564                            .or_insert_with(GlobSetBuilder::new)
 3565                            .add(glob);
 3566                    }
 3567                });
 3568            } else {
 3569                let (path, pattern) = match &watcher.glob_pattern {
 3570                    lsp::GlobPattern::String(s) => {
 3571                        let watcher_path = SanitizedPath::new(s);
 3572                        let path = glob_literal_prefix(watcher_path.as_path());
 3573                        let pattern = watcher_path
 3574                            .as_path()
 3575                            .strip_prefix(&path)
 3576                            .map(|p| p.to_string_lossy().into_owned())
 3577                            .unwrap_or_else(|e| {
 3578                                debug_panic!(
 3579                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3580                                    s,
 3581                                    path.display(),
 3582                                    e
 3583                                );
 3584                                watcher_path.as_path().to_string_lossy().into_owned()
 3585                            });
 3586                        (path, pattern)
 3587                    }
 3588                    lsp::GlobPattern::Relative(rp) => {
 3589                        let Ok(mut base_uri) = match &rp.base_uri {
 3590                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3591                            lsp::OneOf::Right(base_uri) => base_uri,
 3592                        }
 3593                        .to_file_path() else {
 3594                            continue;
 3595                        };
 3596
 3597                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3598                        let pattern = Path::new(&rp.pattern)
 3599                            .strip_prefix(&path)
 3600                            .map(|p| p.to_string_lossy().into_owned())
 3601                            .unwrap_or_else(|e| {
 3602                                debug_panic!(
 3603                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3604                                    rp.pattern,
 3605                                    path.display(),
 3606                                    e
 3607                                );
 3608                                rp.pattern.clone()
 3609                            });
 3610                        base_uri.push(path);
 3611                        (base_uri, pattern)
 3612                    }
 3613                };
 3614
 3615                if let Some(glob) = Glob::new(&pattern).log_err() {
 3616                    if !path
 3617                        .components()
 3618                        .any(|c| matches!(c, path::Component::Normal(_)))
 3619                    {
 3620                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3621                        // rather than adding a new watcher for `/`.
 3622                        for worktree in &worktrees {
 3623                            worktree_globs
 3624                                .entry(worktree.read(cx).id())
 3625                                .or_insert_with(GlobSetBuilder::new)
 3626                                .add(glob.clone());
 3627                        }
 3628                    } else {
 3629                        abs_globs
 3630                            .entry(path.into())
 3631                            .or_insert_with(GlobSetBuilder::new)
 3632                            .add(glob);
 3633                    }
 3634                }
 3635            }
 3636        }
 3637
 3638        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3639        for (worktree_id, builder) in worktree_globs {
 3640            if let Ok(globset) = builder.build() {
 3641                watch_builder.watch_worktree(worktree_id, globset);
 3642            }
 3643        }
 3644        for (abs_path, builder) in abs_globs {
 3645            if let Ok(globset) = builder.build() {
 3646                watch_builder.watch_abs_path(abs_path, globset);
 3647            }
 3648        }
 3649        watch_builder
 3650    }
 3651
 3652    fn worktree_and_path_for_file_watcher(
 3653        worktrees: &[Entity<Worktree>],
 3654        watcher: &FileSystemWatcher,
 3655        cx: &App,
 3656    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3657        worktrees.iter().find_map(|worktree| {
 3658            let tree = worktree.read(cx);
 3659            let worktree_root_path = tree.abs_path();
 3660            let path_style = tree.path_style();
 3661            match &watcher.glob_pattern {
 3662                lsp::GlobPattern::String(s) => {
 3663                    let watcher_path = SanitizedPath::new(s);
 3664                    let relative = watcher_path
 3665                        .as_path()
 3666                        .strip_prefix(&worktree_root_path)
 3667                        .ok()?;
 3668                    let literal_prefix = glob_literal_prefix(relative);
 3669                    Some((
 3670                        worktree.clone(),
 3671                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3672                        relative.to_string_lossy().into_owned(),
 3673                    ))
 3674                }
 3675                lsp::GlobPattern::Relative(rp) => {
 3676                    let base_uri = match &rp.base_uri {
 3677                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3678                        lsp::OneOf::Right(base_uri) => base_uri,
 3679                    }
 3680                    .to_file_path()
 3681                    .ok()?;
 3682                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3683                    let mut literal_prefix = relative.to_owned();
 3684                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3685                    Some((
 3686                        worktree.clone(),
 3687                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3688                        rp.pattern.clone(),
 3689                    ))
 3690                }
 3691            }
 3692        })
 3693    }
 3694
 3695    fn rebuild_watched_paths(
 3696        &mut self,
 3697        language_server_id: LanguageServerId,
 3698        cx: &mut Context<LspStore>,
 3699    ) {
 3700        let Some(registrations) = self
 3701            .language_server_dynamic_registrations
 3702            .get(&language_server_id)
 3703        else {
 3704            return;
 3705        };
 3706
 3707        let watch_builder = self.rebuild_watched_paths_inner(
 3708            language_server_id,
 3709            registrations.did_change_watched_files.values().flatten(),
 3710            cx,
 3711        );
 3712        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3713        self.language_server_watched_paths
 3714            .insert(language_server_id, watcher);
 3715
 3716        cx.notify();
 3717    }
 3718
 3719    fn on_lsp_did_change_watched_files(
 3720        &mut self,
 3721        language_server_id: LanguageServerId,
 3722        registration_id: &str,
 3723        params: DidChangeWatchedFilesRegistrationOptions,
 3724        cx: &mut Context<LspStore>,
 3725    ) {
 3726        let registrations = self
 3727            .language_server_dynamic_registrations
 3728            .entry(language_server_id)
 3729            .or_default();
 3730
 3731        registrations
 3732            .did_change_watched_files
 3733            .insert(registration_id.to_string(), params.watchers);
 3734
 3735        self.rebuild_watched_paths(language_server_id, cx);
 3736    }
 3737
 3738    fn on_lsp_unregister_did_change_watched_files(
 3739        &mut self,
 3740        language_server_id: LanguageServerId,
 3741        registration_id: &str,
 3742        cx: &mut Context<LspStore>,
 3743    ) {
 3744        let registrations = self
 3745            .language_server_dynamic_registrations
 3746            .entry(language_server_id)
 3747            .or_default();
 3748
 3749        if registrations
 3750            .did_change_watched_files
 3751            .remove(registration_id)
 3752            .is_some()
 3753        {
 3754            log::info!(
 3755                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3756                language_server_id,
 3757                registration_id
 3758            );
 3759        } else {
 3760            log::warn!(
 3761                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3762                language_server_id,
 3763                registration_id
 3764            );
 3765        }
 3766
 3767        self.rebuild_watched_paths(language_server_id, cx);
 3768    }
 3769
 3770    async fn initialization_options_for_adapter(
 3771        adapter: Arc<dyn LspAdapter>,
 3772        delegate: &Arc<dyn LspAdapterDelegate>,
 3773    ) -> Result<Option<serde_json::Value>> {
 3774        let Some(mut initialization_config) =
 3775            adapter.clone().initialization_options(delegate).await?
 3776        else {
 3777            return Ok(None);
 3778        };
 3779
 3780        for other_adapter in delegate.registered_lsp_adapters() {
 3781            if other_adapter.name() == adapter.name() {
 3782                continue;
 3783            }
 3784            if let Ok(Some(target_config)) = other_adapter
 3785                .clone()
 3786                .additional_initialization_options(adapter.name(), delegate)
 3787                .await
 3788            {
 3789                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3790            }
 3791        }
 3792
 3793        Ok(Some(initialization_config))
 3794    }
 3795
 3796    async fn workspace_configuration_for_adapter(
 3797        adapter: Arc<dyn LspAdapter>,
 3798        delegate: &Arc<dyn LspAdapterDelegate>,
 3799        toolchain: Option<Toolchain>,
 3800        requested_uri: Option<Uri>,
 3801        cx: &mut AsyncApp,
 3802    ) -> Result<serde_json::Value> {
 3803        let mut workspace_config = adapter
 3804            .clone()
 3805            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3806            .await?;
 3807
 3808        for other_adapter in delegate.registered_lsp_adapters() {
 3809            if other_adapter.name() == adapter.name() {
 3810                continue;
 3811            }
 3812            if let Ok(Some(target_config)) = other_adapter
 3813                .clone()
 3814                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3815                .await
 3816            {
 3817                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3818            }
 3819        }
 3820
 3821        Ok(workspace_config)
 3822    }
 3823
 3824    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3825        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3826            Some(server.clone())
 3827        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3828            Some(Arc::clone(server))
 3829        } else {
 3830            None
 3831        }
 3832    }
 3833}
 3834
 3835fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3836    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3837        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3838            language_server_id: server.server_id(),
 3839            name: Some(server.name()),
 3840            message: proto::update_language_server::Variant::MetadataUpdated(
 3841                proto::ServerMetadataUpdated {
 3842                    capabilities: Some(capabilities),
 3843                    binary: Some(proto::LanguageServerBinaryInfo {
 3844                        path: server.binary().path.to_string_lossy().into_owned(),
 3845                        arguments: server
 3846                            .binary()
 3847                            .arguments
 3848                            .iter()
 3849                            .map(|arg| arg.to_string_lossy().into_owned())
 3850                            .collect(),
 3851                    }),
 3852                    configuration: serde_json::to_string(server.configuration()).ok(),
 3853                    workspace_folders: server
 3854                        .workspace_folders()
 3855                        .iter()
 3856                        .map(|uri| uri.to_string())
 3857                        .collect(),
 3858                },
 3859            ),
 3860        });
 3861    }
 3862}
 3863
 3864#[derive(Debug)]
 3865pub struct FormattableBuffer {
 3866    handle: Entity<Buffer>,
 3867    abs_path: Option<PathBuf>,
 3868    env: Option<HashMap<String, String>>,
 3869    ranges: Option<Vec<Range<Anchor>>>,
 3870}
 3871
 3872pub struct RemoteLspStore {
 3873    upstream_client: Option<AnyProtoClient>,
 3874    upstream_project_id: u64,
 3875}
 3876
 3877pub(crate) enum LspStoreMode {
 3878    Local(LocalLspStore),   // ssh host and collab host
 3879    Remote(RemoteLspStore), // collab guest
 3880}
 3881
 3882impl LspStoreMode {
 3883    fn is_local(&self) -> bool {
 3884        matches!(self, LspStoreMode::Local(_))
 3885    }
 3886}
 3887
 3888pub struct LspStore {
 3889    mode: LspStoreMode,
 3890    last_formatting_failure: Option<String>,
 3891    downstream_client: Option<(AnyProtoClient, u64)>,
 3892    nonce: u128,
 3893    buffer_store: Entity<BufferStore>,
 3894    worktree_store: Entity<WorktreeStore>,
 3895    pub languages: Arc<LanguageRegistry>,
 3896    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3897    active_entry: Option<ProjectEntryId>,
 3898    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3899    _maintain_buffer_languages: Task<()>,
 3900    diagnostic_summaries:
 3901        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3902    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3903    semantic_token_config: SemanticTokenConfig,
 3904    lsp_data: HashMap<BufferId, BufferLspData>,
 3905    next_hint_id: Arc<AtomicUsize>,
 3906}
 3907
 3908#[derive(Debug)]
 3909pub struct BufferLspData {
 3910    buffer_version: Global,
 3911    document_colors: Option<DocumentColorData>,
 3912    code_lens: Option<CodeLensData>,
 3913    semantic_tokens: Option<SemanticTokensData>,
 3914    folding_ranges: Option<FoldingRangeData>,
 3915    document_symbols: Option<DocumentSymbolsData>,
 3916    inlay_hints: BufferInlayHints,
 3917    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3918    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3919}
 3920
 3921#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3922struct LspKey {
 3923    request_type: TypeId,
 3924    server_queried: Option<LanguageServerId>,
 3925}
 3926
 3927impl BufferLspData {
 3928    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3929        Self {
 3930            buffer_version: buffer.read(cx).version(),
 3931            document_colors: None,
 3932            code_lens: None,
 3933            semantic_tokens: None,
 3934            folding_ranges: None,
 3935            document_symbols: None,
 3936            inlay_hints: BufferInlayHints::new(buffer, cx),
 3937            lsp_requests: HashMap::default(),
 3938            chunk_lsp_requests: HashMap::default(),
 3939        }
 3940    }
 3941
 3942    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3943        if let Some(document_colors) = &mut self.document_colors {
 3944            document_colors.remove_server_data(for_server);
 3945        }
 3946
 3947        if let Some(code_lens) = &mut self.code_lens {
 3948            code_lens.remove_server_data(for_server);
 3949        }
 3950
 3951        self.inlay_hints.remove_server_data(for_server);
 3952
 3953        if let Some(semantic_tokens) = &mut self.semantic_tokens {
 3954            semantic_tokens.raw_tokens.servers.remove(&for_server);
 3955            semantic_tokens
 3956                .latest_invalidation_requests
 3957                .remove(&for_server);
 3958        }
 3959
 3960        if let Some(folding_ranges) = &mut self.folding_ranges {
 3961            folding_ranges.ranges.remove(&for_server);
 3962        }
 3963
 3964        if let Some(document_symbols) = &mut self.document_symbols {
 3965            document_symbols.remove_server_data(for_server);
 3966        }
 3967    }
 3968
 3969    #[cfg(any(test, feature = "test-support"))]
 3970    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3971        &self.inlay_hints
 3972    }
 3973}
 3974
 3975#[derive(Debug)]
 3976pub enum LspStoreEvent {
 3977    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3978    LanguageServerRemoved(LanguageServerId),
 3979    LanguageServerUpdate {
 3980        language_server_id: LanguageServerId,
 3981        name: Option<LanguageServerName>,
 3982        message: proto::update_language_server::Variant,
 3983    },
 3984    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3985    LanguageServerPrompt(LanguageServerPromptRequest),
 3986    LanguageDetected {
 3987        buffer: Entity<Buffer>,
 3988        new_language: Option<Arc<Language>>,
 3989    },
 3990    Notification(String),
 3991    RefreshInlayHints {
 3992        server_id: LanguageServerId,
 3993        request_id: Option<usize>,
 3994    },
 3995    RefreshSemanticTokens {
 3996        server_id: LanguageServerId,
 3997        request_id: Option<usize>,
 3998    },
 3999    RefreshCodeLens,
 4000    DiagnosticsUpdated {
 4001        server_id: LanguageServerId,
 4002        paths: Vec<ProjectPath>,
 4003    },
 4004    DiskBasedDiagnosticsStarted {
 4005        language_server_id: LanguageServerId,
 4006    },
 4007    DiskBasedDiagnosticsFinished {
 4008        language_server_id: LanguageServerId,
 4009    },
 4010    SnippetEdit {
 4011        buffer_id: BufferId,
 4012        edits: Vec<(lsp::Range, Snippet)>,
 4013        most_recent_edit: clock::Lamport,
 4014    },
 4015    WorkspaceEditApplied(ProjectTransaction),
 4016}
 4017
 4018#[derive(Clone, Debug, Serialize)]
 4019pub struct LanguageServerStatus {
 4020    pub name: LanguageServerName,
 4021    pub server_version: Option<SharedString>,
 4022    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 4023    pub has_pending_diagnostic_updates: bool,
 4024    pub progress_tokens: HashSet<ProgressToken>,
 4025    pub worktree: Option<WorktreeId>,
 4026    pub binary: Option<LanguageServerBinary>,
 4027    pub configuration: Option<Value>,
 4028    pub workspace_folders: BTreeSet<Uri>,
 4029    pub process_id: Option<u32>,
 4030}
 4031
 4032#[derive(Clone, Debug)]
 4033struct CoreSymbol {
 4034    pub language_server_name: LanguageServerName,
 4035    pub source_worktree_id: WorktreeId,
 4036    pub source_language_server_id: LanguageServerId,
 4037    pub path: SymbolLocation,
 4038    pub name: String,
 4039    pub kind: lsp::SymbolKind,
 4040    pub range: Range<Unclipped<PointUtf16>>,
 4041    pub container_name: Option<String>,
 4042}
 4043
 4044#[derive(Clone, Debug, PartialEq, Eq)]
 4045pub enum SymbolLocation {
 4046    InProject(ProjectPath),
 4047    OutsideProject {
 4048        abs_path: Arc<Path>,
 4049        signature: [u8; 32],
 4050    },
 4051}
 4052
 4053impl SymbolLocation {
 4054    fn file_name(&self) -> Option<&str> {
 4055        match self {
 4056            Self::InProject(path) => path.path.file_name(),
 4057            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 4058        }
 4059    }
 4060}
 4061
 4062impl LspStore {
 4063    pub fn init(client: &AnyProtoClient) {
 4064        client.add_entity_request_handler(Self::handle_lsp_query);
 4065        client.add_entity_message_handler(Self::handle_lsp_query_response);
 4066        client.add_entity_request_handler(Self::handle_restart_language_servers);
 4067        client.add_entity_request_handler(Self::handle_stop_language_servers);
 4068        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 4069        client.add_entity_message_handler(Self::handle_start_language_server);
 4070        client.add_entity_message_handler(Self::handle_update_language_server);
 4071        client.add_entity_message_handler(Self::handle_language_server_log);
 4072        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 4073        client.add_entity_request_handler(Self::handle_format_buffers);
 4074        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 4075        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 4076        client.add_entity_request_handler(Self::handle_apply_code_action);
 4077        client.add_entity_request_handler(Self::handle_get_project_symbols);
 4078        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 4079        client.add_entity_request_handler(Self::handle_get_color_presentation);
 4080        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 4081        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 4082        client.add_entity_request_handler(Self::handle_refresh_semantic_tokens);
 4083        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 4084        client.add_entity_request_handler(Self::handle_on_type_formatting);
 4085        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 4086        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 4087        client.add_entity_request_handler(Self::handle_rename_project_entry);
 4088        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 4089        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 4090        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 4091        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 4092        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 4093        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 4094        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 4095
 4096        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 4097        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 4098        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 4099        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 4100        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 4101        client.add_entity_request_handler(
 4102            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 4103        );
 4104        client.add_entity_request_handler(
 4105            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 4106        );
 4107        client.add_entity_request_handler(
 4108            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 4109        );
 4110    }
 4111
 4112    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 4113        match &self.mode {
 4114            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 4115            _ => None,
 4116        }
 4117    }
 4118
 4119    pub fn as_local(&self) -> Option<&LocalLspStore> {
 4120        match &self.mode {
 4121            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4122            _ => None,
 4123        }
 4124    }
 4125
 4126    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 4127        match &mut self.mode {
 4128            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4129            _ => None,
 4130        }
 4131    }
 4132
 4133    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4134        match &self.mode {
 4135            LspStoreMode::Remote(RemoteLspStore {
 4136                upstream_client: Some(upstream_client),
 4137                upstream_project_id,
 4138                ..
 4139            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4140
 4141            LspStoreMode::Remote(RemoteLspStore {
 4142                upstream_client: None,
 4143                ..
 4144            }) => None,
 4145            LspStoreMode::Local(_) => None,
 4146        }
 4147    }
 4148
 4149    pub fn new_local(
 4150        buffer_store: Entity<BufferStore>,
 4151        worktree_store: Entity<WorktreeStore>,
 4152        prettier_store: Entity<PrettierStore>,
 4153        toolchain_store: Entity<LocalToolchainStore>,
 4154        environment: Entity<ProjectEnvironment>,
 4155        manifest_tree: Entity<ManifestTree>,
 4156        languages: Arc<LanguageRegistry>,
 4157        http_client: Arc<dyn HttpClient>,
 4158        fs: Arc<dyn Fs>,
 4159        cx: &mut Context<Self>,
 4160    ) -> Self {
 4161        let yarn = YarnPathStore::new(fs.clone(), cx);
 4162        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4163            .detach();
 4164        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4165            .detach();
 4166        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4167            .detach();
 4168        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4169            .detach();
 4170        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4171            .detach();
 4172        subscribe_to_binary_statuses(&languages, cx).detach();
 4173
 4174        let _maintain_workspace_config = {
 4175            let (sender, receiver) = watch::channel();
 4176            (Self::maintain_workspace_config(receiver, cx), sender)
 4177        };
 4178
 4179        Self {
 4180            mode: LspStoreMode::Local(LocalLspStore {
 4181                weak: cx.weak_entity(),
 4182                worktree_store: worktree_store.clone(),
 4183
 4184                supplementary_language_servers: Default::default(),
 4185                languages: languages.clone(),
 4186                language_server_ids: Default::default(),
 4187                language_servers: Default::default(),
 4188                last_workspace_edits_by_language_server: Default::default(),
 4189                language_server_watched_paths: Default::default(),
 4190                language_server_paths_watched_for_rename: Default::default(),
 4191                language_server_dynamic_registrations: Default::default(),
 4192                buffers_being_formatted: Default::default(),
 4193                buffers_to_refresh_hash_set: HashSet::default(),
 4194                buffers_to_refresh_queue: VecDeque::new(),
 4195                _background_diagnostics_worker: Task::ready(()).shared(),
 4196                buffer_snapshots: Default::default(),
 4197                prettier_store,
 4198                environment,
 4199                http_client,
 4200                fs,
 4201                yarn,
 4202                next_diagnostic_group_id: Default::default(),
 4203                diagnostics: Default::default(),
 4204                _subscription: cx.on_app_quit(|this, _| {
 4205                    this.as_local_mut()
 4206                        .unwrap()
 4207                        .shutdown_language_servers_on_quit()
 4208                }),
 4209                lsp_tree: LanguageServerTree::new(
 4210                    manifest_tree,
 4211                    languages.clone(),
 4212                    toolchain_store.clone(),
 4213                ),
 4214                toolchain_store,
 4215                registered_buffers: HashMap::default(),
 4216                buffers_opened_in_servers: HashMap::default(),
 4217                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4218                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4219                restricted_worktrees_tasks: HashMap::default(),
 4220                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4221                    .manifest_file_names(),
 4222            }),
 4223            last_formatting_failure: None,
 4224            downstream_client: None,
 4225            buffer_store,
 4226            worktree_store,
 4227            languages: languages.clone(),
 4228            language_server_statuses: Default::default(),
 4229            nonce: StdRng::from_os_rng().random(),
 4230            diagnostic_summaries: HashMap::default(),
 4231            lsp_server_capabilities: HashMap::default(),
 4232            semantic_token_config: SemanticTokenConfig::new(cx),
 4233            lsp_data: HashMap::default(),
 4234            next_hint_id: Arc::default(),
 4235            active_entry: None,
 4236            _maintain_workspace_config,
 4237            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4238        }
 4239    }
 4240
 4241    fn send_lsp_proto_request<R: LspCommand>(
 4242        &self,
 4243        buffer: Entity<Buffer>,
 4244        client: AnyProtoClient,
 4245        upstream_project_id: u64,
 4246        request: R,
 4247        cx: &mut Context<LspStore>,
 4248    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4249        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4250            return Task::ready(Ok(R::Response::default()));
 4251        }
 4252        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4253        cx.spawn(async move |this, cx| {
 4254            let response = client.request(message).await?;
 4255            let this = this.upgrade().context("project dropped")?;
 4256            request
 4257                .response_from_proto(response, this, buffer, cx.clone())
 4258                .await
 4259        })
 4260    }
 4261
 4262    pub(super) fn new_remote(
 4263        buffer_store: Entity<BufferStore>,
 4264        worktree_store: Entity<WorktreeStore>,
 4265        languages: Arc<LanguageRegistry>,
 4266        upstream_client: AnyProtoClient,
 4267        project_id: u64,
 4268        cx: &mut Context<Self>,
 4269    ) -> Self {
 4270        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4271            .detach();
 4272        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4273            .detach();
 4274        subscribe_to_binary_statuses(&languages, cx).detach();
 4275        let _maintain_workspace_config = {
 4276            let (sender, receiver) = watch::channel();
 4277            (Self::maintain_workspace_config(receiver, cx), sender)
 4278        };
 4279        Self {
 4280            mode: LspStoreMode::Remote(RemoteLspStore {
 4281                upstream_client: Some(upstream_client),
 4282                upstream_project_id: project_id,
 4283            }),
 4284            downstream_client: None,
 4285            last_formatting_failure: None,
 4286            buffer_store,
 4287            worktree_store,
 4288            languages: languages.clone(),
 4289            language_server_statuses: Default::default(),
 4290            nonce: StdRng::from_os_rng().random(),
 4291            diagnostic_summaries: HashMap::default(),
 4292            lsp_server_capabilities: HashMap::default(),
 4293            semantic_token_config: SemanticTokenConfig::new(cx),
 4294            next_hint_id: Arc::default(),
 4295            lsp_data: HashMap::default(),
 4296            active_entry: None,
 4297
 4298            _maintain_workspace_config,
 4299            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4300        }
 4301    }
 4302
 4303    fn on_buffer_store_event(
 4304        &mut self,
 4305        _: Entity<BufferStore>,
 4306        event: &BufferStoreEvent,
 4307        cx: &mut Context<Self>,
 4308    ) {
 4309        match event {
 4310            BufferStoreEvent::BufferAdded(buffer) => {
 4311                self.on_buffer_added(buffer, cx).log_err();
 4312            }
 4313            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4314                let buffer_id = buffer.read(cx).remote_id();
 4315                if let Some(local) = self.as_local_mut()
 4316                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4317                {
 4318                    local.reset_buffer(buffer, old_file, cx);
 4319
 4320                    if local.registered_buffers.contains_key(&buffer_id) {
 4321                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4322                    }
 4323                }
 4324
 4325                self.detect_language_for_buffer(buffer, cx);
 4326                if let Some(local) = self.as_local_mut() {
 4327                    local.initialize_buffer(buffer, cx);
 4328                    if local.registered_buffers.contains_key(&buffer_id) {
 4329                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4330                    }
 4331                }
 4332            }
 4333            _ => {}
 4334        }
 4335    }
 4336
 4337    fn on_worktree_store_event(
 4338        &mut self,
 4339        _: Entity<WorktreeStore>,
 4340        event: &WorktreeStoreEvent,
 4341        cx: &mut Context<Self>,
 4342    ) {
 4343        match event {
 4344            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4345                if !worktree.read(cx).is_local() {
 4346                    return;
 4347                }
 4348                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4349                    worktree::Event::UpdatedEntries(changes) => {
 4350                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4351                    }
 4352                    worktree::Event::UpdatedGitRepositories(_)
 4353                    | worktree::Event::DeletedEntry(_) => {}
 4354                })
 4355                .detach()
 4356            }
 4357            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4358            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4359                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4360            }
 4361            WorktreeStoreEvent::WorktreeReleased(..)
 4362            | WorktreeStoreEvent::WorktreeOrderChanged
 4363            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4364            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4365            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4366        }
 4367    }
 4368
 4369    fn on_prettier_store_event(
 4370        &mut self,
 4371        _: Entity<PrettierStore>,
 4372        event: &PrettierStoreEvent,
 4373        cx: &mut Context<Self>,
 4374    ) {
 4375        match event {
 4376            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4377                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4378            }
 4379            PrettierStoreEvent::LanguageServerAdded {
 4380                new_server_id,
 4381                name,
 4382                prettier_server,
 4383            } => {
 4384                self.register_supplementary_language_server(
 4385                    *new_server_id,
 4386                    name.clone(),
 4387                    prettier_server.clone(),
 4388                    cx,
 4389                );
 4390            }
 4391        }
 4392    }
 4393
 4394    fn on_toolchain_store_event(
 4395        &mut self,
 4396        _: Entity<LocalToolchainStore>,
 4397        event: &ToolchainStoreEvent,
 4398        _: &mut Context<Self>,
 4399    ) {
 4400        if let ToolchainStoreEvent::ToolchainActivated = event {
 4401            self.request_workspace_config_refresh()
 4402        }
 4403    }
 4404
 4405    fn request_workspace_config_refresh(&mut self) {
 4406        *self._maintain_workspace_config.1.borrow_mut() = ();
 4407    }
 4408
 4409    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4410        self.as_local().map(|local| local.prettier_store.clone())
 4411    }
 4412
 4413    fn on_buffer_event(
 4414        &mut self,
 4415        buffer: Entity<Buffer>,
 4416        event: &language::BufferEvent,
 4417        cx: &mut Context<Self>,
 4418    ) {
 4419        match event {
 4420            language::BufferEvent::Edited => {
 4421                self.on_buffer_edited(buffer, cx);
 4422            }
 4423
 4424            language::BufferEvent::Saved => {
 4425                self.on_buffer_saved(buffer, cx);
 4426            }
 4427
 4428            _ => {}
 4429        }
 4430    }
 4431
 4432    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4433        buffer
 4434            .read(cx)
 4435            .set_language_registry(self.languages.clone());
 4436
 4437        cx.subscribe(buffer, |this, buffer, event, cx| {
 4438            this.on_buffer_event(buffer, event, cx);
 4439        })
 4440        .detach();
 4441
 4442        self.detect_language_for_buffer(buffer, cx);
 4443        if let Some(local) = self.as_local_mut() {
 4444            local.initialize_buffer(buffer, cx);
 4445        }
 4446
 4447        Ok(())
 4448    }
 4449
 4450    pub fn refresh_background_diagnostics_for_buffers(
 4451        &mut self,
 4452        buffers: HashSet<BufferId>,
 4453        cx: &mut Context<Self>,
 4454    ) -> Shared<Task<()>> {
 4455        let Some(local) = self.as_local_mut() else {
 4456            return Task::ready(()).shared();
 4457        };
 4458        for buffer in buffers {
 4459            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4460                local.buffers_to_refresh_queue.push_back(buffer);
 4461                if local.buffers_to_refresh_queue.len() == 1 {
 4462                    local._background_diagnostics_worker =
 4463                        Self::background_diagnostics_worker(cx).shared();
 4464                }
 4465            }
 4466        }
 4467
 4468        local._background_diagnostics_worker.clone()
 4469    }
 4470
 4471    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4472        let buffer_store = self.buffer_store.clone();
 4473        let local = self.as_local_mut()?;
 4474        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4475            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4476            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4477                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4478            }
 4479        }
 4480        None
 4481    }
 4482
 4483    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4484        cx.spawn(async move |this, cx| {
 4485            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4486                task.await.log_err();
 4487            }
 4488        })
 4489    }
 4490
 4491    pub(crate) fn register_buffer_with_language_servers(
 4492        &mut self,
 4493        buffer: &Entity<Buffer>,
 4494        only_register_servers: HashSet<LanguageServerSelector>,
 4495        ignore_refcounts: bool,
 4496        cx: &mut Context<Self>,
 4497    ) -> OpenLspBufferHandle {
 4498        let buffer_id = buffer.read(cx).remote_id();
 4499        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4500        if let Some(local) = self.as_local_mut() {
 4501            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4502            if !ignore_refcounts {
 4503                *refcount += 1;
 4504            }
 4505
 4506            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4507            // 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
 4508            // 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
 4509            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4510            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4511                return handle;
 4512            };
 4513            if !file.is_local() {
 4514                return handle;
 4515            }
 4516
 4517            if ignore_refcounts || *refcount == 1 {
 4518                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4519            }
 4520            if !ignore_refcounts {
 4521                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4522                    let refcount = {
 4523                        let local = lsp_store.as_local_mut().unwrap();
 4524                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4525                            debug_panic!("bad refcounting");
 4526                            return;
 4527                        };
 4528
 4529                        *refcount -= 1;
 4530                        *refcount
 4531                    };
 4532                    if refcount == 0 {
 4533                        lsp_store.lsp_data.remove(&buffer_id);
 4534                        let local = lsp_store.as_local_mut().unwrap();
 4535                        local.registered_buffers.remove(&buffer_id);
 4536
 4537                        local.buffers_opened_in_servers.remove(&buffer_id);
 4538                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4539                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4540
 4541                            let buffer_abs_path = file.abs_path(cx);
 4542                            for (_, buffer_pull_diagnostics_result_ids) in
 4543                                &mut local.buffer_pull_diagnostics_result_ids
 4544                            {
 4545                                buffer_pull_diagnostics_result_ids.retain(
 4546                                    |_, buffer_result_ids| {
 4547                                        buffer_result_ids.remove(&buffer_abs_path);
 4548                                        !buffer_result_ids.is_empty()
 4549                                    },
 4550                                );
 4551                            }
 4552
 4553                            let diagnostic_updates = local
 4554                                .language_servers
 4555                                .keys()
 4556                                .cloned()
 4557                                .map(|server_id| DocumentDiagnosticsUpdate {
 4558                                    diagnostics: DocumentDiagnostics {
 4559                                        document_abs_path: buffer_abs_path.clone(),
 4560                                        version: None,
 4561                                        diagnostics: Vec::new(),
 4562                                    },
 4563                                    result_id: None,
 4564                                    registration_id: None,
 4565                                    server_id,
 4566                                    disk_based_sources: Cow::Borrowed(&[]),
 4567                                })
 4568                                .collect::<Vec<_>>();
 4569
 4570                            lsp_store
 4571                                .merge_diagnostic_entries(
 4572                                    diagnostic_updates,
 4573                                    |_, diagnostic, _| {
 4574                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4575                                    },
 4576                                    cx,
 4577                                )
 4578                                .context("Clearing diagnostics for the closed buffer")
 4579                                .log_err();
 4580                        }
 4581                    }
 4582                })
 4583                .detach();
 4584            }
 4585        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4586            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4587            cx.background_spawn(async move {
 4588                upstream_client
 4589                    .request(proto::RegisterBufferWithLanguageServers {
 4590                        project_id: upstream_project_id,
 4591                        buffer_id,
 4592                        only_servers: only_register_servers
 4593                            .into_iter()
 4594                            .map(|selector| {
 4595                                let selector = match selector {
 4596                                    LanguageServerSelector::Id(language_server_id) => {
 4597                                        proto::language_server_selector::Selector::ServerId(
 4598                                            language_server_id.to_proto(),
 4599                                        )
 4600                                    }
 4601                                    LanguageServerSelector::Name(language_server_name) => {
 4602                                        proto::language_server_selector::Selector::Name(
 4603                                            language_server_name.to_string(),
 4604                                        )
 4605                                    }
 4606                                };
 4607                                proto::LanguageServerSelector {
 4608                                    selector: Some(selector),
 4609                                }
 4610                            })
 4611                            .collect(),
 4612                    })
 4613                    .await
 4614            })
 4615            .detach();
 4616        } else {
 4617            // Our remote connection got closed
 4618        }
 4619        handle
 4620    }
 4621
 4622    fn maintain_buffer_languages(
 4623        languages: Arc<LanguageRegistry>,
 4624        cx: &mut Context<Self>,
 4625    ) -> Task<()> {
 4626        let mut subscription = languages.subscribe();
 4627        let mut prev_reload_count = languages.reload_count();
 4628        cx.spawn(async move |this, cx| {
 4629            while let Some(()) = subscription.next().await {
 4630                if let Some(this) = this.upgrade() {
 4631                    // If the language registry has been reloaded, then remove and
 4632                    // re-assign the languages on all open buffers.
 4633                    let reload_count = languages.reload_count();
 4634                    if reload_count > prev_reload_count {
 4635                        prev_reload_count = reload_count;
 4636                        this.update(cx, |this, cx| {
 4637                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4638                                for buffer in buffer_store.buffers() {
 4639                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4640                                    {
 4641                                        buffer.update(cx, |buffer, cx| {
 4642                                            buffer.set_language_async(None, cx)
 4643                                        });
 4644                                        if let Some(local) = this.as_local_mut() {
 4645                                            local.reset_buffer(&buffer, &f, cx);
 4646
 4647                                            if local
 4648                                                .registered_buffers
 4649                                                .contains_key(&buffer.read(cx).remote_id())
 4650                                                && let Some(file_url) =
 4651                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4652                                            {
 4653                                                local.unregister_buffer_from_language_servers(
 4654                                                    &buffer, &file_url, cx,
 4655                                                );
 4656                                            }
 4657                                        }
 4658                                    }
 4659                                }
 4660                            });
 4661                        });
 4662                    }
 4663
 4664                    this.update(cx, |this, cx| {
 4665                        let mut plain_text_buffers = Vec::new();
 4666                        let mut buffers_with_unknown_injections = Vec::new();
 4667                        for handle in this.buffer_store.read(cx).buffers() {
 4668                            let buffer = handle.read(cx);
 4669                            if buffer.language().is_none()
 4670                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4671                            {
 4672                                plain_text_buffers.push(handle);
 4673                            } else if buffer.contains_unknown_injections() {
 4674                                buffers_with_unknown_injections.push(handle);
 4675                            }
 4676                        }
 4677
 4678                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4679                        // and reused later in the invisible worktrees.
 4680                        plain_text_buffers.sort_by_key(|buffer| {
 4681                            Reverse(
 4682                                File::from_dyn(buffer.read(cx).file())
 4683                                    .map(|file| file.worktree.read(cx).is_visible()),
 4684                            )
 4685                        });
 4686
 4687                        for buffer in plain_text_buffers {
 4688                            this.detect_language_for_buffer(&buffer, cx);
 4689                            if let Some(local) = this.as_local_mut() {
 4690                                local.initialize_buffer(&buffer, cx);
 4691                                if local
 4692                                    .registered_buffers
 4693                                    .contains_key(&buffer.read(cx).remote_id())
 4694                                {
 4695                                    local.register_buffer_with_language_servers(
 4696                                        &buffer,
 4697                                        HashSet::default(),
 4698                                        cx,
 4699                                    );
 4700                                }
 4701                            }
 4702                        }
 4703
 4704                        for buffer in buffers_with_unknown_injections {
 4705                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4706                        }
 4707                    });
 4708                }
 4709            }
 4710        })
 4711    }
 4712
 4713    fn detect_language_for_buffer(
 4714        &mut self,
 4715        buffer_handle: &Entity<Buffer>,
 4716        cx: &mut Context<Self>,
 4717    ) -> Option<language::AvailableLanguage> {
 4718        // If the buffer has a language, set it and start the language server if we haven't already.
 4719        let buffer = buffer_handle.read(cx);
 4720        let file = buffer.file()?;
 4721
 4722        let content = buffer.as_rope();
 4723        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4724        if let Some(available_language) = &available_language {
 4725            if let Some(Ok(Ok(new_language))) = self
 4726                .languages
 4727                .load_language(available_language)
 4728                .now_or_never()
 4729            {
 4730                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4731            }
 4732        } else {
 4733            cx.emit(LspStoreEvent::LanguageDetected {
 4734                buffer: buffer_handle.clone(),
 4735                new_language: None,
 4736            });
 4737        }
 4738
 4739        available_language
 4740    }
 4741
 4742    pub(crate) fn set_language_for_buffer(
 4743        &mut self,
 4744        buffer_entity: &Entity<Buffer>,
 4745        new_language: Arc<Language>,
 4746        cx: &mut Context<Self>,
 4747    ) {
 4748        let buffer = buffer_entity.read(cx);
 4749        let buffer_file = buffer.file().cloned();
 4750        let buffer_id = buffer.remote_id();
 4751        if let Some(local_store) = self.as_local_mut()
 4752            && local_store.registered_buffers.contains_key(&buffer_id)
 4753            && let Some(abs_path) =
 4754                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4755            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4756        {
 4757            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4758        }
 4759        buffer_entity.update(cx, |buffer, cx| {
 4760            if buffer
 4761                .language()
 4762                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4763            {
 4764                buffer.set_language_async(Some(new_language.clone()), cx);
 4765            }
 4766        });
 4767
 4768        let settings =
 4769            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4770        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4771
 4772        let worktree_id = if let Some(file) = buffer_file {
 4773            let worktree = file.worktree.clone();
 4774
 4775            if let Some(local) = self.as_local_mut()
 4776                && local.registered_buffers.contains_key(&buffer_id)
 4777            {
 4778                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4779            }
 4780            Some(worktree.read(cx).id())
 4781        } else {
 4782            None
 4783        };
 4784
 4785        if settings.prettier.allowed
 4786            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4787        {
 4788            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4789            if let Some(prettier_store) = prettier_store {
 4790                prettier_store.update(cx, |prettier_store, cx| {
 4791                    prettier_store.install_default_prettier(
 4792                        worktree_id,
 4793                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4794                        cx,
 4795                    )
 4796                })
 4797            }
 4798        }
 4799
 4800        cx.emit(LspStoreEvent::LanguageDetected {
 4801            buffer: buffer_entity.clone(),
 4802            new_language: Some(new_language),
 4803        })
 4804    }
 4805
 4806    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4807        self.buffer_store.clone()
 4808    }
 4809
 4810    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4811        self.active_entry = active_entry;
 4812    }
 4813
 4814    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4815        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4816            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4817        {
 4818            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4819                summaries
 4820                    .iter()
 4821                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4822            });
 4823            if let Some(summary) = summaries.next() {
 4824                client
 4825                    .send(proto::UpdateDiagnosticSummary {
 4826                        project_id: downstream_project_id,
 4827                        worktree_id: worktree.id().to_proto(),
 4828                        summary: Some(summary),
 4829                        more_summaries: summaries.collect(),
 4830                    })
 4831                    .log_err();
 4832            }
 4833        }
 4834    }
 4835
 4836    fn is_capable_for_proto_request<R>(
 4837        &self,
 4838        buffer: &Entity<Buffer>,
 4839        request: &R,
 4840        cx: &App,
 4841    ) -> bool
 4842    where
 4843        R: LspCommand,
 4844    {
 4845        self.check_if_capable_for_proto_request(
 4846            buffer,
 4847            |capabilities| {
 4848                request.check_capabilities(AdapterServerCapabilities {
 4849                    server_capabilities: capabilities.clone(),
 4850                    code_action_kinds: None,
 4851                })
 4852            },
 4853            cx,
 4854        )
 4855    }
 4856
 4857    fn check_if_capable_for_proto_request<F>(
 4858        &self,
 4859        buffer: &Entity<Buffer>,
 4860        check: F,
 4861        cx: &App,
 4862    ) -> bool
 4863    where
 4864        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4865    {
 4866        let Some(language) = buffer.read(cx).language().cloned() else {
 4867            return false;
 4868        };
 4869        let registered_language_servers = self
 4870            .languages
 4871            .lsp_adapters(&language.name())
 4872            .into_iter()
 4873            .map(|lsp_adapter| lsp_adapter.name())
 4874            .collect::<HashSet<_>>();
 4875        self.language_server_statuses
 4876            .iter()
 4877            .filter_map(|(server_id, server_status)| {
 4878                // Include servers that are either registered for this language OR
 4879                // available to be loaded (for SSH remote mode where adapters like
 4880                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4881                // but only loaded on the server side)
 4882                let is_relevant = registered_language_servers.contains(&server_status.name)
 4883                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4884                is_relevant.then_some(server_id)
 4885            })
 4886            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4887            .any(check)
 4888    }
 4889
 4890    fn all_capable_for_proto_request<F>(
 4891        &self,
 4892        buffer: &Entity<Buffer>,
 4893        mut check: F,
 4894        cx: &App,
 4895    ) -> Vec<lsp::LanguageServerId>
 4896    where
 4897        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4898    {
 4899        let Some(language) = buffer.read(cx).language().cloned() else {
 4900            return Vec::default();
 4901        };
 4902        let registered_language_servers = self
 4903            .languages
 4904            .lsp_adapters(&language.name())
 4905            .into_iter()
 4906            .map(|lsp_adapter| lsp_adapter.name())
 4907            .collect::<HashSet<_>>();
 4908        self.language_server_statuses
 4909            .iter()
 4910            .filter_map(|(server_id, server_status)| {
 4911                // Include servers that are either registered for this language OR
 4912                // available to be loaded (for SSH remote mode where adapters like
 4913                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4914                // but only loaded on the server side)
 4915                let is_relevant = registered_language_servers.contains(&server_status.name)
 4916                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4917                is_relevant.then_some((server_id, &server_status.name))
 4918            })
 4919            .filter_map(|(server_id, server_name)| {
 4920                self.lsp_server_capabilities
 4921                    .get(server_id)
 4922                    .map(|c| (server_id, server_name, c))
 4923            })
 4924            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4925            .map(|(server_id, _, _)| *server_id)
 4926            .collect()
 4927    }
 4928
 4929    pub fn request_lsp<R>(
 4930        &mut self,
 4931        buffer: Entity<Buffer>,
 4932        server: LanguageServerToQuery,
 4933        request: R,
 4934        cx: &mut Context<Self>,
 4935    ) -> Task<Result<R::Response>>
 4936    where
 4937        R: LspCommand,
 4938        <R::LspRequest as lsp::request::Request>::Result: Send,
 4939        <R::LspRequest as lsp::request::Request>::Params: Send,
 4940    {
 4941        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4942            return self.send_lsp_proto_request(
 4943                buffer,
 4944                upstream_client,
 4945                upstream_project_id,
 4946                request,
 4947                cx,
 4948            );
 4949        }
 4950
 4951        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4952            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4953                local
 4954                    .language_servers_for_buffer(buffer, cx)
 4955                    .find(|(_, server)| {
 4956                        request.check_capabilities(server.adapter_server_capabilities())
 4957                    })
 4958                    .map(|(_, server)| server.clone())
 4959            }),
 4960            LanguageServerToQuery::Other(id) => self
 4961                .language_server_for_local_buffer(buffer, id, cx)
 4962                .and_then(|(_, server)| {
 4963                    request
 4964                        .check_capabilities(server.adapter_server_capabilities())
 4965                        .then(|| Arc::clone(server))
 4966                }),
 4967        }) else {
 4968            return Task::ready(Ok(Default::default()));
 4969        };
 4970
 4971        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4972
 4973        let Some(file) = file else {
 4974            return Task::ready(Ok(Default::default()));
 4975        };
 4976
 4977        let lsp_params = match request.to_lsp_params_or_response(
 4978            &file.abs_path(cx),
 4979            buffer.read(cx),
 4980            &language_server,
 4981            cx,
 4982        ) {
 4983            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4984            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4985            Err(err) => {
 4986                let message = format!(
 4987                    "{} via {} failed: {}",
 4988                    request.display_name(),
 4989                    language_server.name(),
 4990                    err
 4991                );
 4992                // rust-analyzer likes to error with this when its still loading up
 4993                if !message.ends_with("content modified") {
 4994                    log::warn!("{message}");
 4995                }
 4996                return Task::ready(Err(anyhow!(message)));
 4997            }
 4998        };
 4999
 5000        let status = request.status();
 5001        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 5002            return Task::ready(Ok(Default::default()));
 5003        }
 5004
 5005        let request_timeout = ProjectSettings::get_global(cx)
 5006            .global_lsp_settings
 5007            .get_request_timeout();
 5008
 5009        cx.spawn(async move |this, cx| {
 5010            let lsp_request = language_server.request::<R::LspRequest>(lsp_params, request_timeout);
 5011
 5012            let id = lsp_request.id();
 5013            let _cleanup = if status.is_some() {
 5014                cx.update(|cx| {
 5015                    this.update(cx, |this, cx| {
 5016                        this.on_lsp_work_start(
 5017                            language_server.server_id(),
 5018                            ProgressToken::Number(id),
 5019                            LanguageServerProgress {
 5020                                is_disk_based_diagnostics_progress: false,
 5021                                is_cancellable: false,
 5022                                title: None,
 5023                                message: status.clone(),
 5024                                percentage: None,
 5025                                last_update_at: cx.background_executor().now(),
 5026                            },
 5027                            cx,
 5028                        );
 5029                    })
 5030                })
 5031                .log_err();
 5032
 5033                Some(defer(|| {
 5034                    cx.update(|cx| {
 5035                        this.update(cx, |this, cx| {
 5036                            this.on_lsp_work_end(
 5037                                language_server.server_id(),
 5038                                ProgressToken::Number(id),
 5039                                cx,
 5040                            );
 5041                        })
 5042                    })
 5043                    .log_err();
 5044                }))
 5045            } else {
 5046                None
 5047            };
 5048
 5049            let result = lsp_request.await.into_response();
 5050
 5051            let response = result.map_err(|err| {
 5052                let message = format!(
 5053                    "{} via {} failed: {}",
 5054                    request.display_name(),
 5055                    language_server.name(),
 5056                    err
 5057                );
 5058                // rust-analyzer likes to error with this when its still loading up
 5059                if !message.ends_with("content modified") {
 5060                    log::warn!("{message}");
 5061                }
 5062                anyhow::anyhow!(message)
 5063            })?;
 5064
 5065            request
 5066                .response_from_lsp(
 5067                    response,
 5068                    this.upgrade().context("no app context")?,
 5069                    buffer,
 5070                    language_server.server_id(),
 5071                    cx.clone(),
 5072                )
 5073                .await
 5074        })
 5075    }
 5076
 5077    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 5078        let mut language_formatters_to_check = Vec::new();
 5079        for buffer in self.buffer_store.read(cx).buffers() {
 5080            let buffer = buffer.read(cx);
 5081            let buffer_file = File::from_dyn(buffer.file());
 5082            let buffer_language = buffer.language();
 5083            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 5084            if buffer_language.is_some() {
 5085                language_formatters_to_check.push((
 5086                    buffer_file.map(|f| f.worktree_id(cx)),
 5087                    settings.into_owned(),
 5088                ));
 5089            }
 5090        }
 5091
 5092        self.request_workspace_config_refresh();
 5093
 5094        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 5095            prettier_store.update(cx, |prettier_store, cx| {
 5096                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 5097            })
 5098        }
 5099
 5100        let new_semantic_token_rules = crate::project_settings::ProjectSettings::get_global(cx)
 5101            .global_lsp_settings
 5102            .semantic_token_rules
 5103            .clone();
 5104        self.semantic_token_config
 5105            .update_rules(new_semantic_token_rules);
 5106
 5107        let new_global_semantic_tokens_mode =
 5108            all_language_settings(None, cx).defaults.semantic_tokens;
 5109        if self
 5110            .semantic_token_config
 5111            .update_global_mode(new_global_semantic_tokens_mode)
 5112        {
 5113            self.restart_all_language_servers(cx);
 5114        }
 5115
 5116        cx.notify();
 5117    }
 5118
 5119    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 5120        let buffer_store = self.buffer_store.clone();
 5121        let Some(local) = self.as_local_mut() else {
 5122            return;
 5123        };
 5124        let mut adapters = BTreeMap::default();
 5125        let get_adapter = {
 5126            let languages = local.languages.clone();
 5127            let environment = local.environment.clone();
 5128            let weak = local.weak.clone();
 5129            let worktree_store = local.worktree_store.clone();
 5130            let http_client = local.http_client.clone();
 5131            let fs = local.fs.clone();
 5132            move |worktree_id, cx: &mut App| {
 5133                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 5134                Some(LocalLspAdapterDelegate::new(
 5135                    languages.clone(),
 5136                    &environment,
 5137                    weak.clone(),
 5138                    &worktree,
 5139                    http_client.clone(),
 5140                    fs.clone(),
 5141                    cx,
 5142                ))
 5143            }
 5144        };
 5145
 5146        let mut messages_to_report = Vec::new();
 5147        let (new_tree, to_stop) = {
 5148            let mut rebase = local.lsp_tree.rebase();
 5149            let buffers = buffer_store
 5150                .read(cx)
 5151                .buffers()
 5152                .filter_map(|buffer| {
 5153                    let raw_buffer = buffer.read(cx);
 5154                    if !local
 5155                        .registered_buffers
 5156                        .contains_key(&raw_buffer.remote_id())
 5157                    {
 5158                        return None;
 5159                    }
 5160                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5161                    let language = raw_buffer.language().cloned()?;
 5162                    Some((file, language, raw_buffer.remote_id()))
 5163                })
 5164                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5165            for (file, language, buffer_id) in buffers {
 5166                let worktree_id = file.worktree_id(cx);
 5167                let Some(worktree) = local
 5168                    .worktree_store
 5169                    .read(cx)
 5170                    .worktree_for_id(worktree_id, cx)
 5171                else {
 5172                    continue;
 5173                };
 5174
 5175                if let Some((_, apply)) = local.reuse_existing_language_server(
 5176                    rebase.server_tree(),
 5177                    &worktree,
 5178                    &language.name(),
 5179                    cx,
 5180                ) {
 5181                    (apply)(rebase.server_tree());
 5182                } else if let Some(lsp_delegate) = adapters
 5183                    .entry(worktree_id)
 5184                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5185                    .clone()
 5186                {
 5187                    let delegate =
 5188                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5189                    let path = file
 5190                        .path()
 5191                        .parent()
 5192                        .map(Arc::from)
 5193                        .unwrap_or_else(|| file.path().clone());
 5194                    let worktree_path = ProjectPath { worktree_id, path };
 5195                    let abs_path = file.abs_path(cx);
 5196                    let nodes = rebase
 5197                        .walk(
 5198                            worktree_path,
 5199                            language.name(),
 5200                            language.manifest(),
 5201                            delegate.clone(),
 5202                            cx,
 5203                        )
 5204                        .collect::<Vec<_>>();
 5205                    for node in nodes {
 5206                        let server_id = node.server_id_or_init(|disposition| {
 5207                            let path = &disposition.path;
 5208                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5209                            let key = LanguageServerSeed {
 5210                                worktree_id,
 5211                                name: disposition.server_name.clone(),
 5212                                settings: LanguageServerSeedSettings {
 5213                                    binary: disposition.settings.binary.clone(),
 5214                                    initialization_options: disposition
 5215                                        .settings
 5216                                        .initialization_options
 5217                                        .clone(),
 5218                                },
 5219                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5220                                    path.worktree_id,
 5221                                    &path.path,
 5222                                    language.name(),
 5223                                ),
 5224                            };
 5225                            local.language_server_ids.remove(&key);
 5226
 5227                            let server_id = local.get_or_insert_language_server(
 5228                                &worktree,
 5229                                lsp_delegate.clone(),
 5230                                disposition,
 5231                                &language.name(),
 5232                                cx,
 5233                            );
 5234                            if let Some(state) = local.language_servers.get(&server_id)
 5235                                && let Ok(uri) = uri
 5236                            {
 5237                                state.add_workspace_folder(uri);
 5238                            };
 5239                            server_id
 5240                        });
 5241
 5242                        if let Some(language_server_id) = server_id {
 5243                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5244                                language_server_id,
 5245                                name: node.name(),
 5246                                message:
 5247                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5248                                        proto::RegisteredForBuffer {
 5249                                            buffer_abs_path: abs_path
 5250                                                .to_string_lossy()
 5251                                                .into_owned(),
 5252                                            buffer_id: buffer_id.to_proto(),
 5253                                        },
 5254                                    ),
 5255                            });
 5256                        }
 5257                    }
 5258                } else {
 5259                    continue;
 5260                }
 5261            }
 5262            rebase.finish()
 5263        };
 5264        for message in messages_to_report {
 5265            cx.emit(message);
 5266        }
 5267        local.lsp_tree = new_tree;
 5268        for (id, _) in to_stop {
 5269            self.stop_local_language_server(id, cx).detach();
 5270        }
 5271    }
 5272
 5273    pub fn apply_code_action(
 5274        &self,
 5275        buffer_handle: Entity<Buffer>,
 5276        mut action: CodeAction,
 5277        push_to_history: bool,
 5278        cx: &mut Context<Self>,
 5279    ) -> Task<Result<ProjectTransaction>> {
 5280        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5281            let request = proto::ApplyCodeAction {
 5282                project_id,
 5283                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5284                action: Some(Self::serialize_code_action(&action)),
 5285            };
 5286            let buffer_store = self.buffer_store();
 5287            cx.spawn(async move |_, cx| {
 5288                let response = upstream_client
 5289                    .request(request)
 5290                    .await?
 5291                    .transaction
 5292                    .context("missing transaction")?;
 5293
 5294                buffer_store
 5295                    .update(cx, |buffer_store, cx| {
 5296                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5297                    })
 5298                    .await
 5299            })
 5300        } else if self.mode.is_local() {
 5301            let Some((_, lang_server, request_timeout)) = buffer_handle.update(cx, |buffer, cx| {
 5302                let request_timeout = ProjectSettings::get_global(cx)
 5303                    .global_lsp_settings
 5304                    .get_request_timeout();
 5305                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5306                    .map(|(adapter, server)| (adapter.clone(), server.clone(), request_timeout))
 5307            }) else {
 5308                return Task::ready(Ok(ProjectTransaction::default()));
 5309            };
 5310
 5311            cx.spawn(async move |this, cx| {
 5312                LocalLspStore::try_resolve_code_action(&lang_server, &mut action, request_timeout)
 5313                    .await
 5314                    .context("resolving a code action")?;
 5315                if let Some(edit) = action.lsp_action.edit()
 5316                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5317                        return LocalLspStore::deserialize_workspace_edit(
 5318                            this.upgrade().context("no app present")?,
 5319                            edit.clone(),
 5320                            push_to_history,
 5321
 5322                            lang_server.clone(),
 5323                            cx,
 5324                        )
 5325                        .await;
 5326                    }
 5327
 5328                let Some(command) = action.lsp_action.command() else {
 5329                    return Ok(ProjectTransaction::default())
 5330                };
 5331
 5332                let server_capabilities = lang_server.capabilities();
 5333                let available_commands = server_capabilities
 5334                    .execute_command_provider
 5335                    .as_ref()
 5336                    .map(|options| options.commands.as_slice())
 5337                    .unwrap_or_default();
 5338
 5339                if !available_commands.contains(&command.command) {
 5340                    log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5341                    return Ok(ProjectTransaction::default())
 5342                }
 5343
 5344                let request_timeout = cx.update(|app|
 5345                    ProjectSettings::get_global(app)
 5346                    .global_lsp_settings
 5347                    .get_request_timeout()
 5348                );
 5349
 5350                this.update(cx, |this, _| {
 5351                    this.as_local_mut()
 5352                        .unwrap()
 5353                        .last_workspace_edits_by_language_server
 5354                        .remove(&lang_server.server_id());
 5355                })?;
 5356
 5357                let _result = lang_server
 5358                    .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5359                        command: command.command.clone(),
 5360                        arguments: command.arguments.clone().unwrap_or_default(),
 5361                        ..lsp::ExecuteCommandParams::default()
 5362                    }, request_timeout)
 5363                    .await.into_response()
 5364                    .context("execute command")?;
 5365
 5366                return this.update(cx, |this, _| {
 5367                    this.as_local_mut()
 5368                        .unwrap()
 5369                        .last_workspace_edits_by_language_server
 5370                        .remove(&lang_server.server_id())
 5371                        .unwrap_or_default()
 5372                });
 5373            })
 5374        } else {
 5375            Task::ready(Err(anyhow!("no upstream client and not local")))
 5376        }
 5377    }
 5378
 5379    pub fn apply_code_action_kind(
 5380        &mut self,
 5381        buffers: HashSet<Entity<Buffer>>,
 5382        kind: CodeActionKind,
 5383        push_to_history: bool,
 5384        cx: &mut Context<Self>,
 5385    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5386        if self.as_local().is_some() {
 5387            cx.spawn(async move |lsp_store, cx| {
 5388                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5389                let result = LocalLspStore::execute_code_action_kind_locally(
 5390                    lsp_store.clone(),
 5391                    buffers,
 5392                    kind,
 5393                    push_to_history,
 5394                    cx,
 5395                )
 5396                .await;
 5397                lsp_store.update(cx, |lsp_store, _| {
 5398                    lsp_store.update_last_formatting_failure(&result);
 5399                })?;
 5400                result
 5401            })
 5402        } else if let Some((client, project_id)) = self.upstream_client() {
 5403            let buffer_store = self.buffer_store();
 5404            cx.spawn(async move |lsp_store, cx| {
 5405                let result = client
 5406                    .request(proto::ApplyCodeActionKind {
 5407                        project_id,
 5408                        kind: kind.as_str().to_owned(),
 5409                        buffer_ids: buffers
 5410                            .iter()
 5411                            .map(|buffer| {
 5412                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5413                            })
 5414                            .collect(),
 5415                    })
 5416                    .await
 5417                    .and_then(|result| result.transaction.context("missing transaction"));
 5418                lsp_store.update(cx, |lsp_store, _| {
 5419                    lsp_store.update_last_formatting_failure(&result);
 5420                })?;
 5421
 5422                let transaction_response = result?;
 5423                buffer_store
 5424                    .update(cx, |buffer_store, cx| {
 5425                        buffer_store.deserialize_project_transaction(
 5426                            transaction_response,
 5427                            push_to_history,
 5428                            cx,
 5429                        )
 5430                    })
 5431                    .await
 5432            })
 5433        } else {
 5434            Task::ready(Ok(ProjectTransaction::default()))
 5435        }
 5436    }
 5437
 5438    pub fn resolved_hint(
 5439        &mut self,
 5440        buffer_id: BufferId,
 5441        id: InlayId,
 5442        cx: &mut Context<Self>,
 5443    ) -> Option<ResolvedHint> {
 5444        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5445
 5446        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5447        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5448        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5449        let (server_id, resolve_data) = match &hint.resolve_state {
 5450            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5451            ResolveState::Resolving => {
 5452                return Some(ResolvedHint::Resolving(
 5453                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5454                ));
 5455            }
 5456            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5457        };
 5458
 5459        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5460        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5461        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5462            id,
 5463            cx.spawn(async move |lsp_store, cx| {
 5464                let resolved_hint = resolve_task.await;
 5465                lsp_store
 5466                    .update(cx, |lsp_store, _| {
 5467                        if let Some(old_inlay_hint) = lsp_store
 5468                            .lsp_data
 5469                            .get_mut(&buffer_id)
 5470                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5471                        {
 5472                            match resolved_hint {
 5473                                Ok(resolved_hint) => {
 5474                                    *old_inlay_hint = resolved_hint;
 5475                                }
 5476                                Err(e) => {
 5477                                    old_inlay_hint.resolve_state =
 5478                                        ResolveState::CanResolve(server_id, resolve_data);
 5479                                    log::error!("Inlay hint resolve failed: {e:#}");
 5480                                }
 5481                            }
 5482                        }
 5483                    })
 5484                    .ok();
 5485            })
 5486            .shared(),
 5487        );
 5488        debug_assert!(
 5489            previous_task.is_none(),
 5490            "Did not change hint's resolve state after spawning its resolve"
 5491        );
 5492        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5493        None
 5494    }
 5495
 5496    pub(crate) fn linked_edits(
 5497        &mut self,
 5498        buffer: &Entity<Buffer>,
 5499        position: Anchor,
 5500        cx: &mut Context<Self>,
 5501    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5502        let snapshot = buffer.read(cx).snapshot();
 5503        let scope = snapshot.language_scope_at(position);
 5504        let Some(server_id) = self
 5505            .as_local()
 5506            .and_then(|local| {
 5507                buffer.update(cx, |buffer, cx| {
 5508                    local
 5509                        .language_servers_for_buffer(buffer, cx)
 5510                        .filter(|(_, server)| {
 5511                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5512                        })
 5513                        .filter(|(adapter, _)| {
 5514                            scope
 5515                                .as_ref()
 5516                                .map(|scope| scope.language_allowed(&adapter.name))
 5517                                .unwrap_or(true)
 5518                        })
 5519                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5520                        .next()
 5521                })
 5522            })
 5523            .or_else(|| {
 5524                self.upstream_client()
 5525                    .is_some()
 5526                    .then_some(LanguageServerToQuery::FirstCapable)
 5527            })
 5528            .filter(|_| {
 5529                maybe!({
 5530                    let language = buffer.read(cx).language_at(position)?;
 5531                    Some(
 5532                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5533                            .linked_edits,
 5534                    )
 5535                }) == Some(true)
 5536            })
 5537        else {
 5538            return Task::ready(Ok(Vec::new()));
 5539        };
 5540
 5541        self.request_lsp(
 5542            buffer.clone(),
 5543            server_id,
 5544            LinkedEditingRange { position },
 5545            cx,
 5546        )
 5547    }
 5548
 5549    fn apply_on_type_formatting(
 5550        &mut self,
 5551        buffer: Entity<Buffer>,
 5552        position: Anchor,
 5553        trigger: String,
 5554        cx: &mut Context<Self>,
 5555    ) -> Task<Result<Option<Transaction>>> {
 5556        if let Some((client, project_id)) = self.upstream_client() {
 5557            if !self.check_if_capable_for_proto_request(
 5558                &buffer,
 5559                |capabilities| {
 5560                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5561                },
 5562                cx,
 5563            ) {
 5564                return Task::ready(Ok(None));
 5565            }
 5566            let request = proto::OnTypeFormatting {
 5567                project_id,
 5568                buffer_id: buffer.read(cx).remote_id().into(),
 5569                position: Some(serialize_anchor(&position)),
 5570                trigger,
 5571                version: serialize_version(&buffer.read(cx).version()),
 5572            };
 5573            cx.background_spawn(async move {
 5574                client
 5575                    .request(request)
 5576                    .await?
 5577                    .transaction
 5578                    .map(language::proto::deserialize_transaction)
 5579                    .transpose()
 5580            })
 5581        } else if let Some(local) = self.as_local_mut() {
 5582            let buffer_id = buffer.read(cx).remote_id();
 5583            local.buffers_being_formatted.insert(buffer_id);
 5584            cx.spawn(async move |this, cx| {
 5585                let _cleanup = defer({
 5586                    let this = this.clone();
 5587                    let mut cx = cx.clone();
 5588                    move || {
 5589                        this.update(&mut cx, |this, _| {
 5590                            if let Some(local) = this.as_local_mut() {
 5591                                local.buffers_being_formatted.remove(&buffer_id);
 5592                            }
 5593                        })
 5594                        .ok();
 5595                    }
 5596                });
 5597
 5598                buffer
 5599                    .update(cx, |buffer, _| {
 5600                        buffer.wait_for_edits(Some(position.timestamp))
 5601                    })
 5602                    .await?;
 5603                this.update(cx, |this, cx| {
 5604                    let position = position.to_point_utf16(buffer.read(cx));
 5605                    this.on_type_format(buffer, position, trigger, false, cx)
 5606                })?
 5607                .await
 5608            })
 5609        } else {
 5610            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5611        }
 5612    }
 5613
 5614    pub fn on_type_format<T: ToPointUtf16>(
 5615        &mut self,
 5616        buffer: Entity<Buffer>,
 5617        position: T,
 5618        trigger: String,
 5619        push_to_history: bool,
 5620        cx: &mut Context<Self>,
 5621    ) -> Task<Result<Option<Transaction>>> {
 5622        let position = position.to_point_utf16(buffer.read(cx));
 5623        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5624    }
 5625
 5626    fn on_type_format_impl(
 5627        &mut self,
 5628        buffer: Entity<Buffer>,
 5629        position: PointUtf16,
 5630        trigger: String,
 5631        push_to_history: bool,
 5632        cx: &mut Context<Self>,
 5633    ) -> Task<Result<Option<Transaction>>> {
 5634        let options = buffer.update(cx, |buffer, cx| {
 5635            lsp_command::lsp_formatting_options(
 5636                language_settings(
 5637                    buffer.language_at(position).map(|l| l.name()),
 5638                    buffer.file(),
 5639                    cx,
 5640                )
 5641                .as_ref(),
 5642            )
 5643        });
 5644
 5645        cx.spawn(async move |this, cx| {
 5646            if let Some(waiter) =
 5647                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5648            {
 5649                waiter.await?;
 5650            }
 5651            cx.update(|cx| {
 5652                this.update(cx, |this, cx| {
 5653                    this.request_lsp(
 5654                        buffer.clone(),
 5655                        LanguageServerToQuery::FirstCapable,
 5656                        OnTypeFormatting {
 5657                            position,
 5658                            trigger,
 5659                            options,
 5660                            push_to_history,
 5661                        },
 5662                        cx,
 5663                    )
 5664                })
 5665            })?
 5666            .await
 5667        })
 5668    }
 5669
 5670    pub fn definitions(
 5671        &mut self,
 5672        buffer: &Entity<Buffer>,
 5673        position: PointUtf16,
 5674        cx: &mut Context<Self>,
 5675    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5676        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5677            let request = GetDefinitions { position };
 5678            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5679                return Task::ready(Ok(None));
 5680            }
 5681
 5682            let request_timeout = ProjectSettings::get_global(cx)
 5683                .global_lsp_settings
 5684                .get_request_timeout();
 5685
 5686            let request_task = upstream_client.request_lsp(
 5687                project_id,
 5688                None,
 5689                request_timeout,
 5690                cx.background_executor().clone(),
 5691                request.to_proto(project_id, buffer.read(cx)),
 5692            );
 5693            let buffer = buffer.clone();
 5694            cx.spawn(async move |weak_lsp_store, cx| {
 5695                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5696                    return Ok(None);
 5697                };
 5698                let Some(responses) = request_task.await? else {
 5699                    return Ok(None);
 5700                };
 5701                let actions = join_all(responses.payload.into_iter().map(|response| {
 5702                    GetDefinitions { position }.response_from_proto(
 5703                        response.response,
 5704                        lsp_store.clone(),
 5705                        buffer.clone(),
 5706                        cx.clone(),
 5707                    )
 5708                }))
 5709                .await;
 5710
 5711                Ok(Some(
 5712                    actions
 5713                        .into_iter()
 5714                        .collect::<Result<Vec<Vec<_>>>>()?
 5715                        .into_iter()
 5716                        .flatten()
 5717                        .dedup()
 5718                        .collect(),
 5719                ))
 5720            })
 5721        } else {
 5722            let definitions_task = self.request_multiple_lsp_locally(
 5723                buffer,
 5724                Some(position),
 5725                GetDefinitions { position },
 5726                cx,
 5727            );
 5728            cx.background_spawn(async move {
 5729                Ok(Some(
 5730                    definitions_task
 5731                        .await
 5732                        .into_iter()
 5733                        .flat_map(|(_, definitions)| definitions)
 5734                        .dedup()
 5735                        .collect(),
 5736                ))
 5737            })
 5738        }
 5739    }
 5740
 5741    pub fn declarations(
 5742        &mut self,
 5743        buffer: &Entity<Buffer>,
 5744        position: PointUtf16,
 5745        cx: &mut Context<Self>,
 5746    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5747        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5748            let request = GetDeclarations { position };
 5749            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5750                return Task::ready(Ok(None));
 5751            }
 5752            let request_timeout = ProjectSettings::get_global(cx)
 5753                .global_lsp_settings
 5754                .get_request_timeout();
 5755            let request_task = upstream_client.request_lsp(
 5756                project_id,
 5757                None,
 5758                request_timeout,
 5759                cx.background_executor().clone(),
 5760                request.to_proto(project_id, buffer.read(cx)),
 5761            );
 5762            let buffer = buffer.clone();
 5763            cx.spawn(async move |weak_lsp_store, cx| {
 5764                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5765                    return Ok(None);
 5766                };
 5767                let Some(responses) = request_task.await? else {
 5768                    return Ok(None);
 5769                };
 5770                let actions = join_all(responses.payload.into_iter().map(|response| {
 5771                    GetDeclarations { position }.response_from_proto(
 5772                        response.response,
 5773                        lsp_store.clone(),
 5774                        buffer.clone(),
 5775                        cx.clone(),
 5776                    )
 5777                }))
 5778                .await;
 5779
 5780                Ok(Some(
 5781                    actions
 5782                        .into_iter()
 5783                        .collect::<Result<Vec<Vec<_>>>>()?
 5784                        .into_iter()
 5785                        .flatten()
 5786                        .dedup()
 5787                        .collect(),
 5788                ))
 5789            })
 5790        } else {
 5791            let declarations_task = self.request_multiple_lsp_locally(
 5792                buffer,
 5793                Some(position),
 5794                GetDeclarations { position },
 5795                cx,
 5796            );
 5797            cx.background_spawn(async move {
 5798                Ok(Some(
 5799                    declarations_task
 5800                        .await
 5801                        .into_iter()
 5802                        .flat_map(|(_, declarations)| declarations)
 5803                        .dedup()
 5804                        .collect(),
 5805                ))
 5806            })
 5807        }
 5808    }
 5809
 5810    pub fn type_definitions(
 5811        &mut self,
 5812        buffer: &Entity<Buffer>,
 5813        position: PointUtf16,
 5814        cx: &mut Context<Self>,
 5815    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5816        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5817            let request = GetTypeDefinitions { position };
 5818            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5819                return Task::ready(Ok(None));
 5820            }
 5821            let request_timeout = ProjectSettings::get_global(cx)
 5822                .global_lsp_settings
 5823                .get_request_timeout();
 5824            let request_task = upstream_client.request_lsp(
 5825                project_id,
 5826                None,
 5827                request_timeout,
 5828                cx.background_executor().clone(),
 5829                request.to_proto(project_id, buffer.read(cx)),
 5830            );
 5831            let buffer = buffer.clone();
 5832            cx.spawn(async move |weak_lsp_store, cx| {
 5833                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5834                    return Ok(None);
 5835                };
 5836                let Some(responses) = request_task.await? else {
 5837                    return Ok(None);
 5838                };
 5839                let actions = join_all(responses.payload.into_iter().map(|response| {
 5840                    GetTypeDefinitions { position }.response_from_proto(
 5841                        response.response,
 5842                        lsp_store.clone(),
 5843                        buffer.clone(),
 5844                        cx.clone(),
 5845                    )
 5846                }))
 5847                .await;
 5848
 5849                Ok(Some(
 5850                    actions
 5851                        .into_iter()
 5852                        .collect::<Result<Vec<Vec<_>>>>()?
 5853                        .into_iter()
 5854                        .flatten()
 5855                        .dedup()
 5856                        .collect(),
 5857                ))
 5858            })
 5859        } else {
 5860            let type_definitions_task = self.request_multiple_lsp_locally(
 5861                buffer,
 5862                Some(position),
 5863                GetTypeDefinitions { position },
 5864                cx,
 5865            );
 5866            cx.background_spawn(async move {
 5867                Ok(Some(
 5868                    type_definitions_task
 5869                        .await
 5870                        .into_iter()
 5871                        .flat_map(|(_, type_definitions)| type_definitions)
 5872                        .dedup()
 5873                        .collect(),
 5874                ))
 5875            })
 5876        }
 5877    }
 5878
 5879    pub fn implementations(
 5880        &mut self,
 5881        buffer: &Entity<Buffer>,
 5882        position: PointUtf16,
 5883        cx: &mut Context<Self>,
 5884    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5885        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5886            let request = GetImplementations { position };
 5887            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5888                return Task::ready(Ok(None));
 5889            }
 5890
 5891            let request_timeout = ProjectSettings::get_global(cx)
 5892                .global_lsp_settings
 5893                .get_request_timeout();
 5894            let request_task = upstream_client.request_lsp(
 5895                project_id,
 5896                None,
 5897                request_timeout,
 5898                cx.background_executor().clone(),
 5899                request.to_proto(project_id, buffer.read(cx)),
 5900            );
 5901            let buffer = buffer.clone();
 5902            cx.spawn(async move |weak_lsp_store, cx| {
 5903                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5904                    return Ok(None);
 5905                };
 5906                let Some(responses) = request_task.await? else {
 5907                    return Ok(None);
 5908                };
 5909                let actions = join_all(responses.payload.into_iter().map(|response| {
 5910                    GetImplementations { position }.response_from_proto(
 5911                        response.response,
 5912                        lsp_store.clone(),
 5913                        buffer.clone(),
 5914                        cx.clone(),
 5915                    )
 5916                }))
 5917                .await;
 5918
 5919                Ok(Some(
 5920                    actions
 5921                        .into_iter()
 5922                        .collect::<Result<Vec<Vec<_>>>>()?
 5923                        .into_iter()
 5924                        .flatten()
 5925                        .dedup()
 5926                        .collect(),
 5927                ))
 5928            })
 5929        } else {
 5930            let implementations_task = self.request_multiple_lsp_locally(
 5931                buffer,
 5932                Some(position),
 5933                GetImplementations { position },
 5934                cx,
 5935            );
 5936            cx.background_spawn(async move {
 5937                Ok(Some(
 5938                    implementations_task
 5939                        .await
 5940                        .into_iter()
 5941                        .flat_map(|(_, implementations)| implementations)
 5942                        .dedup()
 5943                        .collect(),
 5944                ))
 5945            })
 5946        }
 5947    }
 5948
 5949    pub fn references(
 5950        &mut self,
 5951        buffer: &Entity<Buffer>,
 5952        position: PointUtf16,
 5953        cx: &mut Context<Self>,
 5954    ) -> Task<Result<Option<Vec<Location>>>> {
 5955        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5956            let request = GetReferences { position };
 5957            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5958                return Task::ready(Ok(None));
 5959            }
 5960
 5961            let request_timeout = ProjectSettings::get_global(cx)
 5962                .global_lsp_settings
 5963                .get_request_timeout();
 5964            let request_task = upstream_client.request_lsp(
 5965                project_id,
 5966                None,
 5967                request_timeout,
 5968                cx.background_executor().clone(),
 5969                request.to_proto(project_id, buffer.read(cx)),
 5970            );
 5971            let buffer = buffer.clone();
 5972            cx.spawn(async move |weak_lsp_store, cx| {
 5973                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5974                    return Ok(None);
 5975                };
 5976                let Some(responses) = request_task.await? else {
 5977                    return Ok(None);
 5978                };
 5979
 5980                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5981                    GetReferences { position }.response_from_proto(
 5982                        lsp_response.response,
 5983                        lsp_store.clone(),
 5984                        buffer.clone(),
 5985                        cx.clone(),
 5986                    )
 5987                }))
 5988                .await
 5989                .into_iter()
 5990                .collect::<Result<Vec<Vec<_>>>>()?
 5991                .into_iter()
 5992                .flatten()
 5993                .dedup()
 5994                .collect();
 5995                Ok(Some(locations))
 5996            })
 5997        } else {
 5998            let references_task = self.request_multiple_lsp_locally(
 5999                buffer,
 6000                Some(position),
 6001                GetReferences { position },
 6002                cx,
 6003            );
 6004            cx.background_spawn(async move {
 6005                Ok(Some(
 6006                    references_task
 6007                        .await
 6008                        .into_iter()
 6009                        .flat_map(|(_, references)| references)
 6010                        .dedup()
 6011                        .collect(),
 6012                ))
 6013            })
 6014        }
 6015    }
 6016
 6017    pub fn code_actions(
 6018        &mut self,
 6019        buffer: &Entity<Buffer>,
 6020        range: Range<Anchor>,
 6021        kinds: Option<Vec<CodeActionKind>>,
 6022        cx: &mut Context<Self>,
 6023    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6024        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6025            let request = GetCodeActions {
 6026                range: range.clone(),
 6027                kinds: kinds.clone(),
 6028            };
 6029            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6030                return Task::ready(Ok(None));
 6031            }
 6032            let request_timeout = ProjectSettings::get_global(cx)
 6033                .global_lsp_settings
 6034                .get_request_timeout();
 6035            let request_task = upstream_client.request_lsp(
 6036                project_id,
 6037                None,
 6038                request_timeout,
 6039                cx.background_executor().clone(),
 6040                request.to_proto(project_id, buffer.read(cx)),
 6041            );
 6042            let buffer = buffer.clone();
 6043            cx.spawn(async move |weak_lsp_store, cx| {
 6044                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6045                    return Ok(None);
 6046                };
 6047                let Some(responses) = request_task.await? else {
 6048                    return Ok(None);
 6049                };
 6050                let actions = join_all(responses.payload.into_iter().map(|response| {
 6051                    GetCodeActions {
 6052                        range: range.clone(),
 6053                        kinds: kinds.clone(),
 6054                    }
 6055                    .response_from_proto(
 6056                        response.response,
 6057                        lsp_store.clone(),
 6058                        buffer.clone(),
 6059                        cx.clone(),
 6060                    )
 6061                }))
 6062                .await;
 6063
 6064                Ok(Some(
 6065                    actions
 6066                        .into_iter()
 6067                        .collect::<Result<Vec<Vec<_>>>>()?
 6068                        .into_iter()
 6069                        .flatten()
 6070                        .collect(),
 6071                ))
 6072            })
 6073        } else {
 6074            let all_actions_task = self.request_multiple_lsp_locally(
 6075                buffer,
 6076                Some(range.start),
 6077                GetCodeActions { range, kinds },
 6078                cx,
 6079            );
 6080            cx.background_spawn(async move {
 6081                Ok(Some(
 6082                    all_actions_task
 6083                        .await
 6084                        .into_iter()
 6085                        .flat_map(|(_, actions)| actions)
 6086                        .collect(),
 6087                ))
 6088            })
 6089        }
 6090    }
 6091
 6092    #[inline(never)]
 6093    pub fn completions(
 6094        &self,
 6095        buffer: &Entity<Buffer>,
 6096        position: PointUtf16,
 6097        context: CompletionContext,
 6098        cx: &mut Context<Self>,
 6099    ) -> Task<Result<Vec<CompletionResponse>>> {
 6100        let language_registry = self.languages.clone();
 6101
 6102        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6103            let snapshot = buffer.read(cx).snapshot();
 6104            let offset = position.to_offset(&snapshot);
 6105            let scope = snapshot.language_scope_at(offset);
 6106            let capable_lsps = self.all_capable_for_proto_request(
 6107                buffer,
 6108                |server_name, capabilities| {
 6109                    capabilities.completion_provider.is_some()
 6110                        && scope
 6111                            .as_ref()
 6112                            .map(|scope| scope.language_allowed(server_name))
 6113                            .unwrap_or(true)
 6114                },
 6115                cx,
 6116            );
 6117            if capable_lsps.is_empty() {
 6118                return Task::ready(Ok(Vec::new()));
 6119            }
 6120
 6121            let language = buffer.read(cx).language().cloned();
 6122
 6123            // In the future, we should provide project guests with the names of LSP adapters,
 6124            // so that they can use the correct LSP adapter when computing labels. For now,
 6125            // guests just use the first LSP adapter associated with the buffer's language.
 6126            let lsp_adapter = language.as_ref().and_then(|language| {
 6127                language_registry
 6128                    .lsp_adapters(&language.name())
 6129                    .first()
 6130                    .cloned()
 6131            });
 6132
 6133            let buffer = buffer.clone();
 6134
 6135            cx.spawn(async move |this, cx| {
 6136                let requests = join_all(
 6137                    capable_lsps
 6138                        .into_iter()
 6139                        .map(|id| {
 6140                            let request = GetCompletions {
 6141                                position,
 6142                                context: context.clone(),
 6143                                server_id: Some(id),
 6144                            };
 6145                            let buffer = buffer.clone();
 6146                            let language = language.clone();
 6147                            let lsp_adapter = lsp_adapter.clone();
 6148                            let upstream_client = upstream_client.clone();
 6149                            let response = this
 6150                                .update(cx, |this, cx| {
 6151                                    this.send_lsp_proto_request(
 6152                                        buffer,
 6153                                        upstream_client,
 6154                                        project_id,
 6155                                        request,
 6156                                        cx,
 6157                                    )
 6158                                })
 6159                                .log_err();
 6160                            async move {
 6161                                let response = response?.await.log_err()?;
 6162
 6163                                let completions = populate_labels_for_completions(
 6164                                    response.completions,
 6165                                    language,
 6166                                    lsp_adapter,
 6167                                )
 6168                                .await;
 6169
 6170                                Some(CompletionResponse {
 6171                                    completions,
 6172                                    display_options: CompletionDisplayOptions::default(),
 6173                                    is_incomplete: response.is_incomplete,
 6174                                })
 6175                            }
 6176                        })
 6177                        .collect::<Vec<_>>(),
 6178                );
 6179                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6180            })
 6181        } else if let Some(local) = self.as_local() {
 6182            let snapshot = buffer.read(cx).snapshot();
 6183            let offset = position.to_offset(&snapshot);
 6184            let scope = snapshot.language_scope_at(offset);
 6185            let language = snapshot.language().cloned();
 6186            let completion_settings = language_settings(
 6187                language.as_ref().map(|language| language.name()),
 6188                buffer.read(cx).file(),
 6189                cx,
 6190            )
 6191            .completions
 6192            .clone();
 6193            if !completion_settings.lsp {
 6194                return Task::ready(Ok(Vec::new()));
 6195            }
 6196
 6197            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6198                local
 6199                    .language_servers_for_buffer(buffer, cx)
 6200                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6201                    .filter(|(adapter, _)| {
 6202                        scope
 6203                            .as_ref()
 6204                            .map(|scope| scope.language_allowed(&adapter.name))
 6205                            .unwrap_or(true)
 6206                    })
 6207                    .map(|(_, server)| server.server_id())
 6208                    .collect()
 6209            });
 6210
 6211            let buffer = buffer.clone();
 6212            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6213            let lsp_timeout = if lsp_timeout > 0 {
 6214                Some(Duration::from_millis(lsp_timeout))
 6215            } else {
 6216                None
 6217            };
 6218            cx.spawn(async move |this,  cx| {
 6219                let mut tasks = Vec::with_capacity(server_ids.len());
 6220                this.update(cx, |lsp_store, cx| {
 6221                    for server_id in server_ids {
 6222                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6223                        let lsp_timeout = lsp_timeout
 6224                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6225                        let mut timeout = cx.background_spawn(async move {
 6226                            match lsp_timeout {
 6227                                Some(lsp_timeout) => {
 6228                                    lsp_timeout.await;
 6229                                    true
 6230                                },
 6231                                None => false,
 6232                            }
 6233                        }).fuse();
 6234                        let mut lsp_request = lsp_store.request_lsp(
 6235                            buffer.clone(),
 6236                            LanguageServerToQuery::Other(server_id),
 6237                            GetCompletions {
 6238                                position,
 6239                                context: context.clone(),
 6240                                server_id: Some(server_id),
 6241                            },
 6242                            cx,
 6243                        ).fuse();
 6244                        let new_task = cx.background_spawn(async move {
 6245                            select_biased! {
 6246                                response = lsp_request => anyhow::Ok(Some(response?)),
 6247                                timeout_happened = timeout => {
 6248                                    if timeout_happened {
 6249                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6250                                        Ok(None)
 6251                                    } else {
 6252                                        let completions = lsp_request.await?;
 6253                                        Ok(Some(completions))
 6254                                    }
 6255                                },
 6256                            }
 6257                        });
 6258                        tasks.push((lsp_adapter, new_task));
 6259                    }
 6260                })?;
 6261
 6262                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6263                    let completion_response = task.await.ok()??;
 6264                    let completions = populate_labels_for_completions(
 6265                            completion_response.completions,
 6266                            language.clone(),
 6267                            lsp_adapter,
 6268                        )
 6269                        .await;
 6270                    Some(CompletionResponse {
 6271                        completions,
 6272                        display_options: CompletionDisplayOptions::default(),
 6273                        is_incomplete: completion_response.is_incomplete,
 6274                    })
 6275                });
 6276
 6277                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6278
 6279                Ok(responses.into_iter().flatten().collect())
 6280            })
 6281        } else {
 6282            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6283        }
 6284    }
 6285
 6286    pub fn resolve_completions(
 6287        &self,
 6288        buffer: Entity<Buffer>,
 6289        completion_indices: Vec<usize>,
 6290        completions: Rc<RefCell<Box<[Completion]>>>,
 6291        cx: &mut Context<Self>,
 6292    ) -> Task<Result<bool>> {
 6293        let client = self.upstream_client();
 6294        let buffer_id = buffer.read(cx).remote_id();
 6295        let buffer_snapshot = buffer.read(cx).snapshot();
 6296
 6297        if !self.check_if_capable_for_proto_request(
 6298            &buffer,
 6299            GetCompletions::can_resolve_completions,
 6300            cx,
 6301        ) {
 6302            return Task::ready(Ok(false));
 6303        }
 6304        cx.spawn(async move |lsp_store, cx| {
 6305            let request_timeout = cx.update(|app| {
 6306                ProjectSettings::get_global(app)
 6307                    .global_lsp_settings
 6308                    .get_request_timeout()
 6309            });
 6310
 6311            let mut did_resolve = false;
 6312            if let Some((client, project_id)) = client {
 6313                for completion_index in completion_indices {
 6314                    let server_id = {
 6315                        let completion = &completions.borrow()[completion_index];
 6316                        completion.source.server_id()
 6317                    };
 6318                    if let Some(server_id) = server_id {
 6319                        if Self::resolve_completion_remote(
 6320                            project_id,
 6321                            server_id,
 6322                            buffer_id,
 6323                            completions.clone(),
 6324                            completion_index,
 6325                            client.clone(),
 6326                        )
 6327                        .await
 6328                        .log_err()
 6329                        .is_some()
 6330                        {
 6331                            did_resolve = true;
 6332                        }
 6333                    } else {
 6334                        resolve_word_completion(
 6335                            &buffer_snapshot,
 6336                            &mut completions.borrow_mut()[completion_index],
 6337                        );
 6338                    }
 6339                }
 6340            } else {
 6341                for completion_index in completion_indices {
 6342                    let server_id = {
 6343                        let completion = &completions.borrow()[completion_index];
 6344                        completion.source.server_id()
 6345                    };
 6346                    if let Some(server_id) = server_id {
 6347                        let server_and_adapter = lsp_store
 6348                            .read_with(cx, |lsp_store, _| {
 6349                                let server = lsp_store.language_server_for_id(server_id)?;
 6350                                let adapter =
 6351                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6352                                Some((server, adapter))
 6353                            })
 6354                            .ok()
 6355                            .flatten();
 6356                        let Some((server, adapter)) = server_and_adapter else {
 6357                            continue;
 6358                        };
 6359
 6360                        let resolved = Self::resolve_completion_local(
 6361                            server,
 6362                            completions.clone(),
 6363                            completion_index,
 6364                            request_timeout,
 6365                        )
 6366                        .await
 6367                        .log_err()
 6368                        .is_some();
 6369                        if resolved {
 6370                            Self::regenerate_completion_labels(
 6371                                adapter,
 6372                                &buffer_snapshot,
 6373                                completions.clone(),
 6374                                completion_index,
 6375                            )
 6376                            .await
 6377                            .log_err();
 6378                            did_resolve = true;
 6379                        }
 6380                    } else {
 6381                        resolve_word_completion(
 6382                            &buffer_snapshot,
 6383                            &mut completions.borrow_mut()[completion_index],
 6384                        );
 6385                    }
 6386                }
 6387            }
 6388
 6389            Ok(did_resolve)
 6390        })
 6391    }
 6392
 6393    async fn resolve_completion_local(
 6394        server: Arc<lsp::LanguageServer>,
 6395        completions: Rc<RefCell<Box<[Completion]>>>,
 6396        completion_index: usize,
 6397        request_timeout: Duration,
 6398    ) -> Result<()> {
 6399        let server_id = server.server_id();
 6400        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6401            return Ok(());
 6402        }
 6403
 6404        let request = {
 6405            let completion = &completions.borrow()[completion_index];
 6406            match &completion.source {
 6407                CompletionSource::Lsp {
 6408                    lsp_completion,
 6409                    resolved,
 6410                    server_id: completion_server_id,
 6411                    ..
 6412                } => {
 6413                    if *resolved {
 6414                        return Ok(());
 6415                    }
 6416                    anyhow::ensure!(
 6417                        server_id == *completion_server_id,
 6418                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6419                    );
 6420                    server.request::<lsp::request::ResolveCompletionItem>(
 6421                        *lsp_completion.clone(),
 6422                        request_timeout,
 6423                    )
 6424                }
 6425                CompletionSource::BufferWord { .. }
 6426                | CompletionSource::Dap { .. }
 6427                | CompletionSource::Custom => {
 6428                    return Ok(());
 6429                }
 6430            }
 6431        };
 6432        let resolved_completion = request
 6433            .await
 6434            .into_response()
 6435            .context("resolve completion")?;
 6436
 6437        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6438        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6439
 6440        let mut completions = completions.borrow_mut();
 6441        let completion = &mut completions[completion_index];
 6442        if let CompletionSource::Lsp {
 6443            lsp_completion,
 6444            resolved,
 6445            server_id: completion_server_id,
 6446            ..
 6447        } = &mut completion.source
 6448        {
 6449            if *resolved {
 6450                return Ok(());
 6451            }
 6452            anyhow::ensure!(
 6453                server_id == *completion_server_id,
 6454                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6455            );
 6456            **lsp_completion = resolved_completion;
 6457            *resolved = true;
 6458        }
 6459        Ok(())
 6460    }
 6461
 6462    async fn regenerate_completion_labels(
 6463        adapter: Arc<CachedLspAdapter>,
 6464        snapshot: &BufferSnapshot,
 6465        completions: Rc<RefCell<Box<[Completion]>>>,
 6466        completion_index: usize,
 6467    ) -> Result<()> {
 6468        let completion_item = completions.borrow()[completion_index]
 6469            .source
 6470            .lsp_completion(true)
 6471            .map(Cow::into_owned);
 6472        if let Some(lsp_documentation) = completion_item
 6473            .as_ref()
 6474            .and_then(|completion_item| completion_item.documentation.clone())
 6475        {
 6476            let mut completions = completions.borrow_mut();
 6477            let completion = &mut completions[completion_index];
 6478            completion.documentation = Some(lsp_documentation.into());
 6479        } else {
 6480            let mut completions = completions.borrow_mut();
 6481            let completion = &mut completions[completion_index];
 6482            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6483        }
 6484
 6485        let mut new_label = match completion_item {
 6486            Some(completion_item) => {
 6487                // Some language servers always return `detail` lazily via resolve, regardless of
 6488                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6489                // See: https://github.com/yioneko/vtsls/issues/213
 6490                let language = snapshot.language();
 6491                match language {
 6492                    Some(language) => {
 6493                        adapter
 6494                            .labels_for_completions(
 6495                                std::slice::from_ref(&completion_item),
 6496                                language,
 6497                            )
 6498                            .await?
 6499                    }
 6500                    None => Vec::new(),
 6501                }
 6502                .pop()
 6503                .flatten()
 6504                .unwrap_or_else(|| {
 6505                    CodeLabel::fallback_for_completion(
 6506                        &completion_item,
 6507                        language.map(|language| language.as_ref()),
 6508                    )
 6509                })
 6510            }
 6511            None => CodeLabel::plain(
 6512                completions.borrow()[completion_index].new_text.clone(),
 6513                None,
 6514            ),
 6515        };
 6516        ensure_uniform_list_compatible_label(&mut new_label);
 6517
 6518        let mut completions = completions.borrow_mut();
 6519        let completion = &mut completions[completion_index];
 6520        if completion.label.filter_text() == new_label.filter_text() {
 6521            completion.label = new_label;
 6522        } else {
 6523            log::error!(
 6524                "Resolved completion changed display label from {} to {}. \
 6525                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6526                completion.label.text(),
 6527                new_label.text(),
 6528                completion.label.filter_text(),
 6529                new_label.filter_text()
 6530            );
 6531        }
 6532
 6533        Ok(())
 6534    }
 6535
 6536    async fn resolve_completion_remote(
 6537        project_id: u64,
 6538        server_id: LanguageServerId,
 6539        buffer_id: BufferId,
 6540        completions: Rc<RefCell<Box<[Completion]>>>,
 6541        completion_index: usize,
 6542        client: AnyProtoClient,
 6543    ) -> Result<()> {
 6544        let lsp_completion = {
 6545            let completion = &completions.borrow()[completion_index];
 6546            match &completion.source {
 6547                CompletionSource::Lsp {
 6548                    lsp_completion,
 6549                    resolved,
 6550                    server_id: completion_server_id,
 6551                    ..
 6552                } => {
 6553                    anyhow::ensure!(
 6554                        server_id == *completion_server_id,
 6555                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6556                    );
 6557                    if *resolved {
 6558                        return Ok(());
 6559                    }
 6560                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6561                }
 6562                CompletionSource::Custom
 6563                | CompletionSource::Dap { .. }
 6564                | CompletionSource::BufferWord { .. } => {
 6565                    return Ok(());
 6566                }
 6567            }
 6568        };
 6569        let request = proto::ResolveCompletionDocumentation {
 6570            project_id,
 6571            language_server_id: server_id.0 as u64,
 6572            lsp_completion,
 6573            buffer_id: buffer_id.into(),
 6574        };
 6575
 6576        let response = client
 6577            .request(request)
 6578            .await
 6579            .context("completion documentation resolve proto request")?;
 6580        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6581
 6582        let documentation = if response.documentation.is_empty() {
 6583            CompletionDocumentation::Undocumented
 6584        } else if response.documentation_is_markdown {
 6585            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6586        } else if response.documentation.lines().count() <= 1 {
 6587            CompletionDocumentation::SingleLine(response.documentation.into())
 6588        } else {
 6589            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6590        };
 6591
 6592        let mut completions = completions.borrow_mut();
 6593        let completion = &mut completions[completion_index];
 6594        completion.documentation = Some(documentation);
 6595        if let CompletionSource::Lsp {
 6596            insert_range,
 6597            lsp_completion,
 6598            resolved,
 6599            server_id: completion_server_id,
 6600            lsp_defaults: _,
 6601        } = &mut completion.source
 6602        {
 6603            let completion_insert_range = response
 6604                .old_insert_start
 6605                .and_then(deserialize_anchor)
 6606                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6607            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6608
 6609            if *resolved {
 6610                return Ok(());
 6611            }
 6612            anyhow::ensure!(
 6613                server_id == *completion_server_id,
 6614                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6615            );
 6616            **lsp_completion = resolved_lsp_completion;
 6617            *resolved = true;
 6618        }
 6619
 6620        let replace_range = response
 6621            .old_replace_start
 6622            .and_then(deserialize_anchor)
 6623            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6624        if let Some((old_replace_start, old_replace_end)) = replace_range
 6625            && !response.new_text.is_empty()
 6626        {
 6627            completion.new_text = response.new_text;
 6628            completion.replace_range = old_replace_start..old_replace_end;
 6629        }
 6630
 6631        Ok(())
 6632    }
 6633
 6634    pub fn apply_additional_edits_for_completion(
 6635        &self,
 6636        buffer_handle: Entity<Buffer>,
 6637        completions: Rc<RefCell<Box<[Completion]>>>,
 6638        completion_index: usize,
 6639        push_to_history: bool,
 6640        cx: &mut Context<Self>,
 6641    ) -> Task<Result<Option<Transaction>>> {
 6642        if let Some((client, project_id)) = self.upstream_client() {
 6643            let buffer = buffer_handle.read(cx);
 6644            let buffer_id = buffer.remote_id();
 6645            cx.spawn(async move |_, cx| {
 6646                let request = {
 6647                    let completion = completions.borrow()[completion_index].clone();
 6648                    proto::ApplyCompletionAdditionalEdits {
 6649                        project_id,
 6650                        buffer_id: buffer_id.into(),
 6651                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6652                            replace_range: completion.replace_range,
 6653                            new_text: completion.new_text,
 6654                            source: completion.source,
 6655                        })),
 6656                    }
 6657                };
 6658
 6659                let Some(transaction) = client.request(request).await?.transaction else {
 6660                    return Ok(None);
 6661                };
 6662
 6663                let transaction = language::proto::deserialize_transaction(transaction)?;
 6664                buffer_handle
 6665                    .update(cx, |buffer, _| {
 6666                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6667                    })
 6668                    .await?;
 6669                if push_to_history {
 6670                    buffer_handle.update(cx, |buffer, _| {
 6671                        buffer.push_transaction(transaction.clone(), Instant::now());
 6672                        buffer.finalize_last_transaction();
 6673                    });
 6674                }
 6675                Ok(Some(transaction))
 6676            })
 6677        } else {
 6678            let request_timeout = ProjectSettings::get_global(cx)
 6679                .global_lsp_settings
 6680                .get_request_timeout();
 6681
 6682            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6683                let completion = &completions.borrow()[completion_index];
 6684                let server_id = completion.source.server_id()?;
 6685                Some(
 6686                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6687                        .1
 6688                        .clone(),
 6689                )
 6690            }) else {
 6691                return Task::ready(Ok(None));
 6692            };
 6693
 6694            cx.spawn(async move |this, cx| {
 6695                Self::resolve_completion_local(
 6696                    server.clone(),
 6697                    completions.clone(),
 6698                    completion_index,
 6699                    request_timeout,
 6700                )
 6701                .await
 6702                .context("resolving completion")?;
 6703                let completion = completions.borrow()[completion_index].clone();
 6704                let additional_text_edits = completion
 6705                    .source
 6706                    .lsp_completion(true)
 6707                    .as_ref()
 6708                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6709                if let Some(edits) = additional_text_edits {
 6710                    let edits = this
 6711                        .update(cx, |this, cx| {
 6712                            this.as_local_mut().unwrap().edits_from_lsp(
 6713                                &buffer_handle,
 6714                                edits,
 6715                                server.server_id(),
 6716                                None,
 6717                                cx,
 6718                            )
 6719                        })?
 6720                        .await?;
 6721
 6722                    buffer_handle.update(cx, |buffer, cx| {
 6723                        buffer.finalize_last_transaction();
 6724                        buffer.start_transaction();
 6725
 6726                        for (range, text) in edits {
 6727                            let primary = &completion.replace_range;
 6728
 6729                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6730                            // and the primary completion is just an insertion (empty range), then this is likely
 6731                            // an auto-import scenario and should not be considered overlapping
 6732                            // https://github.com/zed-industries/zed/issues/26136
 6733                            let is_file_start_auto_import = {
 6734                                let snapshot = buffer.snapshot();
 6735                                let primary_start_point = primary.start.to_point(&snapshot);
 6736                                let range_start_point = range.start.to_point(&snapshot);
 6737
 6738                                let result = primary_start_point.row == 0
 6739                                    && primary_start_point.column == 0
 6740                                    && range_start_point.row == 0
 6741                                    && range_start_point.column == 0;
 6742
 6743                                result
 6744                            };
 6745
 6746                            let has_overlap = if is_file_start_auto_import {
 6747                                false
 6748                            } else {
 6749                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6750                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6751                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6752                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6753                                let result = start_within || end_within;
 6754                                result
 6755                            };
 6756
 6757                            //Skip additional edits which overlap with the primary completion edit
 6758                            //https://github.com/zed-industries/zed/pull/1871
 6759                            if !has_overlap {
 6760                                buffer.edit([(range, text)], None, cx);
 6761                            }
 6762                        }
 6763
 6764                        let transaction = if buffer.end_transaction(cx).is_some() {
 6765                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6766                            if !push_to_history {
 6767                                buffer.forget_transaction(transaction.id);
 6768                            }
 6769                            Some(transaction)
 6770                        } else {
 6771                            None
 6772                        };
 6773                        Ok(transaction)
 6774                    })
 6775                } else {
 6776                    Ok(None)
 6777                }
 6778            })
 6779        }
 6780    }
 6781
 6782    pub fn pull_diagnostics(
 6783        &mut self,
 6784        buffer: Entity<Buffer>,
 6785        cx: &mut Context<Self>,
 6786    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6787        let buffer_id = buffer.read(cx).remote_id();
 6788
 6789        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6790            let mut suitable_capabilities = None;
 6791            // Are we capable for proto request?
 6792            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6793                &buffer,
 6794                |capabilities| {
 6795                    if let Some(caps) = &capabilities.diagnostic_provider {
 6796                        suitable_capabilities = Some(caps.clone());
 6797                        true
 6798                    } else {
 6799                        false
 6800                    }
 6801                },
 6802                cx,
 6803            );
 6804            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6805            let Some(dynamic_caps) = suitable_capabilities else {
 6806                return Task::ready(Ok(None));
 6807            };
 6808            assert!(any_server_has_diagnostics_provider);
 6809
 6810            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6811            let request = GetDocumentDiagnostics {
 6812                previous_result_id: None,
 6813                identifier,
 6814                registration_id: None,
 6815            };
 6816            let request_timeout = ProjectSettings::get_global(cx)
 6817                .global_lsp_settings
 6818                .get_request_timeout();
 6819            let request_task = client.request_lsp(
 6820                upstream_project_id,
 6821                None,
 6822                request_timeout,
 6823                cx.background_executor().clone(),
 6824                request.to_proto(upstream_project_id, buffer.read(cx)),
 6825            );
 6826            cx.background_spawn(async move {
 6827                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6828                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6829                // Do not attempt to further process the dummy responses here.
 6830                let _response = request_task.await?;
 6831                Ok(None)
 6832            })
 6833        } else {
 6834            let servers = buffer.update(cx, |buffer, cx| {
 6835                self.running_language_servers_for_local_buffer(buffer, cx)
 6836                    .map(|(_, server)| server.clone())
 6837                    .collect::<Vec<_>>()
 6838            });
 6839
 6840            let pull_diagnostics = servers
 6841                .into_iter()
 6842                .flat_map(|server| {
 6843                    let result = maybe!({
 6844                        let local = self.as_local()?;
 6845                        let server_id = server.server_id();
 6846                        let providers_with_identifiers = local
 6847                            .language_server_dynamic_registrations
 6848                            .get(&server_id)
 6849                            .into_iter()
 6850                            .flat_map(|registrations| registrations.diagnostics.clone())
 6851                            .collect::<Vec<_>>();
 6852                        Some(
 6853                            providers_with_identifiers
 6854                                .into_iter()
 6855                                .map(|(registration_id, dynamic_caps)| {
 6856                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6857                                    let registration_id = registration_id.map(SharedString::from);
 6858                                    let result_id = self.result_id_for_buffer_pull(
 6859                                        server_id,
 6860                                        buffer_id,
 6861                                        &registration_id,
 6862                                        cx,
 6863                                    );
 6864                                    self.request_lsp(
 6865                                        buffer.clone(),
 6866                                        LanguageServerToQuery::Other(server_id),
 6867                                        GetDocumentDiagnostics {
 6868                                            previous_result_id: result_id,
 6869                                            registration_id,
 6870                                            identifier,
 6871                                        },
 6872                                        cx,
 6873                                    )
 6874                                })
 6875                                .collect::<Vec<_>>(),
 6876                        )
 6877                    });
 6878
 6879                    result.unwrap_or_default()
 6880                })
 6881                .collect::<Vec<_>>();
 6882
 6883            cx.background_spawn(async move {
 6884                let mut responses = Vec::new();
 6885                for diagnostics in join_all(pull_diagnostics).await {
 6886                    responses.extend(diagnostics?);
 6887                }
 6888                Ok(Some(responses))
 6889            })
 6890        }
 6891    }
 6892
 6893    pub fn applicable_inlay_chunks(
 6894        &mut self,
 6895        buffer: &Entity<Buffer>,
 6896        ranges: &[Range<text::Anchor>],
 6897        cx: &mut Context<Self>,
 6898    ) -> Vec<Range<BufferRow>> {
 6899        let buffer_snapshot = buffer.read(cx).snapshot();
 6900        let ranges = ranges
 6901            .iter()
 6902            .map(|range| range.to_point(&buffer_snapshot))
 6903            .collect::<Vec<_>>();
 6904
 6905        self.latest_lsp_data(buffer, cx)
 6906            .inlay_hints
 6907            .applicable_chunks(ranges.as_slice())
 6908            .map(|chunk| chunk.row_range())
 6909            .collect()
 6910    }
 6911
 6912    pub fn invalidate_inlay_hints<'a>(
 6913        &'a mut self,
 6914        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6915    ) {
 6916        for buffer_id in for_buffers {
 6917            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6918                lsp_data.inlay_hints.clear();
 6919            }
 6920        }
 6921    }
 6922
 6923    pub fn inlay_hints(
 6924        &mut self,
 6925        invalidate: InvalidationStrategy,
 6926        buffer: Entity<Buffer>,
 6927        ranges: Vec<Range<text::Anchor>>,
 6928        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6929        cx: &mut Context<Self>,
 6930    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6931        let next_hint_id = self.next_hint_id.clone();
 6932        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6933        let query_version = lsp_data.buffer_version.clone();
 6934        let mut lsp_refresh_requested = false;
 6935        let for_server = if let InvalidationStrategy::RefreshRequested {
 6936            server_id,
 6937            request_id,
 6938        } = invalidate
 6939        {
 6940            let invalidated = lsp_data
 6941                .inlay_hints
 6942                .invalidate_for_server_refresh(server_id, request_id);
 6943            lsp_refresh_requested = invalidated;
 6944            Some(server_id)
 6945        } else {
 6946            None
 6947        };
 6948        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6949        let known_chunks = known_chunks
 6950            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6951            .map(|(_, known_chunks)| known_chunks)
 6952            .unwrap_or_default();
 6953
 6954        let buffer_snapshot = buffer.read(cx).snapshot();
 6955        let ranges = ranges
 6956            .iter()
 6957            .map(|range| range.to_point(&buffer_snapshot))
 6958            .collect::<Vec<_>>();
 6959
 6960        let mut hint_fetch_tasks = Vec::new();
 6961        let mut cached_inlay_hints = None;
 6962        let mut ranges_to_query = None;
 6963        let applicable_chunks = existing_inlay_hints
 6964            .applicable_chunks(ranges.as_slice())
 6965            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 6966            .collect::<Vec<_>>();
 6967        if applicable_chunks.is_empty() {
 6968            return HashMap::default();
 6969        }
 6970
 6971        for row_chunk in applicable_chunks {
 6972            match (
 6973                existing_inlay_hints
 6974                    .cached_hints(&row_chunk)
 6975                    .filter(|_| !lsp_refresh_requested)
 6976                    .cloned(),
 6977                existing_inlay_hints
 6978                    .fetched_hints(&row_chunk)
 6979                    .as_ref()
 6980                    .filter(|_| !lsp_refresh_requested)
 6981                    .cloned(),
 6982            ) {
 6983                (None, None) => {
 6984                    let chunk_range = row_chunk.anchor_range();
 6985                    ranges_to_query
 6986                        .get_or_insert_with(Vec::new)
 6987                        .push((row_chunk, chunk_range));
 6988                }
 6989                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 6990                (Some(cached_hints), None) => {
 6991                    for (server_id, cached_hints) in cached_hints {
 6992                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6993                            cached_inlay_hints
 6994                                .get_or_insert_with(HashMap::default)
 6995                                .entry(row_chunk.row_range())
 6996                                .or_insert_with(HashMap::default)
 6997                                .entry(server_id)
 6998                                .or_insert_with(Vec::new)
 6999                                .extend(cached_hints);
 7000                        }
 7001                    }
 7002                }
 7003                (Some(cached_hints), Some(fetched_hints)) => {
 7004                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7005                    for (server_id, cached_hints) in cached_hints {
 7006                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7007                            cached_inlay_hints
 7008                                .get_or_insert_with(HashMap::default)
 7009                                .entry(row_chunk.row_range())
 7010                                .or_insert_with(HashMap::default)
 7011                                .entry(server_id)
 7012                                .or_insert_with(Vec::new)
 7013                                .extend(cached_hints);
 7014                        }
 7015                    }
 7016                }
 7017            }
 7018        }
 7019
 7020        if hint_fetch_tasks.is_empty()
 7021            && ranges_to_query
 7022                .as_ref()
 7023                .is_none_or(|ranges| ranges.is_empty())
 7024            && let Some(cached_inlay_hints) = cached_inlay_hints
 7025        {
 7026            cached_inlay_hints
 7027                .into_iter()
 7028                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7029                .collect()
 7030        } else {
 7031            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7032                let next_hint_id = next_hint_id.clone();
 7033                let buffer = buffer.clone();
 7034                let query_version = query_version.clone();
 7035                let new_inlay_hints = cx
 7036                    .spawn(async move |lsp_store, cx| {
 7037                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7038                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7039                        })?;
 7040                        new_fetch_task
 7041                            .await
 7042                            .and_then(|new_hints_by_server| {
 7043                                lsp_store.update(cx, |lsp_store, cx| {
 7044                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7045                                    let update_cache = lsp_data.buffer_version == query_version;
 7046                                    if new_hints_by_server.is_empty() {
 7047                                        if update_cache {
 7048                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7049                                        }
 7050                                        HashMap::default()
 7051                                    } else {
 7052                                        new_hints_by_server
 7053                                            .into_iter()
 7054                                            .map(|(server_id, new_hints)| {
 7055                                                let new_hints = new_hints
 7056                                                    .into_iter()
 7057                                                    .map(|new_hint| {
 7058                                                        (
 7059                                                            InlayId::Hint(next_hint_id.fetch_add(
 7060                                                                1,
 7061                                                                atomic::Ordering::AcqRel,
 7062                                                            )),
 7063                                                            new_hint,
 7064                                                        )
 7065                                                    })
 7066                                                    .collect::<Vec<_>>();
 7067                                                if update_cache {
 7068                                                    lsp_data.inlay_hints.insert_new_hints(
 7069                                                        chunk,
 7070                                                        server_id,
 7071                                                        new_hints.clone(),
 7072                                                    );
 7073                                                }
 7074                                                (server_id, new_hints)
 7075                                            })
 7076                                            .collect()
 7077                                    }
 7078                                })
 7079                            })
 7080                            .map_err(Arc::new)
 7081                    })
 7082                    .shared();
 7083
 7084                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7085                *fetch_task = Some(new_inlay_hints.clone());
 7086                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7087            }
 7088
 7089            cached_inlay_hints
 7090                .unwrap_or_default()
 7091                .into_iter()
 7092                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7093                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7094                    (
 7095                        chunk.row_range(),
 7096                        cx.spawn(async move |_, _| {
 7097                            hints_fetch.await.map_err(|e| {
 7098                                if e.error_code() != ErrorCode::Internal {
 7099                                    anyhow!(e.error_code())
 7100                                } else {
 7101                                    anyhow!("{e:#}")
 7102                                }
 7103                            })
 7104                        }),
 7105                    )
 7106                }))
 7107                .collect()
 7108        }
 7109    }
 7110
 7111    fn fetch_inlay_hints(
 7112        &mut self,
 7113        for_server: Option<LanguageServerId>,
 7114        buffer: &Entity<Buffer>,
 7115        range: Range<Anchor>,
 7116        cx: &mut Context<Self>,
 7117    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7118        let request = InlayHints {
 7119            range: range.clone(),
 7120        };
 7121        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7122            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7123                return Task::ready(Ok(HashMap::default()));
 7124            }
 7125            let request_timeout = ProjectSettings::get_global(cx)
 7126                .global_lsp_settings
 7127                .get_request_timeout();
 7128            let request_task = upstream_client.request_lsp(
 7129                project_id,
 7130                for_server.map(|id| id.to_proto()),
 7131                request_timeout,
 7132                cx.background_executor().clone(),
 7133                request.to_proto(project_id, buffer.read(cx)),
 7134            );
 7135            let buffer = buffer.clone();
 7136            cx.spawn(async move |weak_lsp_store, cx| {
 7137                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7138                    return Ok(HashMap::default());
 7139                };
 7140                let Some(responses) = request_task.await? else {
 7141                    return Ok(HashMap::default());
 7142                };
 7143
 7144                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7145                    let lsp_store = lsp_store.clone();
 7146                    let buffer = buffer.clone();
 7147                    let cx = cx.clone();
 7148                    let request = request.clone();
 7149                    async move {
 7150                        (
 7151                            LanguageServerId::from_proto(response.server_id),
 7152                            request
 7153                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7154                                .await,
 7155                        )
 7156                    }
 7157                }))
 7158                .await;
 7159
 7160                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7161                let mut has_errors = false;
 7162                let inlay_hints = inlay_hints
 7163                    .into_iter()
 7164                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7165                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7166                        Err(e) => {
 7167                            has_errors = true;
 7168                            log::error!("{e:#}");
 7169                            None
 7170                        }
 7171                    })
 7172                    .map(|(server_id, mut new_hints)| {
 7173                        new_hints.retain(|hint| {
 7174                            hint.position.is_valid(&buffer_snapshot)
 7175                                && range.start.is_valid(&buffer_snapshot)
 7176                                && range.end.is_valid(&buffer_snapshot)
 7177                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7178                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7179                        });
 7180                        (server_id, new_hints)
 7181                    })
 7182                    .collect::<HashMap<_, _>>();
 7183                anyhow::ensure!(
 7184                    !has_errors || !inlay_hints.is_empty(),
 7185                    "Failed to fetch inlay hints"
 7186                );
 7187                Ok(inlay_hints)
 7188            })
 7189        } else {
 7190            let inlay_hints_task = match for_server {
 7191                Some(server_id) => {
 7192                    let server_task = self.request_lsp(
 7193                        buffer.clone(),
 7194                        LanguageServerToQuery::Other(server_id),
 7195                        request,
 7196                        cx,
 7197                    );
 7198                    cx.background_spawn(async move {
 7199                        let mut responses = Vec::new();
 7200                        match server_task.await {
 7201                            Ok(response) => responses.push((server_id, response)),
 7202                            // rust-analyzer likes to error with this when its still loading up
 7203                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7204                            Err(e) => log::error!(
 7205                                "Error handling response for inlay hints request: {e:#}"
 7206                            ),
 7207                        }
 7208                        responses
 7209                    })
 7210                }
 7211                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7212            };
 7213            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7214            cx.background_spawn(async move {
 7215                Ok(inlay_hints_task
 7216                    .await
 7217                    .into_iter()
 7218                    .map(|(server_id, mut new_hints)| {
 7219                        new_hints.retain(|hint| {
 7220                            hint.position.is_valid(&buffer_snapshot)
 7221                                && range.start.is_valid(&buffer_snapshot)
 7222                                && range.end.is_valid(&buffer_snapshot)
 7223                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7224                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7225                        });
 7226                        (server_id, new_hints)
 7227                    })
 7228                    .collect())
 7229            })
 7230        }
 7231    }
 7232
 7233    fn diagnostic_registration_exists(
 7234        &self,
 7235        server_id: LanguageServerId,
 7236        registration_id: &Option<SharedString>,
 7237    ) -> bool {
 7238        let Some(local) = self.as_local() else {
 7239            return false;
 7240        };
 7241        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7242        else {
 7243            return false;
 7244        };
 7245        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7246        registrations.diagnostics.contains_key(&registration_key)
 7247    }
 7248
 7249    pub fn pull_diagnostics_for_buffer(
 7250        &mut self,
 7251        buffer: Entity<Buffer>,
 7252        cx: &mut Context<Self>,
 7253    ) -> Task<anyhow::Result<()>> {
 7254        let diagnostics = self.pull_diagnostics(buffer, cx);
 7255        cx.spawn(async move |lsp_store, cx| {
 7256            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7257                return Ok(());
 7258            };
 7259            lsp_store.update(cx, |lsp_store, cx| {
 7260                if lsp_store.as_local().is_none() {
 7261                    return;
 7262                }
 7263
 7264                let mut unchanged_buffers = HashMap::default();
 7265                let server_diagnostics_updates = diagnostics
 7266                    .into_iter()
 7267                    .filter_map(|diagnostics_set| match diagnostics_set {
 7268                        LspPullDiagnostics::Response {
 7269                            server_id,
 7270                            uri,
 7271                            diagnostics,
 7272                            registration_id,
 7273                        } => Some((server_id, uri, diagnostics, registration_id)),
 7274                        LspPullDiagnostics::Default => None,
 7275                    })
 7276                    .filter(|(server_id, _, _, registration_id)| {
 7277                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7278                    })
 7279                    .fold(
 7280                        HashMap::default(),
 7281                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7282                            let (result_id, diagnostics) = match diagnostics {
 7283                                PulledDiagnostics::Unchanged { result_id } => {
 7284                                    unchanged_buffers
 7285                                        .entry(new_registration_id.clone())
 7286                                        .or_insert_with(HashSet::default)
 7287                                        .insert(uri.clone());
 7288                                    (Some(result_id), Vec::new())
 7289                                }
 7290                                PulledDiagnostics::Changed {
 7291                                    result_id,
 7292                                    diagnostics,
 7293                                } => (result_id, diagnostics),
 7294                            };
 7295                            let disk_based_sources = Cow::Owned(
 7296                                lsp_store
 7297                                    .language_server_adapter_for_id(server_id)
 7298                                    .as_ref()
 7299                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7300                                    .unwrap_or(&[])
 7301                                    .to_vec(),
 7302                            );
 7303                            acc.entry(server_id)
 7304                                .or_insert_with(HashMap::default)
 7305                                .entry(new_registration_id.clone())
 7306                                .or_insert_with(Vec::new)
 7307                                .push(DocumentDiagnosticsUpdate {
 7308                                    server_id,
 7309                                    diagnostics: lsp::PublishDiagnosticsParams {
 7310                                        uri,
 7311                                        diagnostics,
 7312                                        version: None,
 7313                                    },
 7314                                    result_id: result_id.map(SharedString::new),
 7315                                    disk_based_sources,
 7316                                    registration_id: new_registration_id,
 7317                                });
 7318                            acc
 7319                        },
 7320                    );
 7321
 7322                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7323                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7324                        lsp_store
 7325                            .merge_lsp_diagnostics(
 7326                                DiagnosticSourceKind::Pulled,
 7327                                diagnostic_updates,
 7328                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7329                                    DiagnosticSourceKind::Pulled => {
 7330                                        old_diagnostic.registration_id != registration_id
 7331                                            || unchanged_buffers
 7332                                                .get(&old_diagnostic.registration_id)
 7333                                                .is_some_and(|unchanged_buffers| {
 7334                                                    unchanged_buffers.contains(&document_uri)
 7335                                                })
 7336                                    }
 7337                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7338                                        true
 7339                                    }
 7340                                },
 7341                                cx,
 7342                            )
 7343                            .log_err();
 7344                    }
 7345                }
 7346            })
 7347        })
 7348    }
 7349
 7350    pub fn signature_help<T: ToPointUtf16>(
 7351        &mut self,
 7352        buffer: &Entity<Buffer>,
 7353        position: T,
 7354        cx: &mut Context<Self>,
 7355    ) -> Task<Option<Vec<SignatureHelp>>> {
 7356        let position = position.to_point_utf16(buffer.read(cx));
 7357
 7358        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7359            let request = GetSignatureHelp { position };
 7360            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7361                return Task::ready(None);
 7362            }
 7363            let request_timeout = ProjectSettings::get_global(cx)
 7364                .global_lsp_settings
 7365                .get_request_timeout();
 7366            let request_task = client.request_lsp(
 7367                upstream_project_id,
 7368                None,
 7369                request_timeout,
 7370                cx.background_executor().clone(),
 7371                request.to_proto(upstream_project_id, buffer.read(cx)),
 7372            );
 7373            let buffer = buffer.clone();
 7374            cx.spawn(async move |weak_lsp_store, cx| {
 7375                let lsp_store = weak_lsp_store.upgrade()?;
 7376                let signatures = join_all(
 7377                    request_task
 7378                        .await
 7379                        .log_err()
 7380                        .flatten()
 7381                        .map(|response| response.payload)
 7382                        .unwrap_or_default()
 7383                        .into_iter()
 7384                        .map(|response| {
 7385                            let response = GetSignatureHelp { position }.response_from_proto(
 7386                                response.response,
 7387                                lsp_store.clone(),
 7388                                buffer.clone(),
 7389                                cx.clone(),
 7390                            );
 7391                            async move { response.await.log_err().flatten() }
 7392                        }),
 7393                )
 7394                .await
 7395                .into_iter()
 7396                .flatten()
 7397                .collect();
 7398                Some(signatures)
 7399            })
 7400        } else {
 7401            let all_actions_task = self.request_multiple_lsp_locally(
 7402                buffer,
 7403                Some(position),
 7404                GetSignatureHelp { position },
 7405                cx,
 7406            );
 7407            cx.background_spawn(async move {
 7408                Some(
 7409                    all_actions_task
 7410                        .await
 7411                        .into_iter()
 7412                        .flat_map(|(_, actions)| actions)
 7413                        .collect::<Vec<_>>(),
 7414                )
 7415            })
 7416        }
 7417    }
 7418
 7419    pub fn hover(
 7420        &mut self,
 7421        buffer: &Entity<Buffer>,
 7422        position: PointUtf16,
 7423        cx: &mut Context<Self>,
 7424    ) -> Task<Option<Vec<Hover>>> {
 7425        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7426            let request = GetHover { position };
 7427            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7428                return Task::ready(None);
 7429            }
 7430            let request_timeout = ProjectSettings::get_global(cx)
 7431                .global_lsp_settings
 7432                .get_request_timeout();
 7433            let request_task = client.request_lsp(
 7434                upstream_project_id,
 7435                None,
 7436                request_timeout,
 7437                cx.background_executor().clone(),
 7438                request.to_proto(upstream_project_id, buffer.read(cx)),
 7439            );
 7440            let buffer = buffer.clone();
 7441            cx.spawn(async move |weak_lsp_store, cx| {
 7442                let lsp_store = weak_lsp_store.upgrade()?;
 7443                let hovers = join_all(
 7444                    request_task
 7445                        .await
 7446                        .log_err()
 7447                        .flatten()
 7448                        .map(|response| response.payload)
 7449                        .unwrap_or_default()
 7450                        .into_iter()
 7451                        .map(|response| {
 7452                            let response = GetHover { position }.response_from_proto(
 7453                                response.response,
 7454                                lsp_store.clone(),
 7455                                buffer.clone(),
 7456                                cx.clone(),
 7457                            );
 7458                            async move {
 7459                                response
 7460                                    .await
 7461                                    .log_err()
 7462                                    .flatten()
 7463                                    .and_then(remove_empty_hover_blocks)
 7464                            }
 7465                        }),
 7466                )
 7467                .await
 7468                .into_iter()
 7469                .flatten()
 7470                .collect();
 7471                Some(hovers)
 7472            })
 7473        } else {
 7474            let all_actions_task = self.request_multiple_lsp_locally(
 7475                buffer,
 7476                Some(position),
 7477                GetHover { position },
 7478                cx,
 7479            );
 7480            cx.background_spawn(async move {
 7481                Some(
 7482                    all_actions_task
 7483                        .await
 7484                        .into_iter()
 7485                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7486                        .collect::<Vec<Hover>>(),
 7487                )
 7488            })
 7489        }
 7490    }
 7491
 7492    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7493        let language_registry = self.languages.clone();
 7494
 7495        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7496            let request = upstream_client.request(proto::GetProjectSymbols {
 7497                project_id: *project_id,
 7498                query: query.to_string(),
 7499            });
 7500            cx.foreground_executor().spawn(async move {
 7501                let response = request.await?;
 7502                let mut symbols = Vec::new();
 7503                let core_symbols = response
 7504                    .symbols
 7505                    .into_iter()
 7506                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7507                    .collect::<Vec<_>>();
 7508                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7509                    .await;
 7510                Ok(symbols)
 7511            })
 7512        } else if let Some(local) = self.as_local() {
 7513            struct WorkspaceSymbolsResult {
 7514                server_id: LanguageServerId,
 7515                lsp_adapter: Arc<CachedLspAdapter>,
 7516                worktree: WeakEntity<Worktree>,
 7517                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7518            }
 7519
 7520            let mut requests = Vec::new();
 7521            let mut requested_servers = BTreeSet::new();
 7522            let request_timeout = ProjectSettings::get_global(cx)
 7523                .global_lsp_settings
 7524                .get_request_timeout();
 7525
 7526            for (seed, state) in local.language_server_ids.iter() {
 7527                let Some(worktree_handle) = self
 7528                    .worktree_store
 7529                    .read(cx)
 7530                    .worktree_for_id(seed.worktree_id, cx)
 7531                else {
 7532                    continue;
 7533                };
 7534
 7535                let worktree = worktree_handle.read(cx);
 7536                if !worktree.is_visible() {
 7537                    continue;
 7538                }
 7539
 7540                if !requested_servers.insert(state.id) {
 7541                    continue;
 7542                }
 7543
 7544                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7545                    Some(LanguageServerState::Running {
 7546                        adapter, server, ..
 7547                    }) => (adapter.clone(), server),
 7548
 7549                    _ => continue,
 7550                };
 7551
 7552                let supports_workspace_symbol_request =
 7553                    match server.capabilities().workspace_symbol_provider {
 7554                        Some(OneOf::Left(supported)) => supported,
 7555                        Some(OneOf::Right(_)) => true,
 7556                        None => false,
 7557                    };
 7558
 7559                if !supports_workspace_symbol_request {
 7560                    continue;
 7561                }
 7562
 7563                let worktree_handle = worktree_handle.clone();
 7564                let server_id = server.server_id();
 7565                requests.push(
 7566                    server
 7567                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7568                            lsp::WorkspaceSymbolParams {
 7569                                query: query.to_string(),
 7570                                ..Default::default()
 7571                            },
 7572                            request_timeout,
 7573                        )
 7574                        .map(move |response| {
 7575                            let lsp_symbols = response
 7576                                .into_response()
 7577                                .context("workspace symbols request")
 7578                                .log_err()
 7579                                .flatten()
 7580                                .map(|symbol_response| match symbol_response {
 7581                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7582                                        flat_responses
 7583                                            .into_iter()
 7584                                            .map(|lsp_symbol| {
 7585                                                (
 7586                                                    lsp_symbol.name,
 7587                                                    lsp_symbol.kind,
 7588                                                    lsp_symbol.location,
 7589                                                    lsp_symbol.container_name,
 7590                                                )
 7591                                            })
 7592                                            .collect::<Vec<_>>()
 7593                                    }
 7594                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7595                                        nested_responses
 7596                                            .into_iter()
 7597                                            .filter_map(|lsp_symbol| {
 7598                                                let location = match lsp_symbol.location {
 7599                                                    OneOf::Left(location) => location,
 7600                                                    OneOf::Right(_) => {
 7601                                                        log::error!(
 7602                                                            "Unexpected: client capabilities \
 7603                                                            forbid symbol resolutions in \
 7604                                                            workspace.symbol.resolveSupport"
 7605                                                        );
 7606                                                        return None;
 7607                                                    }
 7608                                                };
 7609                                                Some((
 7610                                                    lsp_symbol.name,
 7611                                                    lsp_symbol.kind,
 7612                                                    location,
 7613                                                    lsp_symbol.container_name,
 7614                                                ))
 7615                                            })
 7616                                            .collect::<Vec<_>>()
 7617                                    }
 7618                                })
 7619                                .unwrap_or_default();
 7620
 7621                            WorkspaceSymbolsResult {
 7622                                server_id,
 7623                                lsp_adapter,
 7624                                worktree: worktree_handle.downgrade(),
 7625                                lsp_symbols,
 7626                            }
 7627                        }),
 7628                );
 7629            }
 7630
 7631            cx.spawn(async move |this, cx| {
 7632                let responses = futures::future::join_all(requests).await;
 7633                let this = match this.upgrade() {
 7634                    Some(this) => this,
 7635                    None => return Ok(Vec::new()),
 7636                };
 7637
 7638                let mut symbols = Vec::new();
 7639                for result in responses {
 7640                    let core_symbols = this.update(cx, |this, cx| {
 7641                        result
 7642                            .lsp_symbols
 7643                            .into_iter()
 7644                            .filter_map(
 7645                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7646                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7647                                    let source_worktree = result.worktree.upgrade()?;
 7648                                    let source_worktree_id = source_worktree.read(cx).id();
 7649
 7650                                    let path = if let Some((tree, rel_path)) =
 7651                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7652                                    {
 7653                                        let worktree_id = tree.read(cx).id();
 7654                                        SymbolLocation::InProject(ProjectPath {
 7655                                            worktree_id,
 7656                                            path: rel_path,
 7657                                        })
 7658                                    } else {
 7659                                        SymbolLocation::OutsideProject {
 7660                                            signature: this.symbol_signature(&abs_path),
 7661                                            abs_path: abs_path.into(),
 7662                                        }
 7663                                    };
 7664
 7665                                    Some(CoreSymbol {
 7666                                        source_language_server_id: result.server_id,
 7667                                        language_server_name: result.lsp_adapter.name.clone(),
 7668                                        source_worktree_id,
 7669                                        path,
 7670                                        kind: symbol_kind,
 7671                                        name: symbol_name,
 7672                                        range: range_from_lsp(symbol_location.range),
 7673                                        container_name,
 7674                                    })
 7675                                },
 7676                            )
 7677                            .collect::<Vec<_>>()
 7678                    });
 7679
 7680                    populate_labels_for_symbols(
 7681                        core_symbols,
 7682                        &language_registry,
 7683                        Some(result.lsp_adapter),
 7684                        &mut symbols,
 7685                    )
 7686                    .await;
 7687                }
 7688
 7689                Ok(symbols)
 7690            })
 7691        } else {
 7692            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7693        }
 7694    }
 7695
 7696    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7697        let mut summary = DiagnosticSummary::default();
 7698        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7699            summary.error_count += path_summary.error_count;
 7700            summary.warning_count += path_summary.warning_count;
 7701        }
 7702        summary
 7703    }
 7704
 7705    /// Returns the diagnostic summary for a specific project path.
 7706    pub fn diagnostic_summary_for_path(
 7707        &self,
 7708        project_path: &ProjectPath,
 7709        _: &App,
 7710    ) -> DiagnosticSummary {
 7711        if let Some(summaries) = self
 7712            .diagnostic_summaries
 7713            .get(&project_path.worktree_id)
 7714            .and_then(|map| map.get(&project_path.path))
 7715        {
 7716            let (error_count, warning_count) = summaries.iter().fold(
 7717                (0, 0),
 7718                |(error_count, warning_count), (_language_server_id, summary)| {
 7719                    (
 7720                        error_count + summary.error_count,
 7721                        warning_count + summary.warning_count,
 7722                    )
 7723                },
 7724            );
 7725
 7726            DiagnosticSummary {
 7727                error_count,
 7728                warning_count,
 7729            }
 7730        } else {
 7731            DiagnosticSummary::default()
 7732        }
 7733    }
 7734
 7735    pub fn diagnostic_summaries<'a>(
 7736        &'a self,
 7737        include_ignored: bool,
 7738        cx: &'a App,
 7739    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7740        self.worktree_store
 7741            .read(cx)
 7742            .visible_worktrees(cx)
 7743            .filter_map(|worktree| {
 7744                let worktree = worktree.read(cx);
 7745                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7746            })
 7747            .flat_map(move |(worktree, summaries)| {
 7748                let worktree_id = worktree.id();
 7749                summaries
 7750                    .iter()
 7751                    .filter(move |(path, _)| {
 7752                        include_ignored
 7753                            || worktree
 7754                                .entry_for_path(path.as_ref())
 7755                                .is_some_and(|entry| !entry.is_ignored)
 7756                    })
 7757                    .flat_map(move |(path, summaries)| {
 7758                        summaries.iter().map(move |(server_id, summary)| {
 7759                            (
 7760                                ProjectPath {
 7761                                    worktree_id,
 7762                                    path: path.clone(),
 7763                                },
 7764                                *server_id,
 7765                                *summary,
 7766                            )
 7767                        })
 7768                    })
 7769            })
 7770    }
 7771
 7772    pub fn on_buffer_edited(
 7773        &mut self,
 7774        buffer: Entity<Buffer>,
 7775        cx: &mut Context<Self>,
 7776    ) -> Option<()> {
 7777        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7778            Some(
 7779                self.as_local()?
 7780                    .language_servers_for_buffer(buffer, cx)
 7781                    .map(|i| i.1.clone())
 7782                    .collect(),
 7783            )
 7784        })?;
 7785
 7786        let buffer = buffer.read(cx);
 7787        let file = File::from_dyn(buffer.file())?;
 7788        let abs_path = file.as_local()?.abs_path(cx);
 7789        let uri = lsp::Uri::from_file_path(&abs_path)
 7790            .ok()
 7791            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7792            .log_err()?;
 7793        let next_snapshot = buffer.text_snapshot();
 7794        for language_server in language_servers {
 7795            let language_server = language_server.clone();
 7796
 7797            let buffer_snapshots = self
 7798                .as_local_mut()?
 7799                .buffer_snapshots
 7800                .get_mut(&buffer.remote_id())
 7801                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7802            let previous_snapshot = buffer_snapshots.last()?;
 7803
 7804            let build_incremental_change = || {
 7805                buffer
 7806                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7807                        previous_snapshot.snapshot.version(),
 7808                    )
 7809                    .map(|edit| {
 7810                        let edit_start = edit.new.start.0;
 7811                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7812                        let new_text = next_snapshot
 7813                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7814                            .collect();
 7815                        lsp::TextDocumentContentChangeEvent {
 7816                            range: Some(lsp::Range::new(
 7817                                point_to_lsp(edit_start),
 7818                                point_to_lsp(edit_end),
 7819                            )),
 7820                            range_length: None,
 7821                            text: new_text,
 7822                        }
 7823                    })
 7824                    .collect()
 7825            };
 7826
 7827            let document_sync_kind = language_server
 7828                .capabilities()
 7829                .text_document_sync
 7830                .as_ref()
 7831                .and_then(|sync| match sync {
 7832                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7833                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7834                });
 7835
 7836            let content_changes: Vec<_> = match document_sync_kind {
 7837                Some(lsp::TextDocumentSyncKind::FULL) => {
 7838                    vec![lsp::TextDocumentContentChangeEvent {
 7839                        range: None,
 7840                        range_length: None,
 7841                        text: next_snapshot.text(),
 7842                    }]
 7843                }
 7844                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7845                _ => {
 7846                    #[cfg(any(test, feature = "test-support"))]
 7847                    {
 7848                        build_incremental_change()
 7849                    }
 7850
 7851                    #[cfg(not(any(test, feature = "test-support")))]
 7852                    {
 7853                        continue;
 7854                    }
 7855                }
 7856            };
 7857
 7858            let next_version = previous_snapshot.version + 1;
 7859            buffer_snapshots.push(LspBufferSnapshot {
 7860                version: next_version,
 7861                snapshot: next_snapshot.clone(),
 7862            });
 7863
 7864            language_server
 7865                .notify::<lsp::notification::DidChangeTextDocument>(
 7866                    lsp::DidChangeTextDocumentParams {
 7867                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7868                            uri.clone(),
 7869                            next_version,
 7870                        ),
 7871                        content_changes,
 7872                    },
 7873                )
 7874                .ok();
 7875            self.pull_workspace_diagnostics(language_server.server_id());
 7876        }
 7877
 7878        None
 7879    }
 7880
 7881    pub fn on_buffer_saved(
 7882        &mut self,
 7883        buffer: Entity<Buffer>,
 7884        cx: &mut Context<Self>,
 7885    ) -> Option<()> {
 7886        let file = File::from_dyn(buffer.read(cx).file())?;
 7887        let worktree_id = file.worktree_id(cx);
 7888        let abs_path = file.as_local()?.abs_path(cx);
 7889        let text_document = lsp::TextDocumentIdentifier {
 7890            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7891        };
 7892        let local = self.as_local()?;
 7893
 7894        for server in local.language_servers_for_worktree(worktree_id) {
 7895            if let Some(include_text) = include_text(server.as_ref()) {
 7896                let text = if include_text {
 7897                    Some(buffer.read(cx).text())
 7898                } else {
 7899                    None
 7900                };
 7901                server
 7902                    .notify::<lsp::notification::DidSaveTextDocument>(
 7903                        lsp::DidSaveTextDocumentParams {
 7904                            text_document: text_document.clone(),
 7905                            text,
 7906                        },
 7907                    )
 7908                    .ok();
 7909            }
 7910        }
 7911
 7912        let language_servers = buffer.update(cx, |buffer, cx| {
 7913            local.language_server_ids_for_buffer(buffer, cx)
 7914        });
 7915        for language_server_id in language_servers {
 7916            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7917        }
 7918
 7919        None
 7920    }
 7921
 7922    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7923        maybe!(async move {
 7924            let mut refreshed_servers = HashSet::default();
 7925            let servers = lsp_store
 7926                .update(cx, |lsp_store, cx| {
 7927                    let local = lsp_store.as_local()?;
 7928
 7929                    let servers = local
 7930                        .language_server_ids
 7931                        .iter()
 7932                        .filter_map(|(seed, state)| {
 7933                            let worktree = lsp_store
 7934                                .worktree_store
 7935                                .read(cx)
 7936                                .worktree_for_id(seed.worktree_id, cx);
 7937                            let delegate: Arc<dyn LspAdapterDelegate> =
 7938                                worktree.map(|worktree| {
 7939                                    LocalLspAdapterDelegate::new(
 7940                                        local.languages.clone(),
 7941                                        &local.environment,
 7942                                        cx.weak_entity(),
 7943                                        &worktree,
 7944                                        local.http_client.clone(),
 7945                                        local.fs.clone(),
 7946                                        cx,
 7947                                    )
 7948                                })?;
 7949                            let server_id = state.id;
 7950
 7951                            let states = local.language_servers.get(&server_id)?;
 7952
 7953                            match states {
 7954                                LanguageServerState::Starting { .. } => None,
 7955                                LanguageServerState::Running {
 7956                                    adapter, server, ..
 7957                                } => {
 7958                                    let adapter = adapter.clone();
 7959                                    let server = server.clone();
 7960                                    refreshed_servers.insert(server.name());
 7961                                    let toolchain = seed.toolchain.clone();
 7962                                    Some(cx.spawn(async move |_, cx| {
 7963                                        let settings =
 7964                                            LocalLspStore::workspace_configuration_for_adapter(
 7965                                                adapter.adapter.clone(),
 7966                                                &delegate,
 7967                                                toolchain,
 7968                                                None,
 7969                                                cx,
 7970                                            )
 7971                                            .await
 7972                                            .ok()?;
 7973                                        server
 7974                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7975                                                lsp::DidChangeConfigurationParams { settings },
 7976                                            )
 7977                                            .ok()?;
 7978                                        Some(())
 7979                                    }))
 7980                                }
 7981                            }
 7982                        })
 7983                        .collect::<Vec<_>>();
 7984
 7985                    Some(servers)
 7986                })
 7987                .ok()
 7988                .flatten()?;
 7989
 7990            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7991            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7992            // to stop and unregister its language server wrapper.
 7993            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7994            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7995            let _: Vec<Option<()>> = join_all(servers).await;
 7996
 7997            Some(())
 7998        })
 7999        .await;
 8000    }
 8001
 8002    fn maintain_workspace_config(
 8003        external_refresh_requests: watch::Receiver<()>,
 8004        cx: &mut Context<Self>,
 8005    ) -> Task<Result<()>> {
 8006        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8007        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8008
 8009        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8010            *settings_changed_tx.borrow_mut() = ();
 8011        });
 8012
 8013        let mut joint_future =
 8014            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8015        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8016        // - 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).
 8017        // - 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.
 8018        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8019        // - 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,
 8020        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8021        cx.spawn(async move |this, cx| {
 8022            while let Some(()) = joint_future.next().await {
 8023                this.update(cx, |this, cx| {
 8024                    this.refresh_server_tree(cx);
 8025                })
 8026                .ok();
 8027
 8028                Self::refresh_workspace_configurations(&this, cx).await;
 8029            }
 8030
 8031            drop(settings_observation);
 8032            anyhow::Ok(())
 8033        })
 8034    }
 8035
 8036    pub fn running_language_servers_for_local_buffer<'a>(
 8037        &'a self,
 8038        buffer: &Buffer,
 8039        cx: &mut App,
 8040    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8041        let local = self.as_local();
 8042        let language_server_ids = local
 8043            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8044            .unwrap_or_default();
 8045
 8046        language_server_ids
 8047            .into_iter()
 8048            .filter_map(
 8049                move |server_id| match local?.language_servers.get(&server_id)? {
 8050                    LanguageServerState::Running {
 8051                        adapter, server, ..
 8052                    } => Some((adapter, server)),
 8053                    _ => None,
 8054                },
 8055            )
 8056    }
 8057
 8058    pub fn language_servers_for_local_buffer(
 8059        &self,
 8060        buffer: &Buffer,
 8061        cx: &mut App,
 8062    ) -> Vec<LanguageServerId> {
 8063        let local = self.as_local();
 8064        local
 8065            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8066            .unwrap_or_default()
 8067    }
 8068
 8069    pub fn language_server_for_local_buffer<'a>(
 8070        &'a self,
 8071        buffer: &'a Buffer,
 8072        server_id: LanguageServerId,
 8073        cx: &'a mut App,
 8074    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8075        self.as_local()?
 8076            .language_servers_for_buffer(buffer, cx)
 8077            .find(|(_, s)| s.server_id() == server_id)
 8078    }
 8079
 8080    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8081        self.diagnostic_summaries.remove(&id_to_remove);
 8082        if let Some(local) = self.as_local_mut() {
 8083            let to_remove = local.remove_worktree(id_to_remove, cx);
 8084            for server in to_remove {
 8085                self.language_server_statuses.remove(&server);
 8086            }
 8087        }
 8088    }
 8089
 8090    pub fn shared(
 8091        &mut self,
 8092        project_id: u64,
 8093        downstream_client: AnyProtoClient,
 8094        _: &mut Context<Self>,
 8095    ) {
 8096        self.downstream_client = Some((downstream_client.clone(), project_id));
 8097
 8098        for (server_id, status) in &self.language_server_statuses {
 8099            if let Some(server) = self.language_server_for_id(*server_id) {
 8100                downstream_client
 8101                    .send(proto::StartLanguageServer {
 8102                        project_id,
 8103                        server: Some(proto::LanguageServer {
 8104                            id: server_id.to_proto(),
 8105                            name: status.name.to_string(),
 8106                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8107                        }),
 8108                        capabilities: serde_json::to_string(&server.capabilities())
 8109                            .expect("serializing server LSP capabilities"),
 8110                    })
 8111                    .log_err();
 8112            }
 8113        }
 8114    }
 8115
 8116    pub fn disconnected_from_host(&mut self) {
 8117        self.downstream_client.take();
 8118    }
 8119
 8120    pub fn disconnected_from_ssh_remote(&mut self) {
 8121        if let LspStoreMode::Remote(RemoteLspStore {
 8122            upstream_client, ..
 8123        }) = &mut self.mode
 8124        {
 8125            upstream_client.take();
 8126        }
 8127    }
 8128
 8129    pub(crate) fn set_language_server_statuses_from_proto(
 8130        &mut self,
 8131        project: WeakEntity<Project>,
 8132        language_servers: Vec<proto::LanguageServer>,
 8133        server_capabilities: Vec<String>,
 8134        cx: &mut Context<Self>,
 8135    ) {
 8136        let lsp_logs = cx
 8137            .try_global::<GlobalLogStore>()
 8138            .map(|lsp_store| lsp_store.0.clone());
 8139
 8140        self.language_server_statuses = language_servers
 8141            .into_iter()
 8142            .zip(server_capabilities)
 8143            .map(|(server, server_capabilities)| {
 8144                let server_id = LanguageServerId(server.id as usize);
 8145                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8146                    self.lsp_server_capabilities
 8147                        .insert(server_id, server_capabilities);
 8148                }
 8149
 8150                let name = LanguageServerName::from_proto(server.name);
 8151                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8152
 8153                if let Some(lsp_logs) = &lsp_logs {
 8154                    lsp_logs.update(cx, |lsp_logs, cx| {
 8155                        lsp_logs.add_language_server(
 8156                            // Only remote clients get their language servers set from proto
 8157                            LanguageServerKind::Remote {
 8158                                project: project.clone(),
 8159                            },
 8160                            server_id,
 8161                            Some(name.clone()),
 8162                            worktree,
 8163                            None,
 8164                            cx,
 8165                        );
 8166                    });
 8167                }
 8168
 8169                (
 8170                    server_id,
 8171                    LanguageServerStatus {
 8172                        name,
 8173                        server_version: None,
 8174                        pending_work: Default::default(),
 8175                        has_pending_diagnostic_updates: false,
 8176                        progress_tokens: Default::default(),
 8177                        worktree,
 8178                        binary: None,
 8179                        configuration: None,
 8180                        workspace_folders: BTreeSet::new(),
 8181                        process_id: None,
 8182                    },
 8183                )
 8184            })
 8185            .collect();
 8186    }
 8187
 8188    #[cfg(feature = "test-support")]
 8189    pub fn update_diagnostic_entries(
 8190        &mut self,
 8191        server_id: LanguageServerId,
 8192        abs_path: PathBuf,
 8193        result_id: Option<SharedString>,
 8194        version: Option<i32>,
 8195        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8196        cx: &mut Context<Self>,
 8197    ) -> anyhow::Result<()> {
 8198        self.merge_diagnostic_entries(
 8199            vec![DocumentDiagnosticsUpdate {
 8200                diagnostics: DocumentDiagnostics {
 8201                    diagnostics,
 8202                    document_abs_path: abs_path,
 8203                    version,
 8204                },
 8205                result_id,
 8206                server_id,
 8207                disk_based_sources: Cow::Borrowed(&[]),
 8208                registration_id: None,
 8209            }],
 8210            |_, _, _| false,
 8211            cx,
 8212        )?;
 8213        Ok(())
 8214    }
 8215
 8216    pub fn merge_diagnostic_entries<'a>(
 8217        &mut self,
 8218        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8219        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8220        cx: &mut Context<Self>,
 8221    ) -> anyhow::Result<()> {
 8222        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8223        let mut updated_diagnostics_paths = HashMap::default();
 8224        for mut update in diagnostic_updates {
 8225            let abs_path = &update.diagnostics.document_abs_path;
 8226            let server_id = update.server_id;
 8227            let Some((worktree, relative_path)) =
 8228                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8229            else {
 8230                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8231                return Ok(());
 8232            };
 8233
 8234            let worktree_id = worktree.read(cx).id();
 8235            let project_path = ProjectPath {
 8236                worktree_id,
 8237                path: relative_path,
 8238            };
 8239
 8240            let document_uri = lsp::Uri::from_file_path(abs_path)
 8241                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8242            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8243                let snapshot = buffer_handle.read(cx).snapshot();
 8244                let buffer = buffer_handle.read(cx);
 8245                let reused_diagnostics = buffer
 8246                    .buffer_diagnostics(Some(server_id))
 8247                    .iter()
 8248                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8249                    .map(|v| {
 8250                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8251                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8252                        DiagnosticEntry {
 8253                            range: start..end,
 8254                            diagnostic: v.diagnostic.clone(),
 8255                        }
 8256                    })
 8257                    .collect::<Vec<_>>();
 8258
 8259                self.as_local_mut()
 8260                    .context("cannot merge diagnostics on a remote LspStore")?
 8261                    .update_buffer_diagnostics(
 8262                        &buffer_handle,
 8263                        server_id,
 8264                        Some(update.registration_id),
 8265                        update.result_id,
 8266                        update.diagnostics.version,
 8267                        update.diagnostics.diagnostics.clone(),
 8268                        reused_diagnostics.clone(),
 8269                        cx,
 8270                    )?;
 8271
 8272                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8273            } else if let Some(local) = self.as_local() {
 8274                let reused_diagnostics = local
 8275                    .diagnostics
 8276                    .get(&worktree_id)
 8277                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8278                    .and_then(|diagnostics_by_server_id| {
 8279                        diagnostics_by_server_id
 8280                            .binary_search_by_key(&server_id, |e| e.0)
 8281                            .ok()
 8282                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8283                    })
 8284                    .into_iter()
 8285                    .flatten()
 8286                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8287
 8288                update
 8289                    .diagnostics
 8290                    .diagnostics
 8291                    .extend(reused_diagnostics.cloned());
 8292            }
 8293
 8294            let updated = worktree.update(cx, |worktree, cx| {
 8295                self.update_worktree_diagnostics(
 8296                    worktree.id(),
 8297                    server_id,
 8298                    project_path.path.clone(),
 8299                    update.diagnostics.diagnostics,
 8300                    cx,
 8301                )
 8302            })?;
 8303            match updated {
 8304                ControlFlow::Continue(new_summary) => {
 8305                    if let Some((project_id, new_summary)) = new_summary {
 8306                        match &mut diagnostics_summary {
 8307                            Some(diagnostics_summary) => {
 8308                                diagnostics_summary
 8309                                    .more_summaries
 8310                                    .push(proto::DiagnosticSummary {
 8311                                        path: project_path.path.as_ref().to_proto(),
 8312                                        language_server_id: server_id.0 as u64,
 8313                                        error_count: new_summary.error_count,
 8314                                        warning_count: new_summary.warning_count,
 8315                                    })
 8316                            }
 8317                            None => {
 8318                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8319                                    project_id,
 8320                                    worktree_id: worktree_id.to_proto(),
 8321                                    summary: Some(proto::DiagnosticSummary {
 8322                                        path: project_path.path.as_ref().to_proto(),
 8323                                        language_server_id: server_id.0 as u64,
 8324                                        error_count: new_summary.error_count,
 8325                                        warning_count: new_summary.warning_count,
 8326                                    }),
 8327                                    more_summaries: Vec::new(),
 8328                                })
 8329                            }
 8330                        }
 8331                    }
 8332                    updated_diagnostics_paths
 8333                        .entry(server_id)
 8334                        .or_insert_with(Vec::new)
 8335                        .push(project_path);
 8336                }
 8337                ControlFlow::Break(()) => {}
 8338            }
 8339        }
 8340
 8341        if let Some((diagnostics_summary, (downstream_client, _))) =
 8342            diagnostics_summary.zip(self.downstream_client.as_ref())
 8343        {
 8344            downstream_client.send(diagnostics_summary).log_err();
 8345        }
 8346        for (server_id, paths) in updated_diagnostics_paths {
 8347            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8348        }
 8349        Ok(())
 8350    }
 8351
 8352    fn update_worktree_diagnostics(
 8353        &mut self,
 8354        worktree_id: WorktreeId,
 8355        server_id: LanguageServerId,
 8356        path_in_worktree: Arc<RelPath>,
 8357        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8358        _: &mut Context<Worktree>,
 8359    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8360        let local = match &mut self.mode {
 8361            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8362            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8363        };
 8364
 8365        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8366        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8367        let summaries_by_server_id = summaries_for_tree
 8368            .entry(path_in_worktree.clone())
 8369            .or_default();
 8370
 8371        let old_summary = summaries_by_server_id
 8372            .remove(&server_id)
 8373            .unwrap_or_default();
 8374
 8375        let new_summary = DiagnosticSummary::new(&diagnostics);
 8376        if diagnostics.is_empty() {
 8377            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8378            {
 8379                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8380                    diagnostics_by_server_id.remove(ix);
 8381                }
 8382                if diagnostics_by_server_id.is_empty() {
 8383                    diagnostics_for_tree.remove(&path_in_worktree);
 8384                }
 8385            }
 8386        } else {
 8387            summaries_by_server_id.insert(server_id, new_summary);
 8388            let diagnostics_by_server_id = diagnostics_for_tree
 8389                .entry(path_in_worktree.clone())
 8390                .or_default();
 8391            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8392                Ok(ix) => {
 8393                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8394                }
 8395                Err(ix) => {
 8396                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8397                }
 8398            }
 8399        }
 8400
 8401        if !old_summary.is_empty() || !new_summary.is_empty() {
 8402            if let Some((_, project_id)) = &self.downstream_client {
 8403                Ok(ControlFlow::Continue(Some((
 8404                    *project_id,
 8405                    proto::DiagnosticSummary {
 8406                        path: path_in_worktree.to_proto(),
 8407                        language_server_id: server_id.0 as u64,
 8408                        error_count: new_summary.error_count as u32,
 8409                        warning_count: new_summary.warning_count as u32,
 8410                    },
 8411                ))))
 8412            } else {
 8413                Ok(ControlFlow::Continue(None))
 8414            }
 8415        } else {
 8416            Ok(ControlFlow::Break(()))
 8417        }
 8418    }
 8419
 8420    pub fn open_buffer_for_symbol(
 8421        &mut self,
 8422        symbol: &Symbol,
 8423        cx: &mut Context<Self>,
 8424    ) -> Task<Result<Entity<Buffer>>> {
 8425        if let Some((client, project_id)) = self.upstream_client() {
 8426            let request = client.request(proto::OpenBufferForSymbol {
 8427                project_id,
 8428                symbol: Some(Self::serialize_symbol(symbol)),
 8429            });
 8430            cx.spawn(async move |this, cx| {
 8431                let response = request.await?;
 8432                let buffer_id = BufferId::new(response.buffer_id)?;
 8433                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8434                    .await
 8435            })
 8436        } else if let Some(local) = self.as_local() {
 8437            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8438                seed.worktree_id == symbol.source_worktree_id
 8439                    && state.id == symbol.source_language_server_id
 8440                    && symbol.language_server_name == seed.name
 8441            });
 8442            if !is_valid {
 8443                return Task::ready(Err(anyhow!(
 8444                    "language server for worktree and language not found"
 8445                )));
 8446            };
 8447
 8448            let symbol_abs_path = match &symbol.path {
 8449                SymbolLocation::InProject(project_path) => self
 8450                    .worktree_store
 8451                    .read(cx)
 8452                    .absolutize(&project_path, cx)
 8453                    .context("no such worktree"),
 8454                SymbolLocation::OutsideProject {
 8455                    abs_path,
 8456                    signature: _,
 8457                } => Ok(abs_path.to_path_buf()),
 8458            };
 8459            let symbol_abs_path = match symbol_abs_path {
 8460                Ok(abs_path) => abs_path,
 8461                Err(err) => return Task::ready(Err(err)),
 8462            };
 8463            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8464                uri
 8465            } else {
 8466                return Task::ready(Err(anyhow!("invalid symbol path")));
 8467            };
 8468
 8469            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8470        } else {
 8471            Task::ready(Err(anyhow!("no upstream client or local store")))
 8472        }
 8473    }
 8474
 8475    pub(crate) fn open_local_buffer_via_lsp(
 8476        &mut self,
 8477        abs_path: lsp::Uri,
 8478        language_server_id: LanguageServerId,
 8479        cx: &mut Context<Self>,
 8480    ) -> Task<Result<Entity<Buffer>>> {
 8481        let path_style = self.worktree_store.read(cx).path_style();
 8482        cx.spawn(async move |lsp_store, cx| {
 8483            // Escape percent-encoded string.
 8484            let current_scheme = abs_path.scheme().to_owned();
 8485            // Uri is immutable, so we can't modify the scheme
 8486
 8487            let abs_path = abs_path
 8488                .to_file_path_ext(path_style)
 8489                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8490            let p = abs_path.clone();
 8491            let yarn_worktree = lsp_store
 8492                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8493                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8494                        cx.spawn(async move |this, cx| {
 8495                            let t = this
 8496                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8497                                .ok()?;
 8498                            t.await
 8499                        })
 8500                    }),
 8501                    None => Task::ready(None),
 8502                })?
 8503                .await;
 8504            let (worktree_root_target, known_relative_path) =
 8505                if let Some((zip_root, relative_path)) = yarn_worktree {
 8506                    (zip_root, Some(relative_path))
 8507                } else {
 8508                    (Arc::<Path>::from(abs_path.as_path()), None)
 8509                };
 8510            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8511                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8512                    worktree_store.find_worktree(&worktree_root_target, cx)
 8513                })
 8514            })?;
 8515            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8516                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8517                (result.0, relative_path, None)
 8518            } else {
 8519                let worktree = lsp_store
 8520                    .update(cx, |lsp_store, cx| {
 8521                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8522                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8523                        })
 8524                    })?
 8525                    .await?;
 8526                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8527                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8528                    lsp_store
 8529                        .update(cx, |lsp_store, cx| {
 8530                            if let Some(local) = lsp_store.as_local_mut() {
 8531                                local.register_language_server_for_invisible_worktree(
 8532                                    &worktree,
 8533                                    language_server_id,
 8534                                    cx,
 8535                                )
 8536                            }
 8537                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8538                                Some(status) => status.worktree,
 8539                                None => None,
 8540                            }
 8541                        })
 8542                        .ok()
 8543                        .flatten()
 8544                        .zip(Some(worktree_root.clone()))
 8545                } else {
 8546                    None
 8547                };
 8548                let relative_path = if let Some(known_path) = known_relative_path {
 8549                    known_path
 8550                } else {
 8551                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8552                        .into_arc()
 8553                };
 8554                (worktree, relative_path, source_ws)
 8555            };
 8556            let project_path = ProjectPath {
 8557                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8558                path: relative_path,
 8559            };
 8560            let buffer = lsp_store
 8561                .update(cx, |lsp_store, cx| {
 8562                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8563                        buffer_store.open_buffer(project_path, cx)
 8564                    })
 8565                })?
 8566                .await?;
 8567            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8568            if let Some((source_ws, worktree_root)) = source_ws {
 8569                buffer.update(cx, |buffer, cx| {
 8570                    let settings = WorktreeSettings::get(
 8571                        Some(
 8572                            (&ProjectPath {
 8573                                worktree_id: source_ws,
 8574                                path: Arc::from(RelPath::empty()),
 8575                            })
 8576                                .into(),
 8577                        ),
 8578                        cx,
 8579                    );
 8580                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8581                    if is_read_only {
 8582                        buffer.set_capability(Capability::ReadOnly, cx);
 8583                    }
 8584                });
 8585            }
 8586            Ok(buffer)
 8587        })
 8588    }
 8589
 8590    fn local_lsp_servers_for_buffer(
 8591        &self,
 8592        buffer: &Entity<Buffer>,
 8593        cx: &mut Context<Self>,
 8594    ) -> Vec<LanguageServerId> {
 8595        let Some(local) = self.as_local() else {
 8596            return Vec::new();
 8597        };
 8598
 8599        let snapshot = buffer.read(cx).snapshot();
 8600
 8601        buffer.update(cx, |buffer, cx| {
 8602            local
 8603                .language_servers_for_buffer(buffer, cx)
 8604                .map(|(_, server)| server.server_id())
 8605                .filter(|server_id| {
 8606                    self.as_local().is_none_or(|local| {
 8607                        local
 8608                            .buffers_opened_in_servers
 8609                            .get(&snapshot.remote_id())
 8610                            .is_some_and(|servers| servers.contains(server_id))
 8611                    })
 8612                })
 8613                .collect()
 8614        })
 8615    }
 8616
 8617    fn request_multiple_lsp_locally<P, R>(
 8618        &mut self,
 8619        buffer: &Entity<Buffer>,
 8620        position: Option<P>,
 8621        request: R,
 8622        cx: &mut Context<Self>,
 8623    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8624    where
 8625        P: ToOffset,
 8626        R: LspCommand + Clone,
 8627        <R::LspRequest as lsp::request::Request>::Result: Send,
 8628        <R::LspRequest as lsp::request::Request>::Params: Send,
 8629    {
 8630        let Some(local) = self.as_local() else {
 8631            return Task::ready(Vec::new());
 8632        };
 8633
 8634        let snapshot = buffer.read(cx).snapshot();
 8635        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8636
 8637        let server_ids = buffer.update(cx, |buffer, cx| {
 8638            local
 8639                .language_servers_for_buffer(buffer, cx)
 8640                .filter(|(adapter, _)| {
 8641                    scope
 8642                        .as_ref()
 8643                        .map(|scope| scope.language_allowed(&adapter.name))
 8644                        .unwrap_or(true)
 8645                })
 8646                .map(|(_, server)| server.server_id())
 8647                .filter(|server_id| {
 8648                    self.as_local().is_none_or(|local| {
 8649                        local
 8650                            .buffers_opened_in_servers
 8651                            .get(&snapshot.remote_id())
 8652                            .is_some_and(|servers| servers.contains(server_id))
 8653                    })
 8654                })
 8655                .collect::<Vec<_>>()
 8656        });
 8657
 8658        let mut response_results = server_ids
 8659            .into_iter()
 8660            .map(|server_id| {
 8661                let task = self.request_lsp(
 8662                    buffer.clone(),
 8663                    LanguageServerToQuery::Other(server_id),
 8664                    request.clone(),
 8665                    cx,
 8666                );
 8667                async move { (server_id, task.await) }
 8668            })
 8669            .collect::<FuturesUnordered<_>>();
 8670
 8671        cx.background_spawn(async move {
 8672            let mut responses = Vec::with_capacity(response_results.len());
 8673            while let Some((server_id, response_result)) = response_results.next().await {
 8674                match response_result {
 8675                    Ok(response) => responses.push((server_id, response)),
 8676                    // rust-analyzer likes to error with this when its still loading up
 8677                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8678                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8679                }
 8680            }
 8681            responses
 8682        })
 8683    }
 8684
 8685    async fn handle_lsp_get_completions(
 8686        this: Entity<Self>,
 8687        envelope: TypedEnvelope<proto::GetCompletions>,
 8688        mut cx: AsyncApp,
 8689    ) -> Result<proto::GetCompletionsResponse> {
 8690        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8691
 8692        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8693        let buffer_handle = this.update(&mut cx, |this, cx| {
 8694            this.buffer_store.read(cx).get_existing(buffer_id)
 8695        })?;
 8696        let request = GetCompletions::from_proto(
 8697            envelope.payload,
 8698            this.clone(),
 8699            buffer_handle.clone(),
 8700            cx.clone(),
 8701        )
 8702        .await?;
 8703
 8704        let server_to_query = match request.server_id {
 8705            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8706            None => LanguageServerToQuery::FirstCapable,
 8707        };
 8708
 8709        let response = this
 8710            .update(&mut cx, |this, cx| {
 8711                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8712            })
 8713            .await?;
 8714        this.update(&mut cx, |this, cx| {
 8715            Ok(GetCompletions::response_to_proto(
 8716                response,
 8717                this,
 8718                sender_id,
 8719                &buffer_handle.read(cx).version(),
 8720                cx,
 8721            ))
 8722        })
 8723    }
 8724
 8725    async fn handle_lsp_command<T: LspCommand>(
 8726        this: Entity<Self>,
 8727        envelope: TypedEnvelope<T::ProtoRequest>,
 8728        mut cx: AsyncApp,
 8729    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8730    where
 8731        <T::LspRequest as lsp::request::Request>::Params: Send,
 8732        <T::LspRequest as lsp::request::Request>::Result: Send,
 8733    {
 8734        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8735        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8736        let buffer_handle = this.update(&mut cx, |this, cx| {
 8737            this.buffer_store.read(cx).get_existing(buffer_id)
 8738        })?;
 8739        let request = T::from_proto(
 8740            envelope.payload,
 8741            this.clone(),
 8742            buffer_handle.clone(),
 8743            cx.clone(),
 8744        )
 8745        .await?;
 8746        let response = this
 8747            .update(&mut cx, |this, cx| {
 8748                this.request_lsp(
 8749                    buffer_handle.clone(),
 8750                    LanguageServerToQuery::FirstCapable,
 8751                    request,
 8752                    cx,
 8753                )
 8754            })
 8755            .await?;
 8756        this.update(&mut cx, |this, cx| {
 8757            Ok(T::response_to_proto(
 8758                response,
 8759                this,
 8760                sender_id,
 8761                &buffer_handle.read(cx).version(),
 8762                cx,
 8763            ))
 8764        })
 8765    }
 8766
 8767    async fn handle_lsp_query(
 8768        lsp_store: Entity<Self>,
 8769        envelope: TypedEnvelope<proto::LspQuery>,
 8770        mut cx: AsyncApp,
 8771    ) -> Result<proto::Ack> {
 8772        use proto::lsp_query::Request;
 8773        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8774        let lsp_query = envelope.payload;
 8775        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8776        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8777        match lsp_query.request.context("invalid LSP query request")? {
 8778            Request::GetReferences(get_references) => {
 8779                let position = get_references.position.clone().and_then(deserialize_anchor);
 8780                Self::query_lsp_locally::<GetReferences>(
 8781                    lsp_store,
 8782                    server_id,
 8783                    sender_id,
 8784                    lsp_request_id,
 8785                    get_references,
 8786                    position,
 8787                    &mut cx,
 8788                )
 8789                .await?;
 8790            }
 8791            Request::GetDocumentColor(get_document_color) => {
 8792                Self::query_lsp_locally::<GetDocumentColor>(
 8793                    lsp_store,
 8794                    server_id,
 8795                    sender_id,
 8796                    lsp_request_id,
 8797                    get_document_color,
 8798                    None,
 8799                    &mut cx,
 8800                )
 8801                .await?;
 8802            }
 8803            Request::GetFoldingRanges(get_folding_ranges) => {
 8804                Self::query_lsp_locally::<GetFoldingRanges>(
 8805                    lsp_store,
 8806                    server_id,
 8807                    sender_id,
 8808                    lsp_request_id,
 8809                    get_folding_ranges,
 8810                    None,
 8811                    &mut cx,
 8812                )
 8813                .await?;
 8814            }
 8815            Request::GetDocumentSymbols(get_document_symbols) => {
 8816                Self::query_lsp_locally::<GetDocumentSymbols>(
 8817                    lsp_store,
 8818                    server_id,
 8819                    sender_id,
 8820                    lsp_request_id,
 8821                    get_document_symbols,
 8822                    None,
 8823                    &mut cx,
 8824                )
 8825                .await?;
 8826            }
 8827            Request::GetHover(get_hover) => {
 8828                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8829                Self::query_lsp_locally::<GetHover>(
 8830                    lsp_store,
 8831                    server_id,
 8832                    sender_id,
 8833                    lsp_request_id,
 8834                    get_hover,
 8835                    position,
 8836                    &mut cx,
 8837                )
 8838                .await?;
 8839            }
 8840            Request::GetCodeActions(get_code_actions) => {
 8841                Self::query_lsp_locally::<GetCodeActions>(
 8842                    lsp_store,
 8843                    server_id,
 8844                    sender_id,
 8845                    lsp_request_id,
 8846                    get_code_actions,
 8847                    None,
 8848                    &mut cx,
 8849                )
 8850                .await?;
 8851            }
 8852            Request::GetSignatureHelp(get_signature_help) => {
 8853                let position = get_signature_help
 8854                    .position
 8855                    .clone()
 8856                    .and_then(deserialize_anchor);
 8857                Self::query_lsp_locally::<GetSignatureHelp>(
 8858                    lsp_store,
 8859                    server_id,
 8860                    sender_id,
 8861                    lsp_request_id,
 8862                    get_signature_help,
 8863                    position,
 8864                    &mut cx,
 8865                )
 8866                .await?;
 8867            }
 8868            Request::GetCodeLens(get_code_lens) => {
 8869                Self::query_lsp_locally::<GetCodeLens>(
 8870                    lsp_store,
 8871                    server_id,
 8872                    sender_id,
 8873                    lsp_request_id,
 8874                    get_code_lens,
 8875                    None,
 8876                    &mut cx,
 8877                )
 8878                .await?;
 8879            }
 8880            Request::GetDefinition(get_definition) => {
 8881                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8882                Self::query_lsp_locally::<GetDefinitions>(
 8883                    lsp_store,
 8884                    server_id,
 8885                    sender_id,
 8886                    lsp_request_id,
 8887                    get_definition,
 8888                    position,
 8889                    &mut cx,
 8890                )
 8891                .await?;
 8892            }
 8893            Request::GetDeclaration(get_declaration) => {
 8894                let position = get_declaration
 8895                    .position
 8896                    .clone()
 8897                    .and_then(deserialize_anchor);
 8898                Self::query_lsp_locally::<GetDeclarations>(
 8899                    lsp_store,
 8900                    server_id,
 8901                    sender_id,
 8902                    lsp_request_id,
 8903                    get_declaration,
 8904                    position,
 8905                    &mut cx,
 8906                )
 8907                .await?;
 8908            }
 8909            Request::GetTypeDefinition(get_type_definition) => {
 8910                let position = get_type_definition
 8911                    .position
 8912                    .clone()
 8913                    .and_then(deserialize_anchor);
 8914                Self::query_lsp_locally::<GetTypeDefinitions>(
 8915                    lsp_store,
 8916                    server_id,
 8917                    sender_id,
 8918                    lsp_request_id,
 8919                    get_type_definition,
 8920                    position,
 8921                    &mut cx,
 8922                )
 8923                .await?;
 8924            }
 8925            Request::GetImplementation(get_implementation) => {
 8926                let position = get_implementation
 8927                    .position
 8928                    .clone()
 8929                    .and_then(deserialize_anchor);
 8930                Self::query_lsp_locally::<GetImplementations>(
 8931                    lsp_store,
 8932                    server_id,
 8933                    sender_id,
 8934                    lsp_request_id,
 8935                    get_implementation,
 8936                    position,
 8937                    &mut cx,
 8938                )
 8939                .await?;
 8940            }
 8941            Request::InlayHints(inlay_hints) => {
 8942                let query_start = inlay_hints
 8943                    .start
 8944                    .clone()
 8945                    .and_then(deserialize_anchor)
 8946                    .context("invalid inlay hints range start")?;
 8947                let query_end = inlay_hints
 8948                    .end
 8949                    .clone()
 8950                    .and_then(deserialize_anchor)
 8951                    .context("invalid inlay hints range end")?;
 8952                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 8953                    &lsp_store,
 8954                    server_id,
 8955                    lsp_request_id,
 8956                    &inlay_hints,
 8957                    query_start..query_end,
 8958                    &mut cx,
 8959                )
 8960                .await
 8961                .context("preparing inlay hints request")?;
 8962                Self::query_lsp_locally::<InlayHints>(
 8963                    lsp_store,
 8964                    server_id,
 8965                    sender_id,
 8966                    lsp_request_id,
 8967                    inlay_hints,
 8968                    None,
 8969                    &mut cx,
 8970                )
 8971                .await
 8972                .context("querying for inlay hints")?
 8973            }
 8974            //////////////////////////////
 8975            // Below are LSP queries that need to fetch more data,
 8976            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 8977            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8978                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 8979                    &lsp_store,
 8980                    &get_document_diagnostics,
 8981                    &mut cx,
 8982                )
 8983                .await?;
 8984                lsp_store.update(&mut cx, |lsp_store, cx| {
 8985                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 8986                    let key = LspKey {
 8987                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 8988                        server_queried: server_id,
 8989                    };
 8990                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8991                    ) {
 8992                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 8993                            lsp_requests.clear();
 8994                        };
 8995                    }
 8996
 8997                    lsp_data.lsp_requests.entry(key).or_default().insert(
 8998                        lsp_request_id,
 8999                        cx.spawn(async move |lsp_store, cx| {
 9000                            let diagnostics_pull = lsp_store
 9001                                .update(cx, |lsp_store, cx| {
 9002                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9003                                })
 9004                                .ok();
 9005                            if let Some(diagnostics_pull) = diagnostics_pull {
 9006                                match diagnostics_pull.await {
 9007                                    Ok(()) => {}
 9008                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9009                                };
 9010                            }
 9011                        }),
 9012                    );
 9013                });
 9014            }
 9015            Request::SemanticTokens(semantic_tokens) => {
 9016                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 9017                    &lsp_store,
 9018                    &semantic_tokens,
 9019                    &mut cx,
 9020                )
 9021                .await?;
 9022                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9023                lsp_store.update(&mut cx, |lsp_store, cx| {
 9024                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9025                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9026                        let key = LspKey {
 9027                            request_type: TypeId::of::<SemanticTokensFull>(),
 9028                            server_queried: server_id,
 9029                        };
 9030                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9031                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9032                                lsp_requests.clear();
 9033                            };
 9034                        }
 9035
 9036                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9037                            lsp_request_id,
 9038                            cx.spawn(async move |lsp_store, cx| {
 9039                                let tokens_fetch = lsp_store
 9040                                    .update(cx, |lsp_store, cx| {
 9041                                        lsp_store
 9042                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9043                                    })
 9044                                    .ok();
 9045                                if let Some(tokens_fetch) = tokens_fetch {
 9046                                    let new_tokens = tokens_fetch.await;
 9047                                    if let Some(new_tokens) = new_tokens {
 9048                                        lsp_store
 9049                                            .update(cx, |lsp_store, cx| {
 9050                                                let response = new_tokens
 9051                                                    .into_iter()
 9052                                                    .map(|(server_id, response)| {
 9053                                                        (
 9054                                                            server_id.to_proto(),
 9055                                                            SemanticTokensFull::response_to_proto(
 9056                                                                response,
 9057                                                                lsp_store,
 9058                                                                sender_id,
 9059                                                                &buffer_version,
 9060                                                                cx,
 9061                                                            ),
 9062                                                        )
 9063                                                    })
 9064                                                    .collect::<HashMap<_, _>>();
 9065                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9066                                                    project_id,
 9067                                                    lsp_request_id,
 9068                                                    response,
 9069                                                ) {
 9070                                                    Ok(()) => {}
 9071                                                    Err(e) => {
 9072                                                        log::error!(
 9073                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9074                                                        )
 9075                                                    }
 9076                                                }
 9077                                            })
 9078                                            .ok();
 9079                                    }
 9080                                }
 9081                            }),
 9082                        );
 9083                    }
 9084                });
 9085            }
 9086        }
 9087        Ok(proto::Ack {})
 9088    }
 9089
 9090    async fn handle_lsp_query_response(
 9091        lsp_store: Entity<Self>,
 9092        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9093        cx: AsyncApp,
 9094    ) -> Result<()> {
 9095        lsp_store.read_with(&cx, |lsp_store, _| {
 9096            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9097                upstream_client.handle_lsp_response(envelope.clone());
 9098            }
 9099        });
 9100        Ok(())
 9101    }
 9102
 9103    async fn handle_apply_code_action(
 9104        this: Entity<Self>,
 9105        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9106        mut cx: AsyncApp,
 9107    ) -> Result<proto::ApplyCodeActionResponse> {
 9108        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9109        let action =
 9110            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9111        let apply_code_action = this.update(&mut cx, |this, cx| {
 9112            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9113            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9114            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9115        })?;
 9116
 9117        let project_transaction = apply_code_action.await?;
 9118        let project_transaction = this.update(&mut cx, |this, cx| {
 9119            this.buffer_store.update(cx, |buffer_store, cx| {
 9120                buffer_store.serialize_project_transaction_for_peer(
 9121                    project_transaction,
 9122                    sender_id,
 9123                    cx,
 9124                )
 9125            })
 9126        });
 9127        Ok(proto::ApplyCodeActionResponse {
 9128            transaction: Some(project_transaction),
 9129        })
 9130    }
 9131
 9132    async fn handle_register_buffer_with_language_servers(
 9133        this: Entity<Self>,
 9134        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9135        mut cx: AsyncApp,
 9136    ) -> Result<proto::Ack> {
 9137        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9138        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9139        this.update(&mut cx, |this, cx| {
 9140            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9141                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9142                    project_id: upstream_project_id,
 9143                    buffer_id: buffer_id.to_proto(),
 9144                    only_servers: envelope.payload.only_servers,
 9145                });
 9146            }
 9147
 9148            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9149                anyhow::bail!("buffer is not open");
 9150            };
 9151
 9152            let handle = this.register_buffer_with_language_servers(
 9153                &buffer,
 9154                envelope
 9155                    .payload
 9156                    .only_servers
 9157                    .into_iter()
 9158                    .filter_map(|selector| {
 9159                        Some(match selector.selector? {
 9160                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9161                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9162                            }
 9163                            proto::language_server_selector::Selector::Name(name) => {
 9164                                LanguageServerSelector::Name(LanguageServerName(
 9165                                    SharedString::from(name),
 9166                                ))
 9167                            }
 9168                        })
 9169                    })
 9170                    .collect(),
 9171                false,
 9172                cx,
 9173            );
 9174            // Pull diagnostics for the buffer even if it was already registered.
 9175            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9176            // but it's unclear if we need it.
 9177            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9178                .detach();
 9179            this.buffer_store().update(cx, |buffer_store, _| {
 9180                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9181            });
 9182
 9183            Ok(())
 9184        })?;
 9185        Ok(proto::Ack {})
 9186    }
 9187
 9188    async fn handle_rename_project_entry(
 9189        this: Entity<Self>,
 9190        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9191        mut cx: AsyncApp,
 9192    ) -> Result<proto::ProjectEntryResponse> {
 9193        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9194        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9195        let new_path =
 9196            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9197
 9198        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9199            .update(&mut cx, |this, cx| {
 9200                let (worktree, entry) = this
 9201                    .worktree_store
 9202                    .read(cx)
 9203                    .worktree_and_entry_for_id(entry_id, cx)?;
 9204                let new_worktree = this
 9205                    .worktree_store
 9206                    .read(cx)
 9207                    .worktree_for_id(new_worktree_id, cx)?;
 9208                Some((
 9209                    this.worktree_store.clone(),
 9210                    worktree,
 9211                    new_worktree,
 9212                    entry.clone(),
 9213                ))
 9214            })
 9215            .context("worktree not found")?;
 9216        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9217            (worktree.absolutize(&old_entry.path), worktree.id())
 9218        });
 9219        let new_abs_path =
 9220            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9221
 9222        let _transaction = Self::will_rename_entry(
 9223            this.downgrade(),
 9224            old_worktree_id,
 9225            &old_abs_path,
 9226            &new_abs_path,
 9227            old_entry.is_dir(),
 9228            cx.clone(),
 9229        )
 9230        .await;
 9231        let response = WorktreeStore::handle_rename_project_entry(
 9232            worktree_store,
 9233            envelope.payload,
 9234            cx.clone(),
 9235        )
 9236        .await;
 9237        this.read_with(&cx, |this, _| {
 9238            this.did_rename_entry(
 9239                old_worktree_id,
 9240                &old_abs_path,
 9241                &new_abs_path,
 9242                old_entry.is_dir(),
 9243            );
 9244        });
 9245        response
 9246    }
 9247
 9248    async fn handle_update_diagnostic_summary(
 9249        this: Entity<Self>,
 9250        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9251        mut cx: AsyncApp,
 9252    ) -> Result<()> {
 9253        this.update(&mut cx, |lsp_store, cx| {
 9254            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9255            let mut updated_diagnostics_paths = HashMap::default();
 9256            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9257            for message_summary in envelope
 9258                .payload
 9259                .summary
 9260                .into_iter()
 9261                .chain(envelope.payload.more_summaries)
 9262            {
 9263                let project_path = ProjectPath {
 9264                    worktree_id,
 9265                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9266                };
 9267                let path = project_path.path.clone();
 9268                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9269                let summary = DiagnosticSummary {
 9270                    error_count: message_summary.error_count as usize,
 9271                    warning_count: message_summary.warning_count as usize,
 9272                };
 9273
 9274                if summary.is_empty() {
 9275                    if let Some(worktree_summaries) =
 9276                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9277                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9278                    {
 9279                        summaries.remove(&server_id);
 9280                        if summaries.is_empty() {
 9281                            worktree_summaries.remove(&path);
 9282                        }
 9283                    }
 9284                } else {
 9285                    lsp_store
 9286                        .diagnostic_summaries
 9287                        .entry(worktree_id)
 9288                        .or_default()
 9289                        .entry(path)
 9290                        .or_default()
 9291                        .insert(server_id, summary);
 9292                }
 9293
 9294                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9295                    match &mut diagnostics_summary {
 9296                        Some(diagnostics_summary) => {
 9297                            diagnostics_summary
 9298                                .more_summaries
 9299                                .push(proto::DiagnosticSummary {
 9300                                    path: project_path.path.as_ref().to_proto(),
 9301                                    language_server_id: server_id.0 as u64,
 9302                                    error_count: summary.error_count as u32,
 9303                                    warning_count: summary.warning_count as u32,
 9304                                })
 9305                        }
 9306                        None => {
 9307                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9308                                project_id: *project_id,
 9309                                worktree_id: worktree_id.to_proto(),
 9310                                summary: Some(proto::DiagnosticSummary {
 9311                                    path: project_path.path.as_ref().to_proto(),
 9312                                    language_server_id: server_id.0 as u64,
 9313                                    error_count: summary.error_count as u32,
 9314                                    warning_count: summary.warning_count as u32,
 9315                                }),
 9316                                more_summaries: Vec::new(),
 9317                            })
 9318                        }
 9319                    }
 9320                }
 9321                updated_diagnostics_paths
 9322                    .entry(server_id)
 9323                    .or_insert_with(Vec::new)
 9324                    .push(project_path);
 9325            }
 9326
 9327            if let Some((diagnostics_summary, (downstream_client, _))) =
 9328                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9329            {
 9330                downstream_client.send(diagnostics_summary).log_err();
 9331            }
 9332            for (server_id, paths) in updated_diagnostics_paths {
 9333                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9334            }
 9335            Ok(())
 9336        })
 9337    }
 9338
 9339    async fn handle_start_language_server(
 9340        lsp_store: Entity<Self>,
 9341        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9342        mut cx: AsyncApp,
 9343    ) -> Result<()> {
 9344        let server = envelope.payload.server.context("invalid server")?;
 9345        let server_capabilities =
 9346            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9347                .with_context(|| {
 9348                    format!(
 9349                        "incorrect server capabilities {}",
 9350                        envelope.payload.capabilities
 9351                    )
 9352                })?;
 9353        lsp_store.update(&mut cx, |lsp_store, cx| {
 9354            let server_id = LanguageServerId(server.id as usize);
 9355            let server_name = LanguageServerName::from_proto(server.name.clone());
 9356            lsp_store
 9357                .lsp_server_capabilities
 9358                .insert(server_id, server_capabilities);
 9359            lsp_store.language_server_statuses.insert(
 9360                server_id,
 9361                LanguageServerStatus {
 9362                    name: server_name.clone(),
 9363                    server_version: None,
 9364                    pending_work: Default::default(),
 9365                    has_pending_diagnostic_updates: false,
 9366                    progress_tokens: Default::default(),
 9367                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9368                    binary: None,
 9369                    configuration: None,
 9370                    workspace_folders: BTreeSet::new(),
 9371                    process_id: None,
 9372                },
 9373            );
 9374            cx.emit(LspStoreEvent::LanguageServerAdded(
 9375                server_id,
 9376                server_name,
 9377                server.worktree_id.map(WorktreeId::from_proto),
 9378            ));
 9379            cx.notify();
 9380        });
 9381        Ok(())
 9382    }
 9383
 9384    async fn handle_update_language_server(
 9385        lsp_store: Entity<Self>,
 9386        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9387        mut cx: AsyncApp,
 9388    ) -> Result<()> {
 9389        lsp_store.update(&mut cx, |lsp_store, cx| {
 9390            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9391
 9392            match envelope.payload.variant.context("invalid variant")? {
 9393                proto::update_language_server::Variant::WorkStart(payload) => {
 9394                    lsp_store.on_lsp_work_start(
 9395                        language_server_id,
 9396                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9397                            .context("invalid progress token value")?,
 9398                        LanguageServerProgress {
 9399                            title: payload.title,
 9400                            is_disk_based_diagnostics_progress: false,
 9401                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9402                            message: payload.message,
 9403                            percentage: payload.percentage.map(|p| p as usize),
 9404                            last_update_at: cx.background_executor().now(),
 9405                        },
 9406                        cx,
 9407                    );
 9408                }
 9409                proto::update_language_server::Variant::WorkProgress(payload) => {
 9410                    lsp_store.on_lsp_work_progress(
 9411                        language_server_id,
 9412                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9413                            .context("invalid progress token value")?,
 9414                        LanguageServerProgress {
 9415                            title: None,
 9416                            is_disk_based_diagnostics_progress: false,
 9417                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9418                            message: payload.message,
 9419                            percentage: payload.percentage.map(|p| p as usize),
 9420                            last_update_at: cx.background_executor().now(),
 9421                        },
 9422                        cx,
 9423                    );
 9424                }
 9425
 9426                proto::update_language_server::Variant::WorkEnd(payload) => {
 9427                    lsp_store.on_lsp_work_end(
 9428                        language_server_id,
 9429                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9430                            .context("invalid progress token value")?,
 9431                        cx,
 9432                    );
 9433                }
 9434
 9435                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9436                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9437                }
 9438
 9439                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9440                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9441                }
 9442
 9443                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9444                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9445                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9446                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9447                        language_server_id,
 9448                        name: envelope
 9449                            .payload
 9450                            .server_name
 9451                            .map(SharedString::new)
 9452                            .map(LanguageServerName),
 9453                        message: non_lsp,
 9454                    });
 9455                }
 9456            }
 9457
 9458            Ok(())
 9459        })
 9460    }
 9461
 9462    async fn handle_language_server_log(
 9463        this: Entity<Self>,
 9464        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9465        mut cx: AsyncApp,
 9466    ) -> Result<()> {
 9467        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9468        let log_type = envelope
 9469            .payload
 9470            .log_type
 9471            .map(LanguageServerLogType::from_proto)
 9472            .context("invalid language server log type")?;
 9473
 9474        let message = envelope.payload.message;
 9475
 9476        this.update(&mut cx, |_, cx| {
 9477            cx.emit(LspStoreEvent::LanguageServerLog(
 9478                language_server_id,
 9479                log_type,
 9480                message,
 9481            ));
 9482        });
 9483        Ok(())
 9484    }
 9485
 9486    async fn handle_lsp_ext_cancel_flycheck(
 9487        lsp_store: Entity<Self>,
 9488        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9489        cx: AsyncApp,
 9490    ) -> Result<proto::Ack> {
 9491        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9492        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9493            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9494                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9495            } else {
 9496                None
 9497            }
 9498        });
 9499        if let Some(task) = task {
 9500            task.context("handling lsp ext cancel flycheck")?;
 9501        }
 9502
 9503        Ok(proto::Ack {})
 9504    }
 9505
 9506    async fn handle_lsp_ext_run_flycheck(
 9507        lsp_store: Entity<Self>,
 9508        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9509        mut cx: AsyncApp,
 9510    ) -> Result<proto::Ack> {
 9511        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9512        lsp_store.update(&mut cx, |lsp_store, cx| {
 9513            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9514                let text_document = if envelope.payload.current_file_only {
 9515                    let buffer_id = envelope
 9516                        .payload
 9517                        .buffer_id
 9518                        .map(|id| BufferId::new(id))
 9519                        .transpose()?;
 9520                    buffer_id
 9521                        .and_then(|buffer_id| {
 9522                            lsp_store
 9523                                .buffer_store()
 9524                                .read(cx)
 9525                                .get(buffer_id)
 9526                                .and_then(|buffer| {
 9527                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9528                                })
 9529                                .map(|path| make_text_document_identifier(&path))
 9530                        })
 9531                        .transpose()?
 9532                } else {
 9533                    None
 9534                };
 9535                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9536                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9537                )?;
 9538            }
 9539            anyhow::Ok(())
 9540        })?;
 9541
 9542        Ok(proto::Ack {})
 9543    }
 9544
 9545    async fn handle_lsp_ext_clear_flycheck(
 9546        lsp_store: Entity<Self>,
 9547        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9548        cx: AsyncApp,
 9549    ) -> Result<proto::Ack> {
 9550        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9551        lsp_store.read_with(&cx, |lsp_store, _| {
 9552            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9553                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9554            } else {
 9555                None
 9556            }
 9557        });
 9558
 9559        Ok(proto::Ack {})
 9560    }
 9561
 9562    pub fn disk_based_diagnostics_started(
 9563        &mut self,
 9564        language_server_id: LanguageServerId,
 9565        cx: &mut Context<Self>,
 9566    ) {
 9567        if let Some(language_server_status) =
 9568            self.language_server_statuses.get_mut(&language_server_id)
 9569        {
 9570            language_server_status.has_pending_diagnostic_updates = true;
 9571        }
 9572
 9573        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9574        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9575            language_server_id,
 9576            name: self
 9577                .language_server_adapter_for_id(language_server_id)
 9578                .map(|adapter| adapter.name()),
 9579            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9580                Default::default(),
 9581            ),
 9582        })
 9583    }
 9584
 9585    pub fn disk_based_diagnostics_finished(
 9586        &mut self,
 9587        language_server_id: LanguageServerId,
 9588        cx: &mut Context<Self>,
 9589    ) {
 9590        if let Some(language_server_status) =
 9591            self.language_server_statuses.get_mut(&language_server_id)
 9592        {
 9593            language_server_status.has_pending_diagnostic_updates = false;
 9594        }
 9595
 9596        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9597        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9598            language_server_id,
 9599            name: self
 9600                .language_server_adapter_for_id(language_server_id)
 9601                .map(|adapter| adapter.name()),
 9602            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9603                Default::default(),
 9604            ),
 9605        })
 9606    }
 9607
 9608    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9609    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9610    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9611    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9612    // the language server might take some time to publish diagnostics.
 9613    fn simulate_disk_based_diagnostics_events_if_needed(
 9614        &mut self,
 9615        language_server_id: LanguageServerId,
 9616        cx: &mut Context<Self>,
 9617    ) {
 9618        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9619
 9620        let Some(LanguageServerState::Running {
 9621            simulate_disk_based_diagnostics_completion,
 9622            adapter,
 9623            ..
 9624        }) = self
 9625            .as_local_mut()
 9626            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9627        else {
 9628            return;
 9629        };
 9630
 9631        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9632            return;
 9633        }
 9634
 9635        let prev_task =
 9636            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9637                cx.background_executor()
 9638                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9639                    .await;
 9640
 9641                this.update(cx, |this, cx| {
 9642                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9643
 9644                    if let Some(LanguageServerState::Running {
 9645                        simulate_disk_based_diagnostics_completion,
 9646                        ..
 9647                    }) = this.as_local_mut().and_then(|local_store| {
 9648                        local_store.language_servers.get_mut(&language_server_id)
 9649                    }) {
 9650                        *simulate_disk_based_diagnostics_completion = None;
 9651                    }
 9652                })
 9653                .ok();
 9654            }));
 9655
 9656        if prev_task.is_none() {
 9657            self.disk_based_diagnostics_started(language_server_id, cx);
 9658        }
 9659    }
 9660
 9661    pub fn language_server_statuses(
 9662        &self,
 9663    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9664        self.language_server_statuses
 9665            .iter()
 9666            .map(|(key, value)| (*key, value))
 9667    }
 9668
 9669    pub(super) fn did_rename_entry(
 9670        &self,
 9671        worktree_id: WorktreeId,
 9672        old_path: &Path,
 9673        new_path: &Path,
 9674        is_dir: bool,
 9675    ) {
 9676        maybe!({
 9677            let local_store = self.as_local()?;
 9678
 9679            let old_uri = lsp::Uri::from_file_path(old_path)
 9680                .ok()
 9681                .map(|uri| uri.to_string())?;
 9682            let new_uri = lsp::Uri::from_file_path(new_path)
 9683                .ok()
 9684                .map(|uri| uri.to_string())?;
 9685
 9686            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9687                let Some(filter) = local_store
 9688                    .language_server_paths_watched_for_rename
 9689                    .get(&language_server.server_id())
 9690                else {
 9691                    continue;
 9692                };
 9693
 9694                if filter.should_send_did_rename(&old_uri, is_dir) {
 9695                    language_server
 9696                        .notify::<DidRenameFiles>(RenameFilesParams {
 9697                            files: vec![FileRename {
 9698                                old_uri: old_uri.clone(),
 9699                                new_uri: new_uri.clone(),
 9700                            }],
 9701                        })
 9702                        .ok();
 9703                }
 9704            }
 9705            Some(())
 9706        });
 9707    }
 9708
 9709    pub(super) fn will_rename_entry(
 9710        this: WeakEntity<Self>,
 9711        worktree_id: WorktreeId,
 9712        old_path: &Path,
 9713        new_path: &Path,
 9714        is_dir: bool,
 9715        cx: AsyncApp,
 9716    ) -> Task<ProjectTransaction> {
 9717        let old_uri = lsp::Uri::from_file_path(old_path)
 9718            .ok()
 9719            .map(|uri| uri.to_string());
 9720        let new_uri = lsp::Uri::from_file_path(new_path)
 9721            .ok()
 9722            .map(|uri| uri.to_string());
 9723        cx.spawn(async move |cx| {
 9724            let mut tasks = vec![];
 9725            this.update(cx, |this, cx| {
 9726                let local_store = this.as_local()?;
 9727                let old_uri = old_uri?;
 9728                let new_uri = new_uri?;
 9729                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9730                    let Some(filter) = local_store
 9731                        .language_server_paths_watched_for_rename
 9732                        .get(&language_server.server_id())
 9733                    else {
 9734                        continue;
 9735                    };
 9736
 9737                    if !filter.should_send_will_rename(&old_uri, is_dir) {
 9738                        continue;
 9739                    }
 9740                    let request_timeout = ProjectSettings::get_global(cx)
 9741                        .global_lsp_settings
 9742                        .get_request_timeout();
 9743
 9744                    let apply_edit = cx.spawn({
 9745                        let old_uri = old_uri.clone();
 9746                        let new_uri = new_uri.clone();
 9747                        let language_server = language_server.clone();
 9748                        async move |this, cx| {
 9749                            let edit = language_server
 9750                                .request::<WillRenameFiles>(
 9751                                    RenameFilesParams {
 9752                                        files: vec![FileRename { old_uri, new_uri }],
 9753                                    },
 9754                                    request_timeout,
 9755                                )
 9756                                .await
 9757                                .into_response()
 9758                                .context("will rename files")
 9759                                .log_err()
 9760                                .flatten()?;
 9761
 9762                            LocalLspStore::deserialize_workspace_edit(
 9763                                this.upgrade()?,
 9764                                edit,
 9765                                false,
 9766                                language_server.clone(),
 9767                                cx,
 9768                            )
 9769                            .await
 9770                            .ok()
 9771                        }
 9772                    });
 9773                    tasks.push(apply_edit);
 9774                }
 9775                Some(())
 9776            })
 9777            .ok()
 9778            .flatten();
 9779            let mut merged_transaction = ProjectTransaction::default();
 9780            for task in tasks {
 9781                // Await on tasks sequentially so that the order of application of edits is deterministic
 9782                // (at least with regards to the order of registration of language servers)
 9783                if let Some(transaction) = task.await {
 9784                    for (buffer, buffer_transaction) in transaction.0 {
 9785                        merged_transaction.0.insert(buffer, buffer_transaction);
 9786                    }
 9787                }
 9788            }
 9789            merged_transaction
 9790        })
 9791    }
 9792
 9793    fn lsp_notify_abs_paths_changed(
 9794        &mut self,
 9795        server_id: LanguageServerId,
 9796        changes: Vec<PathEvent>,
 9797    ) {
 9798        maybe!({
 9799            let server = self.language_server_for_id(server_id)?;
 9800            let changes = changes
 9801                .into_iter()
 9802                .filter_map(|event| {
 9803                    let typ = match event.kind? {
 9804                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9805                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9806                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9807                    };
 9808                    Some(lsp::FileEvent {
 9809                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9810                        typ,
 9811                    })
 9812                })
 9813                .collect::<Vec<_>>();
 9814            if !changes.is_empty() {
 9815                server
 9816                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9817                        lsp::DidChangeWatchedFilesParams { changes },
 9818                    )
 9819                    .ok();
 9820            }
 9821            Some(())
 9822        });
 9823    }
 9824
 9825    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9826        self.as_local()?.language_server_for_id(id)
 9827    }
 9828
 9829    fn on_lsp_progress(
 9830        &mut self,
 9831        progress_params: lsp::ProgressParams,
 9832        language_server_id: LanguageServerId,
 9833        disk_based_diagnostics_progress_token: Option<String>,
 9834        cx: &mut Context<Self>,
 9835    ) {
 9836        match progress_params.value {
 9837            lsp::ProgressParamsValue::WorkDone(progress) => {
 9838                self.handle_work_done_progress(
 9839                    progress,
 9840                    language_server_id,
 9841                    disk_based_diagnostics_progress_token,
 9842                    ProgressToken::from_lsp(progress_params.token),
 9843                    cx,
 9844                );
 9845            }
 9846            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9847                let registration_id = match progress_params.token {
 9848                    lsp::NumberOrString::Number(_) => None,
 9849                    lsp::NumberOrString::String(token) => token
 9850                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9851                        .map(|(_, id)| id.to_owned()),
 9852                };
 9853                if let Some(LanguageServerState::Running {
 9854                    workspace_diagnostics_refresh_tasks,
 9855                    ..
 9856                }) = self
 9857                    .as_local_mut()
 9858                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9859                    && let Some(workspace_diagnostics) =
 9860                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9861                {
 9862                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9863                    self.apply_workspace_diagnostic_report(
 9864                        language_server_id,
 9865                        report,
 9866                        registration_id.map(SharedString::from),
 9867                        cx,
 9868                    )
 9869                }
 9870            }
 9871        }
 9872    }
 9873
 9874    fn handle_work_done_progress(
 9875        &mut self,
 9876        progress: lsp::WorkDoneProgress,
 9877        language_server_id: LanguageServerId,
 9878        disk_based_diagnostics_progress_token: Option<String>,
 9879        token: ProgressToken,
 9880        cx: &mut Context<Self>,
 9881    ) {
 9882        let language_server_status =
 9883            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9884                status
 9885            } else {
 9886                return;
 9887            };
 9888
 9889        if !language_server_status.progress_tokens.contains(&token) {
 9890            return;
 9891        }
 9892
 9893        let is_disk_based_diagnostics_progress =
 9894            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9895                (&disk_based_diagnostics_progress_token, &token)
 9896            {
 9897                token.starts_with(disk_based_token)
 9898            } else {
 9899                false
 9900            };
 9901
 9902        match progress {
 9903            lsp::WorkDoneProgress::Begin(report) => {
 9904                if is_disk_based_diagnostics_progress {
 9905                    self.disk_based_diagnostics_started(language_server_id, cx);
 9906                }
 9907                self.on_lsp_work_start(
 9908                    language_server_id,
 9909                    token.clone(),
 9910                    LanguageServerProgress {
 9911                        title: Some(report.title),
 9912                        is_disk_based_diagnostics_progress,
 9913                        is_cancellable: report.cancellable.unwrap_or(false),
 9914                        message: report.message.clone(),
 9915                        percentage: report.percentage.map(|p| p as usize),
 9916                        last_update_at: cx.background_executor().now(),
 9917                    },
 9918                    cx,
 9919                );
 9920            }
 9921            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9922                language_server_id,
 9923                token,
 9924                LanguageServerProgress {
 9925                    title: None,
 9926                    is_disk_based_diagnostics_progress,
 9927                    is_cancellable: report.cancellable.unwrap_or(false),
 9928                    message: report.message,
 9929                    percentage: report.percentage.map(|p| p as usize),
 9930                    last_update_at: cx.background_executor().now(),
 9931                },
 9932                cx,
 9933            ),
 9934            lsp::WorkDoneProgress::End(_) => {
 9935                language_server_status.progress_tokens.remove(&token);
 9936                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9937                if is_disk_based_diagnostics_progress {
 9938                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9939                }
 9940            }
 9941        }
 9942    }
 9943
 9944    fn on_lsp_work_start(
 9945        &mut self,
 9946        language_server_id: LanguageServerId,
 9947        token: ProgressToken,
 9948        progress: LanguageServerProgress,
 9949        cx: &mut Context<Self>,
 9950    ) {
 9951        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9952            status.pending_work.insert(token.clone(), progress.clone());
 9953            cx.notify();
 9954        }
 9955        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9956            language_server_id,
 9957            name: self
 9958                .language_server_adapter_for_id(language_server_id)
 9959                .map(|adapter| adapter.name()),
 9960            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9961                token: Some(token.to_proto()),
 9962                title: progress.title,
 9963                message: progress.message,
 9964                percentage: progress.percentage.map(|p| p as u32),
 9965                is_cancellable: Some(progress.is_cancellable),
 9966            }),
 9967        })
 9968    }
 9969
 9970    fn on_lsp_work_progress(
 9971        &mut self,
 9972        language_server_id: LanguageServerId,
 9973        token: ProgressToken,
 9974        progress: LanguageServerProgress,
 9975        cx: &mut Context<Self>,
 9976    ) {
 9977        let mut did_update = false;
 9978        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9979            match status.pending_work.entry(token.clone()) {
 9980                btree_map::Entry::Vacant(entry) => {
 9981                    entry.insert(progress.clone());
 9982                    did_update = true;
 9983                }
 9984                btree_map::Entry::Occupied(mut entry) => {
 9985                    let entry = entry.get_mut();
 9986                    if (progress.last_update_at - entry.last_update_at)
 9987                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9988                    {
 9989                        entry.last_update_at = progress.last_update_at;
 9990                        if progress.message.is_some() {
 9991                            entry.message = progress.message.clone();
 9992                        }
 9993                        if progress.percentage.is_some() {
 9994                            entry.percentage = progress.percentage;
 9995                        }
 9996                        if progress.is_cancellable != entry.is_cancellable {
 9997                            entry.is_cancellable = progress.is_cancellable;
 9998                        }
 9999                        did_update = true;
10000                    }
10001                }
10002            }
10003        }
10004
10005        if did_update {
10006            cx.emit(LspStoreEvent::LanguageServerUpdate {
10007                language_server_id,
10008                name: self
10009                    .language_server_adapter_for_id(language_server_id)
10010                    .map(|adapter| adapter.name()),
10011                message: proto::update_language_server::Variant::WorkProgress(
10012                    proto::LspWorkProgress {
10013                        token: Some(token.to_proto()),
10014                        message: progress.message,
10015                        percentage: progress.percentage.map(|p| p as u32),
10016                        is_cancellable: Some(progress.is_cancellable),
10017                    },
10018                ),
10019            })
10020        }
10021    }
10022
10023    fn on_lsp_work_end(
10024        &mut self,
10025        language_server_id: LanguageServerId,
10026        token: ProgressToken,
10027        cx: &mut Context<Self>,
10028    ) {
10029        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10030            if let Some(work) = status.pending_work.remove(&token)
10031                && !work.is_disk_based_diagnostics_progress
10032            {
10033                cx.emit(LspStoreEvent::RefreshInlayHints {
10034                    server_id: language_server_id,
10035                    request_id: None,
10036                });
10037            }
10038            cx.notify();
10039        }
10040
10041        cx.emit(LspStoreEvent::LanguageServerUpdate {
10042            language_server_id,
10043            name: self
10044                .language_server_adapter_for_id(language_server_id)
10045                .map(|adapter| adapter.name()),
10046            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10047                token: Some(token.to_proto()),
10048            }),
10049        })
10050    }
10051
10052    pub async fn handle_resolve_completion_documentation(
10053        this: Entity<Self>,
10054        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10055        mut cx: AsyncApp,
10056    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10057        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10058
10059        let completion = this
10060            .read_with(&cx, |this, cx| {
10061                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10062                let server = this
10063                    .language_server_for_id(id)
10064                    .with_context(|| format!("No language server {id}"))?;
10065
10066                let request_timeout = ProjectSettings::get_global(cx)
10067                    .global_lsp_settings
10068                    .get_request_timeout();
10069
10070                anyhow::Ok(cx.background_spawn(async move {
10071                    let can_resolve = server
10072                        .capabilities()
10073                        .completion_provider
10074                        .as_ref()
10075                        .and_then(|options| options.resolve_provider)
10076                        .unwrap_or(false);
10077                    if can_resolve {
10078                        server
10079                            .request::<lsp::request::ResolveCompletionItem>(
10080                                lsp_completion,
10081                                request_timeout,
10082                            )
10083                            .await
10084                            .into_response()
10085                            .context("resolve completion item")
10086                    } else {
10087                        anyhow::Ok(lsp_completion)
10088                    }
10089                }))
10090            })?
10091            .await?;
10092
10093        let mut documentation_is_markdown = false;
10094        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10095        let documentation = match completion.documentation {
10096            Some(lsp::Documentation::String(text)) => text,
10097
10098            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10099                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10100                value
10101            }
10102
10103            _ => String::new(),
10104        };
10105
10106        // If we have a new buffer_id, that means we're talking to a new client
10107        // and want to check for new text_edits in the completion too.
10108        let mut old_replace_start = None;
10109        let mut old_replace_end = None;
10110        let mut old_insert_start = None;
10111        let mut old_insert_end = None;
10112        let mut new_text = String::default();
10113        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10114            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10115                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10116                anyhow::Ok(buffer.read(cx).snapshot())
10117            })?;
10118
10119            if let Some(text_edit) = completion.text_edit.as_ref() {
10120                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10121
10122                if let Some(mut edit) = edit {
10123                    LineEnding::normalize(&mut edit.new_text);
10124
10125                    new_text = edit.new_text;
10126                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10127                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10128                    if let Some(insert_range) = edit.insert_range {
10129                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10130                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10131                    }
10132                }
10133            }
10134        }
10135
10136        Ok(proto::ResolveCompletionDocumentationResponse {
10137            documentation,
10138            documentation_is_markdown,
10139            old_replace_start,
10140            old_replace_end,
10141            new_text,
10142            lsp_completion,
10143            old_insert_start,
10144            old_insert_end,
10145        })
10146    }
10147
10148    async fn handle_on_type_formatting(
10149        this: Entity<Self>,
10150        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10151        mut cx: AsyncApp,
10152    ) -> Result<proto::OnTypeFormattingResponse> {
10153        let on_type_formatting = this.update(&mut cx, |this, cx| {
10154            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10155            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10156            let position = envelope
10157                .payload
10158                .position
10159                .and_then(deserialize_anchor)
10160                .context("invalid position")?;
10161            anyhow::Ok(this.apply_on_type_formatting(
10162                buffer,
10163                position,
10164                envelope.payload.trigger.clone(),
10165                cx,
10166            ))
10167        })?;
10168
10169        let transaction = on_type_formatting
10170            .await?
10171            .as_ref()
10172            .map(language::proto::serialize_transaction);
10173        Ok(proto::OnTypeFormattingResponse { transaction })
10174    }
10175
10176    async fn handle_pull_workspace_diagnostics(
10177        lsp_store: Entity<Self>,
10178        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10179        mut cx: AsyncApp,
10180    ) -> Result<proto::Ack> {
10181        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10182        lsp_store.update(&mut cx, |lsp_store, _| {
10183            lsp_store.pull_workspace_diagnostics(server_id);
10184        });
10185        Ok(proto::Ack {})
10186    }
10187
10188    async fn handle_open_buffer_for_symbol(
10189        this: Entity<Self>,
10190        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10191        mut cx: AsyncApp,
10192    ) -> Result<proto::OpenBufferForSymbolResponse> {
10193        let peer_id = envelope.original_sender_id().unwrap_or_default();
10194        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10195        let symbol = Self::deserialize_symbol(symbol)?;
10196        this.read_with(&cx, |this, _| {
10197            if let SymbolLocation::OutsideProject {
10198                abs_path,
10199                signature,
10200            } = &symbol.path
10201            {
10202                let new_signature = this.symbol_signature(&abs_path);
10203                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10204            }
10205            Ok(())
10206        })?;
10207        let buffer = this
10208            .update(&mut cx, |this, cx| {
10209                this.open_buffer_for_symbol(
10210                    &Symbol {
10211                        language_server_name: symbol.language_server_name,
10212                        source_worktree_id: symbol.source_worktree_id,
10213                        source_language_server_id: symbol.source_language_server_id,
10214                        path: symbol.path,
10215                        name: symbol.name,
10216                        kind: symbol.kind,
10217                        range: symbol.range,
10218                        label: CodeLabel::default(),
10219                        container_name: symbol.container_name,
10220                    },
10221                    cx,
10222                )
10223            })
10224            .await?;
10225
10226        this.update(&mut cx, |this, cx| {
10227            let is_private = buffer
10228                .read(cx)
10229                .file()
10230                .map(|f| f.is_private())
10231                .unwrap_or_default();
10232            if is_private {
10233                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10234            } else {
10235                this.buffer_store
10236                    .update(cx, |buffer_store, cx| {
10237                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10238                    })
10239                    .detach_and_log_err(cx);
10240                let buffer_id = buffer.read(cx).remote_id().to_proto();
10241                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10242            }
10243        })
10244    }
10245
10246    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10247        let mut hasher = Sha256::new();
10248        hasher.update(abs_path.to_string_lossy().as_bytes());
10249        hasher.update(self.nonce.to_be_bytes());
10250        hasher.finalize().as_slice().try_into().unwrap()
10251    }
10252
10253    pub async fn handle_get_project_symbols(
10254        this: Entity<Self>,
10255        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10256        mut cx: AsyncApp,
10257    ) -> Result<proto::GetProjectSymbolsResponse> {
10258        let symbols = this
10259            .update(&mut cx, |this, cx| {
10260                this.symbols(&envelope.payload.query, cx)
10261            })
10262            .await?;
10263
10264        Ok(proto::GetProjectSymbolsResponse {
10265            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10266        })
10267    }
10268
10269    pub async fn handle_restart_language_servers(
10270        this: Entity<Self>,
10271        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10272        mut cx: AsyncApp,
10273    ) -> Result<proto::Ack> {
10274        this.update(&mut cx, |lsp_store, cx| {
10275            let buffers =
10276                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10277            lsp_store.restart_language_servers_for_buffers(
10278                buffers,
10279                envelope
10280                    .payload
10281                    .only_servers
10282                    .into_iter()
10283                    .filter_map(|selector| {
10284                        Some(match selector.selector? {
10285                            proto::language_server_selector::Selector::ServerId(server_id) => {
10286                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10287                            }
10288                            proto::language_server_selector::Selector::Name(name) => {
10289                                LanguageServerSelector::Name(LanguageServerName(
10290                                    SharedString::from(name),
10291                                ))
10292                            }
10293                        })
10294                    })
10295                    .collect(),
10296                cx,
10297            );
10298        });
10299
10300        Ok(proto::Ack {})
10301    }
10302
10303    pub async fn handle_stop_language_servers(
10304        lsp_store: Entity<Self>,
10305        envelope: TypedEnvelope<proto::StopLanguageServers>,
10306        mut cx: AsyncApp,
10307    ) -> Result<proto::Ack> {
10308        lsp_store.update(&mut cx, |lsp_store, cx| {
10309            if envelope.payload.all
10310                && envelope.payload.also_servers.is_empty()
10311                && envelope.payload.buffer_ids.is_empty()
10312            {
10313                lsp_store.stop_all_language_servers(cx);
10314            } else {
10315                let buffers =
10316                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10317                lsp_store
10318                    .stop_language_servers_for_buffers(
10319                        buffers,
10320                        envelope
10321                            .payload
10322                            .also_servers
10323                            .into_iter()
10324                            .filter_map(|selector| {
10325                                Some(match selector.selector? {
10326                                    proto::language_server_selector::Selector::ServerId(
10327                                        server_id,
10328                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10329                                        server_id,
10330                                    )),
10331                                    proto::language_server_selector::Selector::Name(name) => {
10332                                        LanguageServerSelector::Name(LanguageServerName(
10333                                            SharedString::from(name),
10334                                        ))
10335                                    }
10336                                })
10337                            })
10338                            .collect(),
10339                        cx,
10340                    )
10341                    .detach_and_log_err(cx);
10342            }
10343        });
10344
10345        Ok(proto::Ack {})
10346    }
10347
10348    pub async fn handle_cancel_language_server_work(
10349        lsp_store: Entity<Self>,
10350        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10351        mut cx: AsyncApp,
10352    ) -> Result<proto::Ack> {
10353        lsp_store.update(&mut cx, |lsp_store, cx| {
10354            if let Some(work) = envelope.payload.work {
10355                match work {
10356                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10357                        let buffers =
10358                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10359                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10360                    }
10361                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10362                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10363                        let token = work
10364                            .token
10365                            .map(|token| {
10366                                ProgressToken::from_proto(token)
10367                                    .context("invalid work progress token")
10368                            })
10369                            .transpose()?;
10370                        lsp_store.cancel_language_server_work(server_id, token, cx);
10371                    }
10372                }
10373            }
10374            anyhow::Ok(())
10375        })?;
10376
10377        Ok(proto::Ack {})
10378    }
10379
10380    fn buffer_ids_to_buffers(
10381        &mut self,
10382        buffer_ids: impl Iterator<Item = u64>,
10383        cx: &mut Context<Self>,
10384    ) -> Vec<Entity<Buffer>> {
10385        buffer_ids
10386            .into_iter()
10387            .flat_map(|buffer_id| {
10388                self.buffer_store
10389                    .read(cx)
10390                    .get(BufferId::new(buffer_id).log_err()?)
10391            })
10392            .collect::<Vec<_>>()
10393    }
10394
10395    async fn handle_apply_additional_edits_for_completion(
10396        this: Entity<Self>,
10397        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10398        mut cx: AsyncApp,
10399    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10400        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10401            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10402            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10403            let completion = Self::deserialize_completion(
10404                envelope.payload.completion.context("invalid completion")?,
10405            )?;
10406            anyhow::Ok((buffer, completion))
10407        })?;
10408
10409        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10410            this.apply_additional_edits_for_completion(
10411                buffer,
10412                Rc::new(RefCell::new(Box::new([Completion {
10413                    replace_range: completion.replace_range,
10414                    new_text: completion.new_text,
10415                    source: completion.source,
10416                    documentation: None,
10417                    label: CodeLabel::default(),
10418                    match_start: None,
10419                    snippet_deduplication_key: None,
10420                    insert_text_mode: None,
10421                    icon_path: None,
10422                    confirm: None,
10423                }]))),
10424                0,
10425                false,
10426                cx,
10427            )
10428        });
10429
10430        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10431            transaction: apply_additional_edits
10432                .await?
10433                .as_ref()
10434                .map(language::proto::serialize_transaction),
10435        })
10436    }
10437
10438    pub fn last_formatting_failure(&self) -> Option<&str> {
10439        self.last_formatting_failure.as_deref()
10440    }
10441
10442    pub fn reset_last_formatting_failure(&mut self) {
10443        self.last_formatting_failure = None;
10444    }
10445
10446    pub fn environment_for_buffer(
10447        &self,
10448        buffer: &Entity<Buffer>,
10449        cx: &mut Context<Self>,
10450    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10451        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10452            environment.update(cx, |env, cx| {
10453                env.buffer_environment(buffer, &self.worktree_store, cx)
10454            })
10455        } else {
10456            Task::ready(None).shared()
10457        }
10458    }
10459
10460    pub fn format(
10461        &mut self,
10462        buffers: HashSet<Entity<Buffer>>,
10463        target: LspFormatTarget,
10464        push_to_history: bool,
10465        trigger: FormatTrigger,
10466        cx: &mut Context<Self>,
10467    ) -> Task<anyhow::Result<ProjectTransaction>> {
10468        let logger = zlog::scoped!("format");
10469        if self.as_local().is_some() {
10470            zlog::trace!(logger => "Formatting locally");
10471            let logger = zlog::scoped!(logger => "local");
10472            let buffers = buffers
10473                .into_iter()
10474                .map(|buffer_handle| {
10475                    let buffer = buffer_handle.read(cx);
10476                    let buffer_abs_path = File::from_dyn(buffer.file())
10477                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10478
10479                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10480                })
10481                .collect::<Vec<_>>();
10482
10483            cx.spawn(async move |lsp_store, cx| {
10484                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10485
10486                for (handle, abs_path, id) in buffers {
10487                    let env = lsp_store
10488                        .update(cx, |lsp_store, cx| {
10489                            lsp_store.environment_for_buffer(&handle, cx)
10490                        })?
10491                        .await;
10492
10493                    let ranges = match &target {
10494                        LspFormatTarget::Buffers => None,
10495                        LspFormatTarget::Ranges(ranges) => {
10496                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10497                        }
10498                    };
10499
10500                    formattable_buffers.push(FormattableBuffer {
10501                        handle,
10502                        abs_path,
10503                        env,
10504                        ranges,
10505                    });
10506                }
10507                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10508
10509                let format_timer = zlog::time!(logger => "Formatting buffers");
10510                let result = LocalLspStore::format_locally(
10511                    lsp_store.clone(),
10512                    formattable_buffers,
10513                    push_to_history,
10514                    trigger,
10515                    logger,
10516                    cx,
10517                )
10518                .await;
10519                format_timer.end();
10520
10521                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10522
10523                lsp_store.update(cx, |lsp_store, _| {
10524                    lsp_store.update_last_formatting_failure(&result);
10525                })?;
10526
10527                result
10528            })
10529        } else if let Some((client, project_id)) = self.upstream_client() {
10530            zlog::trace!(logger => "Formatting remotely");
10531            let logger = zlog::scoped!(logger => "remote");
10532
10533            let buffer_ranges = match &target {
10534                LspFormatTarget::Buffers => Vec::new(),
10535                LspFormatTarget::Ranges(ranges) => ranges
10536                    .iter()
10537                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10538                        buffer_id: buffer_id.to_proto(),
10539                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10540                    })
10541                    .collect(),
10542            };
10543
10544            let buffer_store = self.buffer_store();
10545            cx.spawn(async move |lsp_store, cx| {
10546                zlog::trace!(logger => "Sending remote format request");
10547                let request_timer = zlog::time!(logger => "remote format request");
10548                let result = client
10549                    .request(proto::FormatBuffers {
10550                        project_id,
10551                        trigger: trigger as i32,
10552                        buffer_ids: buffers
10553                            .iter()
10554                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10555                            .collect(),
10556                        buffer_ranges,
10557                    })
10558                    .await
10559                    .and_then(|result| result.transaction.context("missing transaction"));
10560                request_timer.end();
10561
10562                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10563
10564                lsp_store.update(cx, |lsp_store, _| {
10565                    lsp_store.update_last_formatting_failure(&result);
10566                })?;
10567
10568                let transaction_response = result?;
10569                let _timer = zlog::time!(logger => "deserializing project transaction");
10570                buffer_store
10571                    .update(cx, |buffer_store, cx| {
10572                        buffer_store.deserialize_project_transaction(
10573                            transaction_response,
10574                            push_to_history,
10575                            cx,
10576                        )
10577                    })
10578                    .await
10579            })
10580        } else {
10581            zlog::trace!(logger => "Not formatting");
10582            Task::ready(Ok(ProjectTransaction::default()))
10583        }
10584    }
10585
10586    async fn handle_format_buffers(
10587        this: Entity<Self>,
10588        envelope: TypedEnvelope<proto::FormatBuffers>,
10589        mut cx: AsyncApp,
10590    ) -> Result<proto::FormatBuffersResponse> {
10591        let sender_id = envelope.original_sender_id().unwrap_or_default();
10592        let format = this.update(&mut cx, |this, cx| {
10593            let mut buffers = HashSet::default();
10594            for buffer_id in &envelope.payload.buffer_ids {
10595                let buffer_id = BufferId::new(*buffer_id)?;
10596                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10597            }
10598
10599            let target = if envelope.payload.buffer_ranges.is_empty() {
10600                LspFormatTarget::Buffers
10601            } else {
10602                let mut ranges_map = BTreeMap::new();
10603                for buffer_range in &envelope.payload.buffer_ranges {
10604                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10605                    let ranges: Result<Vec<_>> = buffer_range
10606                        .ranges
10607                        .iter()
10608                        .map(|range| {
10609                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10610                        })
10611                        .collect();
10612                    ranges_map.insert(buffer_id, ranges?);
10613                }
10614                LspFormatTarget::Ranges(ranges_map)
10615            };
10616
10617            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10618            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10619        })?;
10620
10621        let project_transaction = format.await?;
10622        let project_transaction = this.update(&mut cx, |this, cx| {
10623            this.buffer_store.update(cx, |buffer_store, cx| {
10624                buffer_store.serialize_project_transaction_for_peer(
10625                    project_transaction,
10626                    sender_id,
10627                    cx,
10628                )
10629            })
10630        });
10631        Ok(proto::FormatBuffersResponse {
10632            transaction: Some(project_transaction),
10633        })
10634    }
10635
10636    async fn handle_apply_code_action_kind(
10637        this: Entity<Self>,
10638        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10639        mut cx: AsyncApp,
10640    ) -> Result<proto::ApplyCodeActionKindResponse> {
10641        let sender_id = envelope.original_sender_id().unwrap_or_default();
10642        let format = this.update(&mut cx, |this, cx| {
10643            let mut buffers = HashSet::default();
10644            for buffer_id in &envelope.payload.buffer_ids {
10645                let buffer_id = BufferId::new(*buffer_id)?;
10646                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10647            }
10648            let kind = match envelope.payload.kind.as_str() {
10649                "" => CodeActionKind::EMPTY,
10650                "quickfix" => CodeActionKind::QUICKFIX,
10651                "refactor" => CodeActionKind::REFACTOR,
10652                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10653                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10654                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10655                "source" => CodeActionKind::SOURCE,
10656                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10657                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10658                _ => anyhow::bail!(
10659                    "Invalid code action kind {}",
10660                    envelope.payload.kind.as_str()
10661                ),
10662            };
10663            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10664        })?;
10665
10666        let project_transaction = format.await?;
10667        let project_transaction = this.update(&mut cx, |this, cx| {
10668            this.buffer_store.update(cx, |buffer_store, cx| {
10669                buffer_store.serialize_project_transaction_for_peer(
10670                    project_transaction,
10671                    sender_id,
10672                    cx,
10673                )
10674            })
10675        });
10676        Ok(proto::ApplyCodeActionKindResponse {
10677            transaction: Some(project_transaction),
10678        })
10679    }
10680
10681    async fn shutdown_language_server(
10682        server_state: Option<LanguageServerState>,
10683        name: LanguageServerName,
10684        cx: &mut AsyncApp,
10685    ) {
10686        let server = match server_state {
10687            Some(LanguageServerState::Starting { startup, .. }) => {
10688                let mut timer = cx
10689                    .background_executor()
10690                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10691                    .fuse();
10692
10693                select! {
10694                    server = startup.fuse() => server,
10695                    () = timer => {
10696                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10697                        None
10698                    },
10699                }
10700            }
10701
10702            Some(LanguageServerState::Running { server, .. }) => Some(server),
10703
10704            None => None,
10705        };
10706
10707        let Some(server) = server else { return };
10708        if let Some(shutdown) = server.shutdown() {
10709            shutdown.await;
10710        }
10711    }
10712
10713    // Returns a list of all of the worktrees which no longer have a language server and the root path
10714    // for the stopped server
10715    fn stop_local_language_server(
10716        &mut self,
10717        server_id: LanguageServerId,
10718        cx: &mut Context<Self>,
10719    ) -> Task<()> {
10720        let local = match &mut self.mode {
10721            LspStoreMode::Local(local) => local,
10722            _ => {
10723                return Task::ready(());
10724            }
10725        };
10726
10727        // Remove this server ID from all entries in the given worktree.
10728        local
10729            .language_server_ids
10730            .retain(|_, state| state.id != server_id);
10731        self.buffer_store.update(cx, |buffer_store, cx| {
10732            for buffer in buffer_store.buffers() {
10733                buffer.update(cx, |buffer, cx| {
10734                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10735                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10736                });
10737            }
10738        });
10739
10740        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10741            summaries.retain(|path, summaries_by_server_id| {
10742                if summaries_by_server_id.remove(&server_id).is_some() {
10743                    if let Some((client, project_id)) = self.downstream_client.clone() {
10744                        client
10745                            .send(proto::UpdateDiagnosticSummary {
10746                                project_id,
10747                                worktree_id: worktree_id.to_proto(),
10748                                summary: Some(proto::DiagnosticSummary {
10749                                    path: path.as_ref().to_proto(),
10750                                    language_server_id: server_id.0 as u64,
10751                                    error_count: 0,
10752                                    warning_count: 0,
10753                                }),
10754                                more_summaries: Vec::new(),
10755                            })
10756                            .log_err();
10757                    }
10758                    !summaries_by_server_id.is_empty()
10759                } else {
10760                    true
10761                }
10762            });
10763        }
10764
10765        let local = self.as_local_mut().unwrap();
10766        for diagnostics in local.diagnostics.values_mut() {
10767            diagnostics.retain(|_, diagnostics_by_server_id| {
10768                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10769                    diagnostics_by_server_id.remove(ix);
10770                    !diagnostics_by_server_id.is_empty()
10771                } else {
10772                    true
10773                }
10774            });
10775        }
10776        local.language_server_watched_paths.remove(&server_id);
10777
10778        let server_state = local.language_servers.remove(&server_id);
10779        self.cleanup_lsp_data(server_id);
10780        let name = self
10781            .language_server_statuses
10782            .remove(&server_id)
10783            .map(|status| status.name)
10784            .or_else(|| {
10785                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10786                    Some(adapter.name())
10787                } else {
10788                    None
10789                }
10790            });
10791
10792        if let Some(name) = name {
10793            log::info!("stopping language server {name}");
10794            self.languages
10795                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10796            cx.notify();
10797
10798            return cx.spawn(async move |lsp_store, cx| {
10799                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10800                lsp_store
10801                    .update(cx, |lsp_store, cx| {
10802                        lsp_store
10803                            .languages
10804                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10805                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10806                        cx.notify();
10807                    })
10808                    .ok();
10809            });
10810        }
10811
10812        if server_state.is_some() {
10813            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10814        }
10815        Task::ready(())
10816    }
10817
10818    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10819        self.shutdown_all_language_servers(cx).detach();
10820    }
10821
10822    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
10823        if let Some((client, project_id)) = self.upstream_client() {
10824            let request = client.request(proto::StopLanguageServers {
10825                project_id,
10826                buffer_ids: Vec::new(),
10827                also_servers: Vec::new(),
10828                all: true,
10829            });
10830            cx.background_spawn(async move {
10831                request.await.ok();
10832            })
10833        } else {
10834            let Some(local) = self.as_local_mut() else {
10835                return Task::ready(());
10836            };
10837            let language_servers_to_stop = local
10838                .language_server_ids
10839                .values()
10840                .map(|state| state.id)
10841                .collect();
10842            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10843            let tasks = language_servers_to_stop
10844                .into_iter()
10845                .map(|server| self.stop_local_language_server(server, cx))
10846                .collect::<Vec<_>>();
10847            cx.background_spawn(async move {
10848                futures::future::join_all(tasks).await;
10849            })
10850        }
10851    }
10852
10853    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
10854        let buffers = self.buffer_store.read(cx).buffers().collect();
10855        self.restart_language_servers_for_buffers(buffers, HashSet::default(), cx);
10856    }
10857
10858    pub fn restart_language_servers_for_buffers(
10859        &mut self,
10860        buffers: Vec<Entity<Buffer>>,
10861        only_restart_servers: HashSet<LanguageServerSelector>,
10862        cx: &mut Context<Self>,
10863    ) {
10864        if let Some((client, project_id)) = self.upstream_client() {
10865            let request = client.request(proto::RestartLanguageServers {
10866                project_id,
10867                buffer_ids: buffers
10868                    .into_iter()
10869                    .map(|b| b.read(cx).remote_id().to_proto())
10870                    .collect(),
10871                only_servers: only_restart_servers
10872                    .into_iter()
10873                    .map(|selector| {
10874                        let selector = match selector {
10875                            LanguageServerSelector::Id(language_server_id) => {
10876                                proto::language_server_selector::Selector::ServerId(
10877                                    language_server_id.to_proto(),
10878                                )
10879                            }
10880                            LanguageServerSelector::Name(language_server_name) => {
10881                                proto::language_server_selector::Selector::Name(
10882                                    language_server_name.to_string(),
10883                                )
10884                            }
10885                        };
10886                        proto::LanguageServerSelector {
10887                            selector: Some(selector),
10888                        }
10889                    })
10890                    .collect(),
10891                all: false,
10892            });
10893            cx.background_spawn(request).detach_and_log_err(cx);
10894        } else {
10895            let stop_task = if only_restart_servers.is_empty() {
10896                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10897            } else {
10898                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10899            };
10900            cx.spawn(async move |lsp_store, cx| {
10901                stop_task.await;
10902                lsp_store.update(cx, |lsp_store, cx| {
10903                    for buffer in buffers {
10904                        lsp_store.register_buffer_with_language_servers(
10905                            &buffer,
10906                            only_restart_servers.clone(),
10907                            true,
10908                            cx,
10909                        );
10910                    }
10911                })
10912            })
10913            .detach();
10914        }
10915    }
10916
10917    pub fn stop_language_servers_for_buffers(
10918        &mut self,
10919        buffers: Vec<Entity<Buffer>>,
10920        also_stop_servers: HashSet<LanguageServerSelector>,
10921        cx: &mut Context<Self>,
10922    ) -> Task<Result<()>> {
10923        if let Some((client, project_id)) = self.upstream_client() {
10924            let request = client.request(proto::StopLanguageServers {
10925                project_id,
10926                buffer_ids: buffers
10927                    .into_iter()
10928                    .map(|b| b.read(cx).remote_id().to_proto())
10929                    .collect(),
10930                also_servers: also_stop_servers
10931                    .into_iter()
10932                    .map(|selector| {
10933                        let selector = match selector {
10934                            LanguageServerSelector::Id(language_server_id) => {
10935                                proto::language_server_selector::Selector::ServerId(
10936                                    language_server_id.to_proto(),
10937                                )
10938                            }
10939                            LanguageServerSelector::Name(language_server_name) => {
10940                                proto::language_server_selector::Selector::Name(
10941                                    language_server_name.to_string(),
10942                                )
10943                            }
10944                        };
10945                        proto::LanguageServerSelector {
10946                            selector: Some(selector),
10947                        }
10948                    })
10949                    .collect(),
10950                all: false,
10951            });
10952            cx.background_spawn(async move {
10953                let _ = request.await?;
10954                Ok(())
10955            })
10956        } else {
10957            let task =
10958                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10959            cx.background_spawn(async move {
10960                task.await;
10961                Ok(())
10962            })
10963        }
10964    }
10965
10966    fn stop_local_language_servers_for_buffers(
10967        &mut self,
10968        buffers: &[Entity<Buffer>],
10969        also_stop_servers: HashSet<LanguageServerSelector>,
10970        cx: &mut Context<Self>,
10971    ) -> Task<()> {
10972        let Some(local) = self.as_local_mut() else {
10973            return Task::ready(());
10974        };
10975        let mut language_server_names_to_stop = BTreeSet::default();
10976        let mut language_servers_to_stop = also_stop_servers
10977            .into_iter()
10978            .flat_map(|selector| match selector {
10979                LanguageServerSelector::Id(id) => Some(id),
10980                LanguageServerSelector::Name(name) => {
10981                    language_server_names_to_stop.insert(name);
10982                    None
10983                }
10984            })
10985            .collect::<BTreeSet<_>>();
10986
10987        let mut covered_worktrees = HashSet::default();
10988        for buffer in buffers {
10989            buffer.update(cx, |buffer, cx| {
10990                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10991                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10992                    && covered_worktrees.insert(worktree_id)
10993                {
10994                    language_server_names_to_stop.retain(|name| {
10995                        let old_ids_count = language_servers_to_stop.len();
10996                        let all_language_servers_with_this_name = local
10997                            .language_server_ids
10998                            .iter()
10999                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11000                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11001                        old_ids_count == language_servers_to_stop.len()
11002                    });
11003                }
11004            });
11005        }
11006        for name in language_server_names_to_stop {
11007            language_servers_to_stop.extend(
11008                local
11009                    .language_server_ids
11010                    .iter()
11011                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11012            );
11013        }
11014
11015        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11016        let tasks = language_servers_to_stop
11017            .into_iter()
11018            .map(|server| self.stop_local_language_server(server, cx))
11019            .collect::<Vec<_>>();
11020
11021        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11022    }
11023
11024    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11025        let (worktree, relative_path) =
11026            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11027
11028        let project_path = ProjectPath {
11029            worktree_id: worktree.read(cx).id(),
11030            path: relative_path,
11031        };
11032
11033        Some(
11034            self.buffer_store()
11035                .read(cx)
11036                .get_by_path(&project_path)?
11037                .read(cx),
11038        )
11039    }
11040
11041    #[cfg(any(test, feature = "test-support"))]
11042    pub fn update_diagnostics(
11043        &mut self,
11044        server_id: LanguageServerId,
11045        diagnostics: lsp::PublishDiagnosticsParams,
11046        result_id: Option<SharedString>,
11047        source_kind: DiagnosticSourceKind,
11048        disk_based_sources: &[String],
11049        cx: &mut Context<Self>,
11050    ) -> Result<()> {
11051        self.merge_lsp_diagnostics(
11052            source_kind,
11053            vec![DocumentDiagnosticsUpdate {
11054                diagnostics,
11055                result_id,
11056                server_id,
11057                disk_based_sources: Cow::Borrowed(disk_based_sources),
11058                registration_id: None,
11059            }],
11060            |_, _, _| false,
11061            cx,
11062        )
11063    }
11064
11065    pub fn merge_lsp_diagnostics(
11066        &mut self,
11067        source_kind: DiagnosticSourceKind,
11068        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11069        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11070        cx: &mut Context<Self>,
11071    ) -> Result<()> {
11072        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11073        let updates = lsp_diagnostics
11074            .into_iter()
11075            .filter_map(|update| {
11076                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11077                Some(DocumentDiagnosticsUpdate {
11078                    diagnostics: self.lsp_to_document_diagnostics(
11079                        abs_path,
11080                        source_kind,
11081                        update.server_id,
11082                        update.diagnostics,
11083                        &update.disk_based_sources,
11084                        update.registration_id.clone(),
11085                    ),
11086                    result_id: update.result_id,
11087                    server_id: update.server_id,
11088                    disk_based_sources: update.disk_based_sources,
11089                    registration_id: update.registration_id,
11090                })
11091            })
11092            .collect();
11093        self.merge_diagnostic_entries(updates, merge, cx)?;
11094        Ok(())
11095    }
11096
11097    fn lsp_to_document_diagnostics(
11098        &mut self,
11099        document_abs_path: PathBuf,
11100        source_kind: DiagnosticSourceKind,
11101        server_id: LanguageServerId,
11102        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11103        disk_based_sources: &[String],
11104        registration_id: Option<SharedString>,
11105    ) -> DocumentDiagnostics {
11106        let mut diagnostics = Vec::default();
11107        let mut primary_diagnostic_group_ids = HashMap::default();
11108        let mut sources_by_group_id = HashMap::default();
11109        let mut supporting_diagnostics = HashMap::default();
11110
11111        let adapter = self.language_server_adapter_for_id(server_id);
11112
11113        // Ensure that primary diagnostics are always the most severe
11114        lsp_diagnostics
11115            .diagnostics
11116            .sort_by_key(|item| item.severity);
11117
11118        for diagnostic in &lsp_diagnostics.diagnostics {
11119            let source = diagnostic.source.as_ref();
11120            let range = range_from_lsp(diagnostic.range);
11121            let is_supporting = diagnostic
11122                .related_information
11123                .as_ref()
11124                .is_some_and(|infos| {
11125                    infos.iter().any(|info| {
11126                        primary_diagnostic_group_ids.contains_key(&(
11127                            source,
11128                            diagnostic.code.clone(),
11129                            range_from_lsp(info.location.range),
11130                        ))
11131                    })
11132                });
11133
11134            let is_unnecessary = diagnostic
11135                .tags
11136                .as_ref()
11137                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11138
11139            let underline = self
11140                .language_server_adapter_for_id(server_id)
11141                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11142
11143            if is_supporting {
11144                supporting_diagnostics.insert(
11145                    (source, diagnostic.code.clone(), range),
11146                    (diagnostic.severity, is_unnecessary),
11147                );
11148            } else {
11149                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11150                let is_disk_based =
11151                    source.is_some_and(|source| disk_based_sources.contains(source));
11152
11153                sources_by_group_id.insert(group_id, source);
11154                primary_diagnostic_group_ids
11155                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11156
11157                diagnostics.push(DiagnosticEntry {
11158                    range,
11159                    diagnostic: Diagnostic {
11160                        source: diagnostic.source.clone(),
11161                        source_kind,
11162                        code: diagnostic.code.clone(),
11163                        code_description: diagnostic
11164                            .code_description
11165                            .as_ref()
11166                            .and_then(|d| d.href.clone()),
11167                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11168                        markdown: adapter.as_ref().and_then(|adapter| {
11169                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11170                        }),
11171                        message: diagnostic.message.trim().to_string(),
11172                        group_id,
11173                        is_primary: true,
11174                        is_disk_based,
11175                        is_unnecessary,
11176                        underline,
11177                        data: diagnostic.data.clone(),
11178                        registration_id: registration_id.clone(),
11179                    },
11180                });
11181                if let Some(infos) = &diagnostic.related_information {
11182                    for info in infos {
11183                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11184                            let range = range_from_lsp(info.location.range);
11185                            diagnostics.push(DiagnosticEntry {
11186                                range,
11187                                diagnostic: Diagnostic {
11188                                    source: diagnostic.source.clone(),
11189                                    source_kind,
11190                                    code: diagnostic.code.clone(),
11191                                    code_description: diagnostic
11192                                        .code_description
11193                                        .as_ref()
11194                                        .and_then(|d| d.href.clone()),
11195                                    severity: DiagnosticSeverity::INFORMATION,
11196                                    markdown: adapter.as_ref().and_then(|adapter| {
11197                                        adapter.diagnostic_message_to_markdown(&info.message)
11198                                    }),
11199                                    message: info.message.trim().to_string(),
11200                                    group_id,
11201                                    is_primary: false,
11202                                    is_disk_based,
11203                                    is_unnecessary: false,
11204                                    underline,
11205                                    data: diagnostic.data.clone(),
11206                                    registration_id: registration_id.clone(),
11207                                },
11208                            });
11209                        }
11210                    }
11211                }
11212            }
11213        }
11214
11215        for entry in &mut diagnostics {
11216            let diagnostic = &mut entry.diagnostic;
11217            if !diagnostic.is_primary {
11218                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11219                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11220                    source,
11221                    diagnostic.code.clone(),
11222                    entry.range.clone(),
11223                )) {
11224                    if let Some(severity) = severity {
11225                        diagnostic.severity = severity;
11226                    }
11227                    diagnostic.is_unnecessary = is_unnecessary;
11228                }
11229            }
11230        }
11231
11232        DocumentDiagnostics {
11233            diagnostics,
11234            document_abs_path,
11235            version: lsp_diagnostics.version,
11236        }
11237    }
11238
11239    fn insert_newly_running_language_server(
11240        &mut self,
11241        adapter: Arc<CachedLspAdapter>,
11242        language_server: Arc<LanguageServer>,
11243        server_id: LanguageServerId,
11244        key: LanguageServerSeed,
11245        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11246        cx: &mut Context<Self>,
11247    ) {
11248        let Some(local) = self.as_local_mut() else {
11249            return;
11250        };
11251        // If the language server for this key doesn't match the server id, don't store the
11252        // server. Which will cause it to be dropped, killing the process
11253        if local
11254            .language_server_ids
11255            .get(&key)
11256            .map(|state| state.id != server_id)
11257            .unwrap_or(false)
11258        {
11259            return;
11260        }
11261
11262        // Update language_servers collection with Running variant of LanguageServerState
11263        // indicating that the server is up and running and ready
11264        let workspace_folders = workspace_folders.lock().clone();
11265        language_server.set_workspace_folders(workspace_folders);
11266
11267        let workspace_diagnostics_refresh_tasks = language_server
11268            .capabilities()
11269            .diagnostic_provider
11270            .and_then(|provider| {
11271                local
11272                    .language_server_dynamic_registrations
11273                    .entry(server_id)
11274                    .or_default()
11275                    .diagnostics
11276                    .entry(None)
11277                    .or_insert(provider.clone());
11278                let workspace_refresher =
11279                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11280
11281                Some((None, workspace_refresher))
11282            })
11283            .into_iter()
11284            .collect();
11285        local.language_servers.insert(
11286            server_id,
11287            LanguageServerState::Running {
11288                workspace_diagnostics_refresh_tasks,
11289                adapter: adapter.clone(),
11290                server: language_server.clone(),
11291                simulate_disk_based_diagnostics_completion: None,
11292            },
11293        );
11294        local
11295            .languages
11296            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11297        if let Some(file_ops_caps) = language_server
11298            .capabilities()
11299            .workspace
11300            .as_ref()
11301            .and_then(|ws| ws.file_operations.as_ref())
11302        {
11303            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11304            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11305            if did_rename_caps.or(will_rename_caps).is_some() {
11306                let watcher = RenamePathsWatchedForServer::default()
11307                    .with_did_rename_patterns(did_rename_caps)
11308                    .with_will_rename_patterns(will_rename_caps);
11309                local
11310                    .language_server_paths_watched_for_rename
11311                    .insert(server_id, watcher);
11312            }
11313        }
11314
11315        self.language_server_statuses.insert(
11316            server_id,
11317            LanguageServerStatus {
11318                name: language_server.name(),
11319                server_version: language_server.version(),
11320                pending_work: Default::default(),
11321                has_pending_diagnostic_updates: false,
11322                progress_tokens: Default::default(),
11323                worktree: Some(key.worktree_id),
11324                binary: Some(language_server.binary().clone()),
11325                configuration: Some(language_server.configuration().clone()),
11326                workspace_folders: language_server.workspace_folders(),
11327                process_id: language_server.process_id(),
11328            },
11329        );
11330
11331        cx.emit(LspStoreEvent::LanguageServerAdded(
11332            server_id,
11333            language_server.name(),
11334            Some(key.worktree_id),
11335        ));
11336
11337        let server_capabilities = language_server.capabilities();
11338        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11339            downstream_client
11340                .send(proto::StartLanguageServer {
11341                    project_id: *project_id,
11342                    server: Some(proto::LanguageServer {
11343                        id: server_id.to_proto(),
11344                        name: language_server.name().to_string(),
11345                        worktree_id: Some(key.worktree_id.to_proto()),
11346                    }),
11347                    capabilities: serde_json::to_string(&server_capabilities)
11348                        .expect("serializing server LSP capabilities"),
11349                })
11350                .log_err();
11351        }
11352        self.lsp_server_capabilities
11353            .insert(server_id, server_capabilities);
11354
11355        // Tell the language server about every open buffer in the worktree that matches the language.
11356        // Also check for buffers in worktrees that reused this server
11357        let mut worktrees_using_server = vec![key.worktree_id];
11358        if let Some(local) = self.as_local() {
11359            // Find all worktrees that have this server in their language server tree
11360            for (worktree_id, servers) in &local.lsp_tree.instances {
11361                if *worktree_id != key.worktree_id {
11362                    for server_map in servers.roots.values() {
11363                        if server_map
11364                            .values()
11365                            .any(|(node, _)| node.id() == Some(server_id))
11366                        {
11367                            worktrees_using_server.push(*worktree_id);
11368                        }
11369                    }
11370                }
11371            }
11372        }
11373
11374        let mut buffer_paths_registered = Vec::new();
11375        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11376            let mut lsp_adapters = HashMap::default();
11377            for buffer_handle in buffer_store.buffers() {
11378                let buffer = buffer_handle.read(cx);
11379                let file = match File::from_dyn(buffer.file()) {
11380                    Some(file) => file,
11381                    None => continue,
11382                };
11383                let language = match buffer.language() {
11384                    Some(language) => language,
11385                    None => continue,
11386                };
11387
11388                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11389                    || !lsp_adapters
11390                        .entry(language.name())
11391                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11392                        .iter()
11393                        .any(|a| a.name == key.name)
11394                {
11395                    continue;
11396                }
11397                // didOpen
11398                let file = match file.as_local() {
11399                    Some(file) => file,
11400                    None => continue,
11401                };
11402
11403                let local = self.as_local_mut().unwrap();
11404
11405                let buffer_id = buffer.remote_id();
11406                if local.registered_buffers.contains_key(&buffer_id) {
11407                    let versions = local
11408                        .buffer_snapshots
11409                        .entry(buffer_id)
11410                        .or_default()
11411                        .entry(server_id)
11412                        .and_modify(|_| {
11413                            assert!(
11414                            false,
11415                            "There should not be an existing snapshot for a newly inserted buffer"
11416                        )
11417                        })
11418                        .or_insert_with(|| {
11419                            vec![LspBufferSnapshot {
11420                                version: 0,
11421                                snapshot: buffer.text_snapshot(),
11422                            }]
11423                        });
11424
11425                    let snapshot = versions.last().unwrap();
11426                    let version = snapshot.version;
11427                    let initial_snapshot = &snapshot.snapshot;
11428                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11429                    language_server.register_buffer(
11430                        uri,
11431                        adapter.language_id(&language.name()),
11432                        version,
11433                        initial_snapshot.text(),
11434                    );
11435                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11436                    local
11437                        .buffers_opened_in_servers
11438                        .entry(buffer_id)
11439                        .or_default()
11440                        .insert(server_id);
11441                }
11442                buffer_handle.update(cx, |buffer, cx| {
11443                    buffer.set_completion_triggers(
11444                        server_id,
11445                        language_server
11446                            .capabilities()
11447                            .completion_provider
11448                            .as_ref()
11449                            .and_then(|provider| {
11450                                provider
11451                                    .trigger_characters
11452                                    .as_ref()
11453                                    .map(|characters| characters.iter().cloned().collect())
11454                            })
11455                            .unwrap_or_default(),
11456                        cx,
11457                    )
11458                });
11459            }
11460        });
11461
11462        for (buffer_id, abs_path) in buffer_paths_registered {
11463            cx.emit(LspStoreEvent::LanguageServerUpdate {
11464                language_server_id: server_id,
11465                name: Some(adapter.name()),
11466                message: proto::update_language_server::Variant::RegisteredForBuffer(
11467                    proto::RegisteredForBuffer {
11468                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11469                        buffer_id: buffer_id.to_proto(),
11470                    },
11471                ),
11472            });
11473        }
11474
11475        cx.notify();
11476    }
11477
11478    pub fn language_servers_running_disk_based_diagnostics(
11479        &self,
11480    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11481        self.language_server_statuses
11482            .iter()
11483            .filter_map(|(id, status)| {
11484                if status.has_pending_diagnostic_updates {
11485                    Some(*id)
11486                } else {
11487                    None
11488                }
11489            })
11490    }
11491
11492    pub(crate) fn cancel_language_server_work_for_buffers(
11493        &mut self,
11494        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11495        cx: &mut Context<Self>,
11496    ) {
11497        if let Some((client, project_id)) = self.upstream_client() {
11498            let request = client.request(proto::CancelLanguageServerWork {
11499                project_id,
11500                work: Some(proto::cancel_language_server_work::Work::Buffers(
11501                    proto::cancel_language_server_work::Buffers {
11502                        buffer_ids: buffers
11503                            .into_iter()
11504                            .map(|b| b.read(cx).remote_id().to_proto())
11505                            .collect(),
11506                    },
11507                )),
11508            });
11509            cx.background_spawn(request).detach_and_log_err(cx);
11510        } else if let Some(local) = self.as_local() {
11511            let servers = buffers
11512                .into_iter()
11513                .flat_map(|buffer| {
11514                    buffer.update(cx, |buffer, cx| {
11515                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11516                    })
11517                })
11518                .collect::<HashSet<_>>();
11519            for server_id in servers {
11520                self.cancel_language_server_work(server_id, None, cx);
11521            }
11522        }
11523    }
11524
11525    pub(crate) fn cancel_language_server_work(
11526        &mut self,
11527        server_id: LanguageServerId,
11528        token_to_cancel: Option<ProgressToken>,
11529        cx: &mut Context<Self>,
11530    ) {
11531        if let Some(local) = self.as_local() {
11532            let status = self.language_server_statuses.get(&server_id);
11533            let server = local.language_servers.get(&server_id);
11534            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11535            {
11536                for (token, progress) in &status.pending_work {
11537                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11538                        && token != token_to_cancel
11539                    {
11540                        continue;
11541                    }
11542                    if progress.is_cancellable {
11543                        server
11544                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11545                                WorkDoneProgressCancelParams {
11546                                    token: token.to_lsp(),
11547                                },
11548                            )
11549                            .ok();
11550                    }
11551                }
11552            }
11553        } else if let Some((client, project_id)) = self.upstream_client() {
11554            let request = client.request(proto::CancelLanguageServerWork {
11555                project_id,
11556                work: Some(
11557                    proto::cancel_language_server_work::Work::LanguageServerWork(
11558                        proto::cancel_language_server_work::LanguageServerWork {
11559                            language_server_id: server_id.to_proto(),
11560                            token: token_to_cancel.map(|token| token.to_proto()),
11561                        },
11562                    ),
11563                ),
11564            });
11565            cx.background_spawn(request).detach_and_log_err(cx);
11566        }
11567    }
11568
11569    fn register_supplementary_language_server(
11570        &mut self,
11571        id: LanguageServerId,
11572        name: LanguageServerName,
11573        server: Arc<LanguageServer>,
11574        cx: &mut Context<Self>,
11575    ) {
11576        if let Some(local) = self.as_local_mut() {
11577            local
11578                .supplementary_language_servers
11579                .insert(id, (name.clone(), server));
11580            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11581        }
11582    }
11583
11584    fn unregister_supplementary_language_server(
11585        &mut self,
11586        id: LanguageServerId,
11587        cx: &mut Context<Self>,
11588    ) {
11589        if let Some(local) = self.as_local_mut() {
11590            local.supplementary_language_servers.remove(&id);
11591            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11592        }
11593    }
11594
11595    pub(crate) fn supplementary_language_servers(
11596        &self,
11597    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11598        self.as_local().into_iter().flat_map(|local| {
11599            local
11600                .supplementary_language_servers
11601                .iter()
11602                .map(|(id, (name, _))| (*id, name.clone()))
11603        })
11604    }
11605
11606    pub fn language_server_adapter_for_id(
11607        &self,
11608        id: LanguageServerId,
11609    ) -> Option<Arc<CachedLspAdapter>> {
11610        self.as_local()
11611            .and_then(|local| local.language_servers.get(&id))
11612            .and_then(|language_server_state| match language_server_state {
11613                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11614                _ => None,
11615            })
11616    }
11617
11618    pub(super) fn update_local_worktree_language_servers(
11619        &mut self,
11620        worktree_handle: &Entity<Worktree>,
11621        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11622        cx: &mut Context<Self>,
11623    ) {
11624        if changes.is_empty() {
11625            return;
11626        }
11627
11628        let Some(local) = self.as_local() else { return };
11629
11630        local.prettier_store.update(cx, |prettier_store, cx| {
11631            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11632        });
11633
11634        let worktree_id = worktree_handle.read(cx).id();
11635        let mut language_server_ids = local
11636            .language_server_ids
11637            .iter()
11638            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11639            .collect::<Vec<_>>();
11640        language_server_ids.sort();
11641        language_server_ids.dedup();
11642
11643        // let abs_path = worktree_handle.read(cx).abs_path();
11644        for server_id in &language_server_ids {
11645            if let Some(LanguageServerState::Running { server, .. }) =
11646                local.language_servers.get(server_id)
11647                && let Some(watched_paths) = local
11648                    .language_server_watched_paths
11649                    .get(server_id)
11650                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11651            {
11652                let params = lsp::DidChangeWatchedFilesParams {
11653                    changes: changes
11654                        .iter()
11655                        .filter_map(|(path, _, change)| {
11656                            if !watched_paths.is_match(path.as_std_path()) {
11657                                return None;
11658                            }
11659                            let typ = match change {
11660                                PathChange::Loaded => return None,
11661                                PathChange::Added => lsp::FileChangeType::CREATED,
11662                                PathChange::Removed => lsp::FileChangeType::DELETED,
11663                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11664                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11665                            };
11666                            let uri = lsp::Uri::from_file_path(
11667                                worktree_handle.read(cx).absolutize(&path),
11668                            )
11669                            .ok()?;
11670                            Some(lsp::FileEvent { uri, typ })
11671                        })
11672                        .collect(),
11673                };
11674                if !params.changes.is_empty() {
11675                    server
11676                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11677                        .ok();
11678                }
11679            }
11680        }
11681        for (path, _, _) in changes {
11682            if let Some(file_name) = path.file_name()
11683                && local.watched_manifest_filenames.contains(file_name)
11684            {
11685                self.request_workspace_config_refresh();
11686                break;
11687            }
11688        }
11689    }
11690
11691    pub fn wait_for_remote_buffer(
11692        &mut self,
11693        id: BufferId,
11694        cx: &mut Context<Self>,
11695    ) -> Task<Result<Entity<Buffer>>> {
11696        self.buffer_store.update(cx, |buffer_store, cx| {
11697            buffer_store.wait_for_remote_buffer(id, cx)
11698        })
11699    }
11700
11701    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11702        let mut result = proto::Symbol {
11703            language_server_name: symbol.language_server_name.0.to_string(),
11704            source_worktree_id: symbol.source_worktree_id.to_proto(),
11705            language_server_id: symbol.source_language_server_id.to_proto(),
11706            name: symbol.name.clone(),
11707            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11708            start: Some(proto::PointUtf16 {
11709                row: symbol.range.start.0.row,
11710                column: symbol.range.start.0.column,
11711            }),
11712            end: Some(proto::PointUtf16 {
11713                row: symbol.range.end.0.row,
11714                column: symbol.range.end.0.column,
11715            }),
11716            worktree_id: Default::default(),
11717            path: Default::default(),
11718            signature: Default::default(),
11719            container_name: symbol.container_name.clone(),
11720        };
11721        match &symbol.path {
11722            SymbolLocation::InProject(path) => {
11723                result.worktree_id = path.worktree_id.to_proto();
11724                result.path = path.path.to_proto();
11725            }
11726            SymbolLocation::OutsideProject {
11727                abs_path,
11728                signature,
11729            } => {
11730                result.path = abs_path.to_string_lossy().into_owned();
11731                result.signature = signature.to_vec();
11732            }
11733        }
11734        result
11735    }
11736
11737    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11738        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11739        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11740        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11741
11742        let path = if serialized_symbol.signature.is_empty() {
11743            SymbolLocation::InProject(ProjectPath {
11744                worktree_id,
11745                path: RelPath::from_proto(&serialized_symbol.path)
11746                    .context("invalid symbol path")?,
11747            })
11748        } else {
11749            SymbolLocation::OutsideProject {
11750                abs_path: Path::new(&serialized_symbol.path).into(),
11751                signature: serialized_symbol
11752                    .signature
11753                    .try_into()
11754                    .map_err(|_| anyhow!("invalid signature"))?,
11755            }
11756        };
11757
11758        let start = serialized_symbol.start.context("invalid start")?;
11759        let end = serialized_symbol.end.context("invalid end")?;
11760        Ok(CoreSymbol {
11761            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11762            source_worktree_id,
11763            source_language_server_id: LanguageServerId::from_proto(
11764                serialized_symbol.language_server_id,
11765            ),
11766            path,
11767            name: serialized_symbol.name,
11768            range: Unclipped(PointUtf16::new(start.row, start.column))
11769                ..Unclipped(PointUtf16::new(end.row, end.column)),
11770            kind,
11771            container_name: serialized_symbol.container_name,
11772        })
11773    }
11774
11775    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11776        let mut serialized_completion = proto::Completion {
11777            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11778            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11779            new_text: completion.new_text.clone(),
11780            ..proto::Completion::default()
11781        };
11782        match &completion.source {
11783            CompletionSource::Lsp {
11784                insert_range,
11785                server_id,
11786                lsp_completion,
11787                lsp_defaults,
11788                resolved,
11789            } => {
11790                let (old_insert_start, old_insert_end) = insert_range
11791                    .as_ref()
11792                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11793                    .unzip();
11794
11795                serialized_completion.old_insert_start = old_insert_start;
11796                serialized_completion.old_insert_end = old_insert_end;
11797                serialized_completion.source = proto::completion::Source::Lsp as i32;
11798                serialized_completion.server_id = server_id.0 as u64;
11799                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11800                serialized_completion.lsp_defaults = lsp_defaults
11801                    .as_deref()
11802                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11803                serialized_completion.resolved = *resolved;
11804            }
11805            CompletionSource::BufferWord {
11806                word_range,
11807                resolved,
11808            } => {
11809                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11810                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11811                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11812                serialized_completion.resolved = *resolved;
11813            }
11814            CompletionSource::Custom => {
11815                serialized_completion.source = proto::completion::Source::Custom as i32;
11816                serialized_completion.resolved = true;
11817            }
11818            CompletionSource::Dap { sort_text } => {
11819                serialized_completion.source = proto::completion::Source::Dap as i32;
11820                serialized_completion.sort_text = Some(sort_text.clone());
11821            }
11822        }
11823
11824        serialized_completion
11825    }
11826
11827    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11828        let old_replace_start = completion
11829            .old_replace_start
11830            .and_then(deserialize_anchor)
11831            .context("invalid old start")?;
11832        let old_replace_end = completion
11833            .old_replace_end
11834            .and_then(deserialize_anchor)
11835            .context("invalid old end")?;
11836        let insert_range = {
11837            match completion.old_insert_start.zip(completion.old_insert_end) {
11838                Some((start, end)) => {
11839                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11840                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11841                    Some(start..end)
11842                }
11843                None => None,
11844            }
11845        };
11846        Ok(CoreCompletion {
11847            replace_range: old_replace_start..old_replace_end,
11848            new_text: completion.new_text,
11849            source: match proto::completion::Source::from_i32(completion.source) {
11850                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11851                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11852                    insert_range,
11853                    server_id: LanguageServerId::from_proto(completion.server_id),
11854                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11855                    lsp_defaults: completion
11856                        .lsp_defaults
11857                        .as_deref()
11858                        .map(serde_json::from_slice)
11859                        .transpose()?,
11860                    resolved: completion.resolved,
11861                },
11862                Some(proto::completion::Source::BufferWord) => {
11863                    let word_range = completion
11864                        .buffer_word_start
11865                        .and_then(deserialize_anchor)
11866                        .context("invalid buffer word start")?
11867                        ..completion
11868                            .buffer_word_end
11869                            .and_then(deserialize_anchor)
11870                            .context("invalid buffer word end")?;
11871                    CompletionSource::BufferWord {
11872                        word_range,
11873                        resolved: completion.resolved,
11874                    }
11875                }
11876                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11877                    sort_text: completion
11878                        .sort_text
11879                        .context("expected sort text to exist")?,
11880                },
11881                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11882            },
11883        })
11884    }
11885
11886    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11887        let (kind, lsp_action) = match &action.lsp_action {
11888            LspAction::Action(code_action) => (
11889                proto::code_action::Kind::Action as i32,
11890                serde_json::to_vec(code_action).unwrap(),
11891            ),
11892            LspAction::Command(command) => (
11893                proto::code_action::Kind::Command as i32,
11894                serde_json::to_vec(command).unwrap(),
11895            ),
11896            LspAction::CodeLens(code_lens) => (
11897                proto::code_action::Kind::CodeLens as i32,
11898                serde_json::to_vec(code_lens).unwrap(),
11899            ),
11900        };
11901
11902        proto::CodeAction {
11903            server_id: action.server_id.0 as u64,
11904            start: Some(serialize_anchor(&action.range.start)),
11905            end: Some(serialize_anchor(&action.range.end)),
11906            lsp_action,
11907            kind,
11908            resolved: action.resolved,
11909        }
11910    }
11911
11912    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11913        let start = action
11914            .start
11915            .and_then(deserialize_anchor)
11916            .context("invalid start")?;
11917        let end = action
11918            .end
11919            .and_then(deserialize_anchor)
11920            .context("invalid end")?;
11921        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11922            Some(proto::code_action::Kind::Action) => {
11923                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11924            }
11925            Some(proto::code_action::Kind::Command) => {
11926                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11927            }
11928            Some(proto::code_action::Kind::CodeLens) => {
11929                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11930            }
11931            None => anyhow::bail!("Unknown action kind {}", action.kind),
11932        };
11933        Ok(CodeAction {
11934            server_id: LanguageServerId(action.server_id as usize),
11935            range: start..end,
11936            resolved: action.resolved,
11937            lsp_action,
11938        })
11939    }
11940
11941    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11942        match &formatting_result {
11943            Ok(_) => self.last_formatting_failure = None,
11944            Err(error) => {
11945                let error_string = format!("{error:#}");
11946                log::error!("Formatting failed: {error_string}");
11947                self.last_formatting_failure
11948                    .replace(error_string.lines().join(" "));
11949            }
11950        }
11951    }
11952
11953    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11954        self.lsp_server_capabilities.remove(&for_server);
11955        self.semantic_token_config.remove_server_data(for_server);
11956        for lsp_data in self.lsp_data.values_mut() {
11957            lsp_data.remove_server_data(for_server);
11958        }
11959        if let Some(local) = self.as_local_mut() {
11960            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11961            local
11962                .workspace_pull_diagnostics_result_ids
11963                .remove(&for_server);
11964            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11965                buffer_servers.remove(&for_server);
11966            }
11967        }
11968    }
11969
11970    pub fn result_id_for_buffer_pull(
11971        &self,
11972        server_id: LanguageServerId,
11973        buffer_id: BufferId,
11974        registration_id: &Option<SharedString>,
11975        cx: &App,
11976    ) -> Option<SharedString> {
11977        let abs_path = self
11978            .buffer_store
11979            .read(cx)
11980            .get(buffer_id)
11981            .and_then(|b| File::from_dyn(b.read(cx).file()))
11982            .map(|f| f.abs_path(cx))?;
11983        self.as_local()?
11984            .buffer_pull_diagnostics_result_ids
11985            .get(&server_id)?
11986            .get(registration_id)?
11987            .get(&abs_path)?
11988            .clone()
11989    }
11990
11991    /// Gets all result_ids for a workspace diagnostics pull request.
11992    /// 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.
11993    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
11994    pub fn result_ids_for_workspace_refresh(
11995        &self,
11996        server_id: LanguageServerId,
11997        registration_id: &Option<SharedString>,
11998    ) -> HashMap<PathBuf, SharedString> {
11999        let Some(local) = self.as_local() else {
12000            return HashMap::default();
12001        };
12002        local
12003            .workspace_pull_diagnostics_result_ids
12004            .get(&server_id)
12005            .into_iter()
12006            .filter_map(|diagnostics| diagnostics.get(registration_id))
12007            .flatten()
12008            .filter_map(|(abs_path, result_id)| {
12009                let result_id = local
12010                    .buffer_pull_diagnostics_result_ids
12011                    .get(&server_id)
12012                    .and_then(|buffer_ids_result_ids| {
12013                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12014                    })
12015                    .cloned()
12016                    .flatten()
12017                    .or_else(|| result_id.clone())?;
12018                Some((abs_path.clone(), result_id))
12019            })
12020            .collect()
12021    }
12022
12023    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12024        if let Some(LanguageServerState::Running {
12025            workspace_diagnostics_refresh_tasks,
12026            ..
12027        }) = self
12028            .as_local_mut()
12029            .and_then(|local| local.language_servers.get_mut(&server_id))
12030        {
12031            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12032                diagnostics.refresh_tx.try_send(()).ok();
12033            }
12034        }
12035    }
12036
12037    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12038    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12039    /// which requires refreshing both workspace and document diagnostics.
12040    pub fn pull_document_diagnostics_for_server(
12041        &mut self,
12042        server_id: LanguageServerId,
12043        source_buffer_id: Option<BufferId>,
12044        cx: &mut Context<Self>,
12045    ) -> Shared<Task<()>> {
12046        let Some(local) = self.as_local_mut() else {
12047            return Task::ready(()).shared();
12048        };
12049        let mut buffers_to_refresh = HashSet::default();
12050        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12051            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12052                buffers_to_refresh.insert(*buffer_id);
12053            }
12054        }
12055
12056        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12057    }
12058
12059    pub fn pull_document_diagnostics_for_buffer_edit(
12060        &mut self,
12061        buffer_id: BufferId,
12062        cx: &mut Context<Self>,
12063    ) {
12064        let Some(local) = self.as_local_mut() else {
12065            return;
12066        };
12067        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12068        else {
12069            return;
12070        };
12071        for server_id in languages_servers {
12072            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12073        }
12074    }
12075
12076    fn apply_workspace_diagnostic_report(
12077        &mut self,
12078        server_id: LanguageServerId,
12079        report: lsp::WorkspaceDiagnosticReportResult,
12080        registration_id: Option<SharedString>,
12081        cx: &mut Context<Self>,
12082    ) {
12083        let mut workspace_diagnostics =
12084            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12085                report,
12086                server_id,
12087                registration_id,
12088            );
12089        workspace_diagnostics.retain(|d| match &d.diagnostics {
12090            LspPullDiagnostics::Response {
12091                server_id,
12092                registration_id,
12093                ..
12094            } => self.diagnostic_registration_exists(*server_id, registration_id),
12095            LspPullDiagnostics::Default => false,
12096        });
12097        let mut unchanged_buffers = HashMap::default();
12098        let workspace_diagnostics_updates = workspace_diagnostics
12099            .into_iter()
12100            .filter_map(
12101                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12102                    LspPullDiagnostics::Response {
12103                        server_id,
12104                        uri,
12105                        diagnostics,
12106                        registration_id,
12107                    } => Some((
12108                        server_id,
12109                        uri,
12110                        diagnostics,
12111                        workspace_diagnostics.version,
12112                        registration_id,
12113                    )),
12114                    LspPullDiagnostics::Default => None,
12115                },
12116            )
12117            .fold(
12118                HashMap::default(),
12119                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12120                    let (result_id, diagnostics) = match diagnostics {
12121                        PulledDiagnostics::Unchanged { result_id } => {
12122                            unchanged_buffers
12123                                .entry(new_registration_id.clone())
12124                                .or_insert_with(HashSet::default)
12125                                .insert(uri.clone());
12126                            (Some(result_id), Vec::new())
12127                        }
12128                        PulledDiagnostics::Changed {
12129                            result_id,
12130                            diagnostics,
12131                        } => (result_id, diagnostics),
12132                    };
12133                    let disk_based_sources = Cow::Owned(
12134                        self.language_server_adapter_for_id(server_id)
12135                            .as_ref()
12136                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12137                            .unwrap_or(&[])
12138                            .to_vec(),
12139                    );
12140
12141                    let Some(abs_path) = uri.to_file_path().ok() else {
12142                        return acc;
12143                    };
12144                    let Some((worktree, relative_path)) =
12145                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12146                    else {
12147                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12148                        return acc;
12149                    };
12150                    let worktree_id = worktree.read(cx).id();
12151                    let project_path = ProjectPath {
12152                        worktree_id,
12153                        path: relative_path,
12154                    };
12155                    if let Some(local_lsp_store) = self.as_local_mut() {
12156                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12157                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12158                    }
12159                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12160                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12161                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12162                        acc.entry(server_id)
12163                            .or_insert_with(HashMap::default)
12164                            .entry(new_registration_id.clone())
12165                            .or_insert_with(Vec::new)
12166                            .push(DocumentDiagnosticsUpdate {
12167                                server_id,
12168                                diagnostics: lsp::PublishDiagnosticsParams {
12169                                    uri,
12170                                    diagnostics,
12171                                    version,
12172                                },
12173                                result_id: result_id.map(SharedString::new),
12174                                disk_based_sources,
12175                                registration_id: new_registration_id,
12176                            });
12177                    }
12178                    acc
12179                },
12180            );
12181
12182        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12183            for (registration_id, diagnostic_updates) in diagnostic_updates {
12184                self.merge_lsp_diagnostics(
12185                    DiagnosticSourceKind::Pulled,
12186                    diagnostic_updates,
12187                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12188                        DiagnosticSourceKind::Pulled => {
12189                            old_diagnostic.registration_id != registration_id
12190                                || unchanged_buffers
12191                                    .get(&old_diagnostic.registration_id)
12192                                    .is_some_and(|unchanged_buffers| {
12193                                        unchanged_buffers.contains(&document_uri)
12194                                    })
12195                        }
12196                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12197                    },
12198                    cx,
12199                )
12200                .log_err();
12201            }
12202        }
12203    }
12204
12205    fn register_server_capabilities(
12206        &mut self,
12207        server_id: LanguageServerId,
12208        params: lsp::RegistrationParams,
12209        cx: &mut Context<Self>,
12210    ) -> anyhow::Result<()> {
12211        let server = self
12212            .language_server_for_id(server_id)
12213            .with_context(|| format!("no server {server_id} found"))?;
12214        for reg in params.registrations {
12215            match reg.method.as_str() {
12216                "workspace/didChangeWatchedFiles" => {
12217                    if let Some(options) = reg.register_options {
12218                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12219                            let caps = serde_json::from_value(options)?;
12220                            local_lsp_store
12221                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12222                            true
12223                        } else {
12224                            false
12225                        };
12226                        if notify {
12227                            notify_server_capabilities_updated(&server, cx);
12228                        }
12229                    }
12230                }
12231                "workspace/didChangeConfiguration" => {
12232                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12233                }
12234                "workspace/didChangeWorkspaceFolders" => {
12235                    // In this case register options is an empty object, we can ignore it
12236                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12237                        supported: Some(true),
12238                        change_notifications: Some(OneOf::Right(reg.id)),
12239                    };
12240                    server.update_capabilities(|capabilities| {
12241                        capabilities
12242                            .workspace
12243                            .get_or_insert_default()
12244                            .workspace_folders = Some(caps);
12245                    });
12246                    notify_server_capabilities_updated(&server, cx);
12247                }
12248                "workspace/symbol" => {
12249                    let options = parse_register_capabilities(reg)?;
12250                    server.update_capabilities(|capabilities| {
12251                        capabilities.workspace_symbol_provider = Some(options);
12252                    });
12253                    notify_server_capabilities_updated(&server, cx);
12254                }
12255                "workspace/fileOperations" => {
12256                    if let Some(options) = reg.register_options {
12257                        let caps = serde_json::from_value(options)?;
12258                        server.update_capabilities(|capabilities| {
12259                            capabilities
12260                                .workspace
12261                                .get_or_insert_default()
12262                                .file_operations = Some(caps);
12263                        });
12264                        notify_server_capabilities_updated(&server, cx);
12265                    }
12266                }
12267                "workspace/executeCommand" => {
12268                    if let Some(options) = reg.register_options {
12269                        let options = serde_json::from_value(options)?;
12270                        server.update_capabilities(|capabilities| {
12271                            capabilities.execute_command_provider = Some(options);
12272                        });
12273                        notify_server_capabilities_updated(&server, cx);
12274                    }
12275                }
12276                "textDocument/rangeFormatting" => {
12277                    let options = parse_register_capabilities(reg)?;
12278                    server.update_capabilities(|capabilities| {
12279                        capabilities.document_range_formatting_provider = Some(options);
12280                    });
12281                    notify_server_capabilities_updated(&server, cx);
12282                }
12283                "textDocument/onTypeFormatting" => {
12284                    if let Some(options) = reg
12285                        .register_options
12286                        .map(serde_json::from_value)
12287                        .transpose()?
12288                    {
12289                        server.update_capabilities(|capabilities| {
12290                            capabilities.document_on_type_formatting_provider = Some(options);
12291                        });
12292                        notify_server_capabilities_updated(&server, cx);
12293                    }
12294                }
12295                "textDocument/formatting" => {
12296                    let options = parse_register_capabilities(reg)?;
12297                    server.update_capabilities(|capabilities| {
12298                        capabilities.document_formatting_provider = Some(options);
12299                    });
12300                    notify_server_capabilities_updated(&server, cx);
12301                }
12302                "textDocument/rename" => {
12303                    let options = parse_register_capabilities(reg)?;
12304                    server.update_capabilities(|capabilities| {
12305                        capabilities.rename_provider = Some(options);
12306                    });
12307                    notify_server_capabilities_updated(&server, cx);
12308                }
12309                "textDocument/inlayHint" => {
12310                    let options = parse_register_capabilities(reg)?;
12311                    server.update_capabilities(|capabilities| {
12312                        capabilities.inlay_hint_provider = Some(options);
12313                    });
12314                    notify_server_capabilities_updated(&server, cx);
12315                }
12316                "textDocument/documentSymbol" => {
12317                    let options = parse_register_capabilities(reg)?;
12318                    server.update_capabilities(|capabilities| {
12319                        capabilities.document_symbol_provider = Some(options);
12320                    });
12321                    notify_server_capabilities_updated(&server, cx);
12322                }
12323                "textDocument/codeAction" => {
12324                    let options = parse_register_capabilities(reg)?;
12325                    let provider = match options {
12326                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12327                        OneOf::Right(caps) => caps,
12328                    };
12329                    server.update_capabilities(|capabilities| {
12330                        capabilities.code_action_provider = Some(provider);
12331                    });
12332                    notify_server_capabilities_updated(&server, cx);
12333                }
12334                "textDocument/definition" => {
12335                    let options = parse_register_capabilities(reg)?;
12336                    server.update_capabilities(|capabilities| {
12337                        capabilities.definition_provider = Some(options);
12338                    });
12339                    notify_server_capabilities_updated(&server, cx);
12340                }
12341                "textDocument/completion" => {
12342                    if let Some(caps) = reg
12343                        .register_options
12344                        .map(serde_json::from_value::<CompletionOptions>)
12345                        .transpose()?
12346                    {
12347                        server.update_capabilities(|capabilities| {
12348                            capabilities.completion_provider = Some(caps.clone());
12349                        });
12350
12351                        if let Some(local) = self.as_local() {
12352                            let mut buffers_with_language_server = Vec::new();
12353                            for handle in self.buffer_store.read(cx).buffers() {
12354                                let buffer_id = handle.read(cx).remote_id();
12355                                if local
12356                                    .buffers_opened_in_servers
12357                                    .get(&buffer_id)
12358                                    .filter(|s| s.contains(&server_id))
12359                                    .is_some()
12360                                {
12361                                    buffers_with_language_server.push(handle);
12362                                }
12363                            }
12364                            let triggers = caps
12365                                .trigger_characters
12366                                .unwrap_or_default()
12367                                .into_iter()
12368                                .collect::<BTreeSet<_>>();
12369                            for handle in buffers_with_language_server {
12370                                let triggers = triggers.clone();
12371                                let _ = handle.update(cx, move |buffer, cx| {
12372                                    buffer.set_completion_triggers(server_id, triggers, cx);
12373                                });
12374                            }
12375                        }
12376                        notify_server_capabilities_updated(&server, cx);
12377                    }
12378                }
12379                "textDocument/hover" => {
12380                    let options = parse_register_capabilities(reg)?;
12381                    let provider = match options {
12382                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12383                        OneOf::Right(caps) => caps,
12384                    };
12385                    server.update_capabilities(|capabilities| {
12386                        capabilities.hover_provider = Some(provider);
12387                    });
12388                    notify_server_capabilities_updated(&server, cx);
12389                }
12390                "textDocument/signatureHelp" => {
12391                    if let Some(caps) = reg
12392                        .register_options
12393                        .map(serde_json::from_value)
12394                        .transpose()?
12395                    {
12396                        server.update_capabilities(|capabilities| {
12397                            capabilities.signature_help_provider = Some(caps);
12398                        });
12399                        notify_server_capabilities_updated(&server, cx);
12400                    }
12401                }
12402                "textDocument/didChange" => {
12403                    if let Some(sync_kind) = reg
12404                        .register_options
12405                        .and_then(|opts| opts.get("syncKind").cloned())
12406                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12407                        .transpose()?
12408                    {
12409                        server.update_capabilities(|capabilities| {
12410                            let mut sync_options =
12411                                Self::take_text_document_sync_options(capabilities);
12412                            sync_options.change = Some(sync_kind);
12413                            capabilities.text_document_sync =
12414                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12415                        });
12416                        notify_server_capabilities_updated(&server, cx);
12417                    }
12418                }
12419                "textDocument/didSave" => {
12420                    if let Some(include_text) = reg
12421                        .register_options
12422                        .map(|opts| {
12423                            let transpose = opts
12424                                .get("includeText")
12425                                .cloned()
12426                                .map(serde_json::from_value::<Option<bool>>)
12427                                .transpose();
12428                            match transpose {
12429                                Ok(value) => Ok(value.flatten()),
12430                                Err(e) => Err(e),
12431                            }
12432                        })
12433                        .transpose()?
12434                    {
12435                        server.update_capabilities(|capabilities| {
12436                            let mut sync_options =
12437                                Self::take_text_document_sync_options(capabilities);
12438                            sync_options.save =
12439                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12440                                    include_text,
12441                                }));
12442                            capabilities.text_document_sync =
12443                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12444                        });
12445                        notify_server_capabilities_updated(&server, cx);
12446                    }
12447                }
12448                "textDocument/codeLens" => {
12449                    if let Some(caps) = reg
12450                        .register_options
12451                        .map(serde_json::from_value)
12452                        .transpose()?
12453                    {
12454                        server.update_capabilities(|capabilities| {
12455                            capabilities.code_lens_provider = Some(caps);
12456                        });
12457                        notify_server_capabilities_updated(&server, cx);
12458                    }
12459                }
12460                "textDocument/diagnostic" => {
12461                    if let Some(caps) = reg
12462                        .register_options
12463                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12464                        .transpose()?
12465                    {
12466                        let local = self
12467                            .as_local_mut()
12468                            .context("Expected LSP Store to be local")?;
12469                        let state = local
12470                            .language_servers
12471                            .get_mut(&server_id)
12472                            .context("Could not obtain Language Servers state")?;
12473                        local
12474                            .language_server_dynamic_registrations
12475                            .entry(server_id)
12476                            .or_default()
12477                            .diagnostics
12478                            .insert(Some(reg.id.clone()), caps.clone());
12479
12480                        let supports_workspace_diagnostics =
12481                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12482                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12483                                    diagnostic_options.workspace_diagnostics
12484                                }
12485                                DiagnosticServerCapabilities::RegistrationOptions(
12486                                    diagnostic_registration_options,
12487                                ) => {
12488                                    diagnostic_registration_options
12489                                        .diagnostic_options
12490                                        .workspace_diagnostics
12491                                }
12492                            };
12493
12494                        if supports_workspace_diagnostics(&caps) {
12495                            if let LanguageServerState::Running {
12496                                workspace_diagnostics_refresh_tasks,
12497                                ..
12498                            } = state
12499                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12500                                    Some(reg.id.clone()),
12501                                    caps.clone(),
12502                                    server.clone(),
12503                                    cx,
12504                                )
12505                            {
12506                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12507                            }
12508                        }
12509
12510                        server.update_capabilities(|capabilities| {
12511                            capabilities.diagnostic_provider = Some(caps);
12512                        });
12513
12514                        notify_server_capabilities_updated(&server, cx);
12515
12516                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12517                    }
12518                }
12519                "textDocument/documentColor" => {
12520                    let options = parse_register_capabilities(reg)?;
12521                    let provider = match options {
12522                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12523                        OneOf::Right(caps) => caps,
12524                    };
12525                    server.update_capabilities(|capabilities| {
12526                        capabilities.color_provider = Some(provider);
12527                    });
12528                    notify_server_capabilities_updated(&server, cx);
12529                }
12530                "textDocument/foldingRange" => {
12531                    let options = parse_register_capabilities(reg)?;
12532                    let provider = match options {
12533                        OneOf::Left(value) => lsp::FoldingRangeProviderCapability::Simple(value),
12534                        OneOf::Right(caps) => caps,
12535                    };
12536                    server.update_capabilities(|capabilities| {
12537                        capabilities.folding_range_provider = Some(provider);
12538                    });
12539                    notify_server_capabilities_updated(&server, cx);
12540                }
12541                _ => log::warn!("unhandled capability registration: {reg:?}"),
12542            }
12543        }
12544
12545        Ok(())
12546    }
12547
12548    fn unregister_server_capabilities(
12549        &mut self,
12550        server_id: LanguageServerId,
12551        params: lsp::UnregistrationParams,
12552        cx: &mut Context<Self>,
12553    ) -> anyhow::Result<()> {
12554        let server = self
12555            .language_server_for_id(server_id)
12556            .with_context(|| format!("no server {server_id} found"))?;
12557        for unreg in params.unregisterations.iter() {
12558            match unreg.method.as_str() {
12559                "workspace/didChangeWatchedFiles" => {
12560                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12561                        local_lsp_store
12562                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12563                        true
12564                    } else {
12565                        false
12566                    };
12567                    if notify {
12568                        notify_server_capabilities_updated(&server, cx);
12569                    }
12570                }
12571                "workspace/didChangeConfiguration" => {
12572                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12573                }
12574                "workspace/didChangeWorkspaceFolders" => {
12575                    server.update_capabilities(|capabilities| {
12576                        capabilities
12577                            .workspace
12578                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12579                                workspace_folders: None,
12580                                file_operations: None,
12581                            })
12582                            .workspace_folders = None;
12583                    });
12584                    notify_server_capabilities_updated(&server, cx);
12585                }
12586                "workspace/symbol" => {
12587                    server.update_capabilities(|capabilities| {
12588                        capabilities.workspace_symbol_provider = None
12589                    });
12590                    notify_server_capabilities_updated(&server, cx);
12591                }
12592                "workspace/fileOperations" => {
12593                    server.update_capabilities(|capabilities| {
12594                        capabilities
12595                            .workspace
12596                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12597                                workspace_folders: None,
12598                                file_operations: None,
12599                            })
12600                            .file_operations = None;
12601                    });
12602                    notify_server_capabilities_updated(&server, cx);
12603                }
12604                "workspace/executeCommand" => {
12605                    server.update_capabilities(|capabilities| {
12606                        capabilities.execute_command_provider = None;
12607                    });
12608                    notify_server_capabilities_updated(&server, cx);
12609                }
12610                "textDocument/rangeFormatting" => {
12611                    server.update_capabilities(|capabilities| {
12612                        capabilities.document_range_formatting_provider = None
12613                    });
12614                    notify_server_capabilities_updated(&server, cx);
12615                }
12616                "textDocument/onTypeFormatting" => {
12617                    server.update_capabilities(|capabilities| {
12618                        capabilities.document_on_type_formatting_provider = None;
12619                    });
12620                    notify_server_capabilities_updated(&server, cx);
12621                }
12622                "textDocument/formatting" => {
12623                    server.update_capabilities(|capabilities| {
12624                        capabilities.document_formatting_provider = None;
12625                    });
12626                    notify_server_capabilities_updated(&server, cx);
12627                }
12628                "textDocument/rename" => {
12629                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12630                    notify_server_capabilities_updated(&server, cx);
12631                }
12632                "textDocument/codeAction" => {
12633                    server.update_capabilities(|capabilities| {
12634                        capabilities.code_action_provider = None;
12635                    });
12636                    notify_server_capabilities_updated(&server, cx);
12637                }
12638                "textDocument/definition" => {
12639                    server.update_capabilities(|capabilities| {
12640                        capabilities.definition_provider = None;
12641                    });
12642                    notify_server_capabilities_updated(&server, cx);
12643                }
12644                "textDocument/completion" => {
12645                    server.update_capabilities(|capabilities| {
12646                        capabilities.completion_provider = None;
12647                    });
12648                    notify_server_capabilities_updated(&server, cx);
12649                }
12650                "textDocument/hover" => {
12651                    server.update_capabilities(|capabilities| {
12652                        capabilities.hover_provider = None;
12653                    });
12654                    notify_server_capabilities_updated(&server, cx);
12655                }
12656                "textDocument/signatureHelp" => {
12657                    server.update_capabilities(|capabilities| {
12658                        capabilities.signature_help_provider = None;
12659                    });
12660                    notify_server_capabilities_updated(&server, cx);
12661                }
12662                "textDocument/didChange" => {
12663                    server.update_capabilities(|capabilities| {
12664                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12665                        sync_options.change = None;
12666                        capabilities.text_document_sync =
12667                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12668                    });
12669                    notify_server_capabilities_updated(&server, cx);
12670                }
12671                "textDocument/didSave" => {
12672                    server.update_capabilities(|capabilities| {
12673                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12674                        sync_options.save = None;
12675                        capabilities.text_document_sync =
12676                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12677                    });
12678                    notify_server_capabilities_updated(&server, cx);
12679                }
12680                "textDocument/codeLens" => {
12681                    server.update_capabilities(|capabilities| {
12682                        capabilities.code_lens_provider = None;
12683                    });
12684                    notify_server_capabilities_updated(&server, cx);
12685                }
12686                "textDocument/diagnostic" => {
12687                    let local = self
12688                        .as_local_mut()
12689                        .context("Expected LSP Store to be local")?;
12690
12691                    let state = local
12692                        .language_servers
12693                        .get_mut(&server_id)
12694                        .context("Could not obtain Language Servers state")?;
12695                    let registrations = local
12696                        .language_server_dynamic_registrations
12697                        .get_mut(&server_id)
12698                        .with_context(|| {
12699                            format!("Expected dynamic registration to exist for server {server_id}")
12700                        })?;
12701                    registrations.diagnostics
12702                        .remove(&Some(unreg.id.clone()))
12703                        .with_context(|| format!(
12704                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12705                            unreg.id)
12706                        )?;
12707                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12708
12709                    if let LanguageServerState::Running {
12710                        workspace_diagnostics_refresh_tasks,
12711                        ..
12712                    } = state
12713                    {
12714                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12715                    }
12716
12717                    self.clear_unregistered_diagnostics(
12718                        server_id,
12719                        SharedString::from(unreg.id.clone()),
12720                        cx,
12721                    )?;
12722
12723                    if removed_last_diagnostic_provider {
12724                        server.update_capabilities(|capabilities| {
12725                            debug_assert!(capabilities.diagnostic_provider.is_some());
12726                            capabilities.diagnostic_provider = None;
12727                        });
12728                    }
12729
12730                    notify_server_capabilities_updated(&server, cx);
12731                }
12732                "textDocument/documentColor" => {
12733                    server.update_capabilities(|capabilities| {
12734                        capabilities.color_provider = None;
12735                    });
12736                    notify_server_capabilities_updated(&server, cx);
12737                }
12738                "textDocument/foldingRange" => {
12739                    server.update_capabilities(|capabilities| {
12740                        capabilities.folding_range_provider = None;
12741                    });
12742                    notify_server_capabilities_updated(&server, cx);
12743                }
12744                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12745            }
12746        }
12747
12748        Ok(())
12749    }
12750
12751    fn clear_unregistered_diagnostics(
12752        &mut self,
12753        server_id: LanguageServerId,
12754        cleared_registration_id: SharedString,
12755        cx: &mut Context<Self>,
12756    ) -> anyhow::Result<()> {
12757        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12758
12759        self.buffer_store.update(cx, |buffer_store, cx| {
12760            for buffer_handle in buffer_store.buffers() {
12761                let buffer = buffer_handle.read(cx);
12762                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12763                let Some(abs_path) = abs_path else {
12764                    continue;
12765                };
12766                affected_abs_paths.insert(abs_path);
12767            }
12768        });
12769
12770        let local = self.as_local().context("Expected LSP Store to be local")?;
12771        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12772            let Some(worktree) = self
12773                .worktree_store
12774                .read(cx)
12775                .worktree_for_id(*worktree_id, cx)
12776            else {
12777                continue;
12778            };
12779
12780            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
12781                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
12782                    let has_matching_registration =
12783                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
12784                            entry.diagnostic.registration_id.as_ref()
12785                                == Some(&cleared_registration_id)
12786                        });
12787                    if has_matching_registration {
12788                        let abs_path = worktree.read(cx).absolutize(rel_path);
12789                        affected_abs_paths.insert(abs_path);
12790                    }
12791                }
12792            }
12793        }
12794
12795        if affected_abs_paths.is_empty() {
12796            return Ok(());
12797        }
12798
12799        // Send a fake diagnostic update which clears the state for the registration ID
12800        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
12801            affected_abs_paths
12802                .into_iter()
12803                .map(|abs_path| DocumentDiagnosticsUpdate {
12804                    diagnostics: DocumentDiagnostics {
12805                        diagnostics: Vec::new(),
12806                        document_abs_path: abs_path,
12807                        version: None,
12808                    },
12809                    result_id: None,
12810                    registration_id: Some(cleared_registration_id.clone()),
12811                    server_id,
12812                    disk_based_sources: Cow::Borrowed(&[]),
12813                })
12814                .collect();
12815
12816        let merge_registration_id = cleared_registration_id.clone();
12817        self.merge_diagnostic_entries(
12818            clears,
12819            move |_, diagnostic, _| {
12820                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
12821                    diagnostic.registration_id != Some(merge_registration_id.clone())
12822                } else {
12823                    true
12824                }
12825            },
12826            cx,
12827        )?;
12828
12829        Ok(())
12830    }
12831
12832    async fn deduplicate_range_based_lsp_requests<T>(
12833        lsp_store: &Entity<Self>,
12834        server_id: Option<LanguageServerId>,
12835        lsp_request_id: LspRequestId,
12836        proto_request: &T::ProtoRequest,
12837        range: Range<Anchor>,
12838        cx: &mut AsyncApp,
12839    ) -> Result<()>
12840    where
12841        T: LspCommand,
12842        T::ProtoRequest: proto::LspRequestMessage,
12843    {
12844        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12845        let version = deserialize_version(proto_request.buffer_version());
12846        let buffer = lsp_store.update(cx, |this, cx| {
12847            this.buffer_store.read(cx).get_existing(buffer_id)
12848        })?;
12849        buffer
12850            .update(cx, |buffer, _| buffer.wait_for_version(version))
12851            .await?;
12852        lsp_store.update(cx, |lsp_store, cx| {
12853            let buffer_snapshot = buffer.read(cx).snapshot();
12854            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12855            let chunks_queried_for = lsp_data
12856                .inlay_hints
12857                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
12858                .collect::<Vec<_>>();
12859            match chunks_queried_for.as_slice() {
12860                &[chunk] => {
12861                    let key = LspKey {
12862                        request_type: TypeId::of::<T>(),
12863                        server_queried: server_id,
12864                    };
12865                    let previous_request = lsp_data
12866                        .chunk_lsp_requests
12867                        .entry(key)
12868                        .or_default()
12869                        .insert(chunk, lsp_request_id);
12870                    if let Some((previous_request, running_requests)) =
12871                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12872                    {
12873                        running_requests.remove(&previous_request);
12874                    }
12875                }
12876                _ambiguous_chunks => {
12877                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12878                    // there, a buffer version-based check will be performed and outdated requests discarded.
12879                }
12880            }
12881            anyhow::Ok(())
12882        })?;
12883
12884        Ok(())
12885    }
12886
12887    async fn query_lsp_locally<T>(
12888        lsp_store: Entity<Self>,
12889        for_server_id: Option<LanguageServerId>,
12890        sender_id: proto::PeerId,
12891        lsp_request_id: LspRequestId,
12892        proto_request: T::ProtoRequest,
12893        position: Option<Anchor>,
12894        cx: &mut AsyncApp,
12895    ) -> Result<()>
12896    where
12897        T: LspCommand + Clone,
12898        T::ProtoRequest: proto::LspRequestMessage,
12899        <T::ProtoRequest as proto::RequestMessage>::Response:
12900            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12901    {
12902        let (buffer_version, buffer) =
12903            Self::wait_for_buffer_version::<T>(&lsp_store, &proto_request, cx).await?;
12904        let request =
12905            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12906        let key = LspKey {
12907            request_type: TypeId::of::<T>(),
12908            server_queried: for_server_id,
12909        };
12910        lsp_store.update(cx, |lsp_store, cx| {
12911            let request_task = match for_server_id {
12912                Some(server_id) => {
12913                    let server_task = lsp_store.request_lsp(
12914                        buffer.clone(),
12915                        LanguageServerToQuery::Other(server_id),
12916                        request.clone(),
12917                        cx,
12918                    );
12919                    cx.background_spawn(async move {
12920                        let mut responses = Vec::new();
12921                        match server_task.await {
12922                            Ok(response) => responses.push((server_id, response)),
12923                            // rust-analyzer likes to error with this when its still loading up
12924                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
12925                            Err(e) => log::error!(
12926                                "Error handling response for request {request:?}: {e:#}"
12927                            ),
12928                        }
12929                        responses
12930                    })
12931                }
12932                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12933            };
12934            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12935            if T::ProtoRequest::stop_previous_requests() {
12936                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12937                    lsp_requests.clear();
12938                }
12939            }
12940            lsp_data.lsp_requests.entry(key).or_default().insert(
12941                lsp_request_id,
12942                cx.spawn(async move |lsp_store, cx| {
12943                    let response = request_task.await;
12944                    lsp_store
12945                        .update(cx, |lsp_store, cx| {
12946                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12947                            {
12948                                let response = response
12949                                    .into_iter()
12950                                    .map(|(server_id, response)| {
12951                                        (
12952                                            server_id.to_proto(),
12953                                            T::response_to_proto(
12954                                                response,
12955                                                lsp_store,
12956                                                sender_id,
12957                                                &buffer_version,
12958                                                cx,
12959                                            )
12960                                            .into(),
12961                                        )
12962                                    })
12963                                    .collect::<HashMap<_, _>>();
12964                                match client.send_lsp_response::<T::ProtoRequest>(
12965                                    project_id,
12966                                    lsp_request_id,
12967                                    response,
12968                                ) {
12969                                    Ok(()) => {}
12970                                    Err(e) => {
12971                                        log::error!("Failed to send LSP response: {e:#}",)
12972                                    }
12973                                }
12974                            }
12975                        })
12976                        .ok();
12977                }),
12978            );
12979        });
12980        Ok(())
12981    }
12982
12983    async fn wait_for_buffer_version<T>(
12984        lsp_store: &Entity<Self>,
12985        proto_request: &T::ProtoRequest,
12986        cx: &mut AsyncApp,
12987    ) -> Result<(Global, Entity<Buffer>)>
12988    where
12989        T: LspCommand,
12990        T::ProtoRequest: proto::LspRequestMessage,
12991    {
12992        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12993        let version = deserialize_version(proto_request.buffer_version());
12994        let buffer = lsp_store.update(cx, |this, cx| {
12995            this.buffer_store.read(cx).get_existing(buffer_id)
12996        })?;
12997        buffer
12998            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
12999            .await?;
13000        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13001        Ok((buffer_version, buffer))
13002    }
13003
13004    fn take_text_document_sync_options(
13005        capabilities: &mut lsp::ServerCapabilities,
13006    ) -> lsp::TextDocumentSyncOptions {
13007        match capabilities.text_document_sync.take() {
13008            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13009            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13010                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13011                sync_options.change = Some(sync_kind);
13012                sync_options
13013            }
13014            None => lsp::TextDocumentSyncOptions::default(),
13015        }
13016    }
13017
13018    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13019        self.downstream_client.clone()
13020    }
13021
13022    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13023        self.worktree_store.clone()
13024    }
13025
13026    /// Gets what's stored in the LSP data for the given buffer.
13027    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13028        self.lsp_data.get_mut(&buffer_id)
13029    }
13030
13031    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13032    /// new [`BufferLspData`] will be created to replace the previous state.
13033    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13034        let (buffer_id, buffer_version) =
13035            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13036        let lsp_data = self
13037            .lsp_data
13038            .entry(buffer_id)
13039            .or_insert_with(|| BufferLspData::new(buffer, cx));
13040        if buffer_version.changed_since(&lsp_data.buffer_version) {
13041            // To send delta requests for semantic tokens, the previous tokens
13042            // need to be kept between buffer changes.
13043            let semantic_tokens = lsp_data.semantic_tokens.take();
13044            *lsp_data = BufferLspData::new(buffer, cx);
13045            lsp_data.semantic_tokens = semantic_tokens;
13046        }
13047        lsp_data
13048    }
13049}
13050
13051// Registration with registerOptions as null, should fallback to true.
13052// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13053fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13054    reg: lsp::Registration,
13055) -> Result<OneOf<bool, T>> {
13056    Ok(match reg.register_options {
13057        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13058        None => OneOf::Left(true),
13059    })
13060}
13061
13062fn subscribe_to_binary_statuses(
13063    languages: &Arc<LanguageRegistry>,
13064    cx: &mut Context<'_, LspStore>,
13065) -> Task<()> {
13066    let mut server_statuses = languages.language_server_binary_statuses();
13067    cx.spawn(async move |lsp_store, cx| {
13068        while let Some((server_name, binary_status)) = server_statuses.next().await {
13069            if lsp_store
13070                .update(cx, |_, cx| {
13071                    let mut message = None;
13072                    let binary_status = match binary_status {
13073                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13074                        BinaryStatus::CheckingForUpdate => {
13075                            proto::ServerBinaryStatus::CheckingForUpdate
13076                        }
13077                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13078                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13079                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13080                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13081                        BinaryStatus::Failed { error } => {
13082                            message = Some(error);
13083                            proto::ServerBinaryStatus::Failed
13084                        }
13085                    };
13086                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13087                        // Binary updates are about the binary that might not have any language server id at that point.
13088                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13089                        language_server_id: LanguageServerId(0),
13090                        name: Some(server_name),
13091                        message: proto::update_language_server::Variant::StatusUpdate(
13092                            proto::StatusUpdate {
13093                                message,
13094                                status: Some(proto::status_update::Status::Binary(
13095                                    binary_status as i32,
13096                                )),
13097                            },
13098                        ),
13099                    });
13100                })
13101                .is_err()
13102            {
13103                break;
13104            }
13105        }
13106    })
13107}
13108
13109fn lsp_workspace_diagnostics_refresh(
13110    registration_id: Option<String>,
13111    options: DiagnosticServerCapabilities,
13112    server: Arc<LanguageServer>,
13113    cx: &mut Context<'_, LspStore>,
13114) -> Option<WorkspaceRefreshTask> {
13115    let identifier = workspace_diagnostic_identifier(&options)?;
13116    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13117
13118    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13119    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13120    refresh_tx.try_send(()).ok();
13121
13122    let request_timeout = ProjectSettings::get_global(cx)
13123        .global_lsp_settings
13124        .get_request_timeout();
13125
13126    // 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.
13127    // This allows users to increase the duration if need be
13128    let timeout = if request_timeout != Duration::ZERO {
13129        request_timeout.max(DEFAULT_LSP_REQUEST_TIMEOUT)
13130    } else {
13131        request_timeout
13132    };
13133
13134    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13135        let mut attempts = 0;
13136        let max_attempts = 50;
13137        let mut requests = 0;
13138
13139        loop {
13140            let Some(()) = refresh_rx.recv().await else {
13141                return;
13142            };
13143
13144            'request: loop {
13145                requests += 1;
13146                if attempts > max_attempts {
13147                    log::error!(
13148                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13149                    );
13150                    return;
13151                }
13152                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13153                cx.background_executor()
13154                    .timer(Duration::from_millis(backoff_millis))
13155                    .await;
13156                attempts += 1;
13157
13158                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13159                    lsp_store
13160                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13161                        .into_iter()
13162                        .filter_map(|(abs_path, result_id)| {
13163                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13164                            Some(lsp::PreviousResultId {
13165                                uri,
13166                                value: result_id.to_string(),
13167                            })
13168                        })
13169                        .collect()
13170                }) else {
13171                    return;
13172                };
13173
13174                let token = if let Some(registration_id) = &registration_id {
13175                    format!(
13176                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13177                        server.server_id(),
13178                    )
13179                } else {
13180                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13181                };
13182
13183                progress_rx.try_recv().ok();
13184                let timer = server.request_timer(timeout).fuse();
13185                let progress = pin!(progress_rx.recv().fuse());
13186                let response_result = server
13187                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13188                        lsp::WorkspaceDiagnosticParams {
13189                            previous_result_ids,
13190                            identifier: identifier.clone(),
13191                            work_done_progress_params: Default::default(),
13192                            partial_result_params: lsp::PartialResultParams {
13193                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13194                            },
13195                        },
13196                        select(timer, progress).then(|either| match either {
13197                            Either::Left((message, ..)) => ready(message).left_future(),
13198                            Either::Right(..) => pending::<String>().right_future(),
13199                        }),
13200                    )
13201                    .await;
13202
13203                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13204                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13205                match response_result {
13206                    ConnectionResult::Timeout => {
13207                        log::error!("Timeout during workspace diagnostics pull");
13208                        continue 'request;
13209                    }
13210                    ConnectionResult::ConnectionReset => {
13211                        log::error!("Server closed a workspace diagnostics pull request");
13212                        continue 'request;
13213                    }
13214                    ConnectionResult::Result(Err(e)) => {
13215                        log::error!("Error during workspace diagnostics pull: {e:#}");
13216                        break 'request;
13217                    }
13218                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13219                        attempts = 0;
13220                        if lsp_store
13221                            .update(cx, |lsp_store, cx| {
13222                                lsp_store.apply_workspace_diagnostic_report(
13223                                    server.server_id(),
13224                                    pulled_diagnostics,
13225                                    registration_id_shared.clone(),
13226                                    cx,
13227                                )
13228                            })
13229                            .is_err()
13230                        {
13231                            return;
13232                        }
13233                        break 'request;
13234                    }
13235                }
13236            }
13237        }
13238    });
13239
13240    Some(WorkspaceRefreshTask {
13241        refresh_tx,
13242        progress_tx,
13243        task: workspace_query_language_server,
13244    })
13245}
13246
13247fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<SharedString> {
13248    match &options {
13249        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => diagnostic_options
13250            .identifier
13251            .as_deref()
13252            .map(SharedString::new),
13253        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13254            let diagnostic_options = &registration_options.diagnostic_options;
13255            diagnostic_options
13256                .identifier
13257                .as_deref()
13258                .map(SharedString::new)
13259        }
13260    }
13261}
13262
13263fn workspace_diagnostic_identifier(
13264    options: &DiagnosticServerCapabilities,
13265) -> Option<Option<String>> {
13266    match &options {
13267        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13268            if !diagnostic_options.workspace_diagnostics {
13269                return None;
13270            }
13271            Some(diagnostic_options.identifier.clone())
13272        }
13273        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13274            let diagnostic_options = &registration_options.diagnostic_options;
13275            if !diagnostic_options.workspace_diagnostics {
13276                return None;
13277            }
13278            Some(diagnostic_options.identifier.clone())
13279        }
13280    }
13281}
13282
13283fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13284    let CompletionSource::BufferWord {
13285        word_range,
13286        resolved,
13287    } = &mut completion.source
13288    else {
13289        return;
13290    };
13291    if *resolved {
13292        return;
13293    }
13294
13295    if completion.new_text
13296        != snapshot
13297            .text_for_range(word_range.clone())
13298            .collect::<String>()
13299    {
13300        return;
13301    }
13302
13303    let mut offset = 0;
13304    for chunk in snapshot.chunks(word_range.clone(), true) {
13305        let end_offset = offset + chunk.text.len();
13306        if let Some(highlight_id) = chunk.syntax_highlight_id {
13307            completion
13308                .label
13309                .runs
13310                .push((offset..end_offset, highlight_id));
13311        }
13312        offset = end_offset;
13313    }
13314    *resolved = true;
13315}
13316
13317impl EventEmitter<LspStoreEvent> for LspStore {}
13318
13319fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13320    hover
13321        .contents
13322        .retain(|hover_block| !hover_block.text.trim().is_empty());
13323    if hover.contents.is_empty() {
13324        None
13325    } else {
13326        Some(hover)
13327    }
13328}
13329
13330async fn populate_labels_for_completions(
13331    new_completions: Vec<CoreCompletion>,
13332    language: Option<Arc<Language>>,
13333    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13334) -> Vec<Completion> {
13335    let lsp_completions = new_completions
13336        .iter()
13337        .filter_map(|new_completion| {
13338            new_completion
13339                .source
13340                .lsp_completion(true)
13341                .map(|lsp_completion| lsp_completion.into_owned())
13342        })
13343        .collect::<Vec<_>>();
13344
13345    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13346        lsp_adapter
13347            .labels_for_completions(&lsp_completions, language)
13348            .await
13349            .log_err()
13350            .unwrap_or_default()
13351    } else {
13352        Vec::new()
13353    }
13354    .into_iter()
13355    .fuse();
13356
13357    let mut completions = Vec::new();
13358    for completion in new_completions {
13359        match completion.source.lsp_completion(true) {
13360            Some(lsp_completion) => {
13361                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13362
13363                let mut label = labels.next().flatten().unwrap_or_else(|| {
13364                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13365                });
13366                ensure_uniform_list_compatible_label(&mut label);
13367                completions.push(Completion {
13368                    label,
13369                    documentation,
13370                    replace_range: completion.replace_range,
13371                    new_text: completion.new_text,
13372                    insert_text_mode: lsp_completion.insert_text_mode,
13373                    source: completion.source,
13374                    icon_path: None,
13375                    confirm: None,
13376                    match_start: None,
13377                    snippet_deduplication_key: None,
13378                });
13379            }
13380            None => {
13381                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13382                ensure_uniform_list_compatible_label(&mut label);
13383                completions.push(Completion {
13384                    label,
13385                    documentation: None,
13386                    replace_range: completion.replace_range,
13387                    new_text: completion.new_text,
13388                    source: completion.source,
13389                    insert_text_mode: None,
13390                    icon_path: None,
13391                    confirm: None,
13392                    match_start: None,
13393                    snippet_deduplication_key: None,
13394                });
13395            }
13396        }
13397    }
13398    completions
13399}
13400
13401#[derive(Debug)]
13402pub enum LanguageServerToQuery {
13403    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13404    FirstCapable,
13405    /// Query a specific language server.
13406    Other(LanguageServerId),
13407}
13408
13409#[derive(Default)]
13410struct RenamePathsWatchedForServer {
13411    did_rename: Vec<RenameActionPredicate>,
13412    will_rename: Vec<RenameActionPredicate>,
13413}
13414
13415impl RenamePathsWatchedForServer {
13416    fn with_did_rename_patterns(
13417        mut self,
13418        did_rename: Option<&FileOperationRegistrationOptions>,
13419    ) -> Self {
13420        if let Some(did_rename) = did_rename {
13421            self.did_rename = did_rename
13422                .filters
13423                .iter()
13424                .filter_map(|filter| filter.try_into().log_err())
13425                .collect();
13426        }
13427        self
13428    }
13429    fn with_will_rename_patterns(
13430        mut self,
13431        will_rename: Option<&FileOperationRegistrationOptions>,
13432    ) -> Self {
13433        if let Some(will_rename) = will_rename {
13434            self.will_rename = will_rename
13435                .filters
13436                .iter()
13437                .filter_map(|filter| filter.try_into().log_err())
13438                .collect();
13439        }
13440        self
13441    }
13442
13443    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13444        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13445    }
13446    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13447        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13448    }
13449}
13450
13451impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13452    type Error = globset::Error;
13453    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13454        Ok(Self {
13455            kind: ops.pattern.matches.clone(),
13456            glob: GlobBuilder::new(&ops.pattern.glob)
13457                .case_insensitive(
13458                    ops.pattern
13459                        .options
13460                        .as_ref()
13461                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13462                )
13463                .build()?
13464                .compile_matcher(),
13465        })
13466    }
13467}
13468struct RenameActionPredicate {
13469    glob: GlobMatcher,
13470    kind: Option<FileOperationPatternKind>,
13471}
13472
13473impl RenameActionPredicate {
13474    // Returns true if language server should be notified
13475    fn eval(&self, path: &str, is_dir: bool) -> bool {
13476        self.kind.as_ref().is_none_or(|kind| {
13477            let expected_kind = if is_dir {
13478                FileOperationPatternKind::Folder
13479            } else {
13480                FileOperationPatternKind::File
13481            };
13482            kind == &expected_kind
13483        }) && self.glob.is_match(path)
13484    }
13485}
13486
13487#[derive(Default)]
13488struct LanguageServerWatchedPaths {
13489    worktree_paths: HashMap<WorktreeId, GlobSet>,
13490    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13491}
13492
13493#[derive(Default)]
13494struct LanguageServerWatchedPathsBuilder {
13495    worktree_paths: HashMap<WorktreeId, GlobSet>,
13496    abs_paths: HashMap<Arc<Path>, GlobSet>,
13497}
13498
13499impl LanguageServerWatchedPathsBuilder {
13500    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13501        self.worktree_paths.insert(worktree_id, glob_set);
13502    }
13503    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13504        self.abs_paths.insert(path, glob_set);
13505    }
13506    fn build(
13507        self,
13508        fs: Arc<dyn Fs>,
13509        language_server_id: LanguageServerId,
13510        cx: &mut Context<LspStore>,
13511    ) -> LanguageServerWatchedPaths {
13512        let lsp_store = cx.weak_entity();
13513
13514        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13515        let abs_paths = self
13516            .abs_paths
13517            .into_iter()
13518            .map(|(abs_path, globset)| {
13519                let task = cx.spawn({
13520                    let abs_path = abs_path.clone();
13521                    let fs = fs.clone();
13522
13523                    let lsp_store = lsp_store.clone();
13524                    async move |_, cx| {
13525                        maybe!(async move {
13526                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13527                            while let Some(update) = push_updates.0.next().await {
13528                                let action = lsp_store
13529                                    .update(cx, |this, _| {
13530                                        let Some(local) = this.as_local() else {
13531                                            return ControlFlow::Break(());
13532                                        };
13533                                        let Some(watcher) = local
13534                                            .language_server_watched_paths
13535                                            .get(&language_server_id)
13536                                        else {
13537                                            return ControlFlow::Break(());
13538                                        };
13539                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13540                                            "Watched abs path is not registered with a watcher",
13541                                        );
13542                                        let matching_entries = update
13543                                            .into_iter()
13544                                            .filter(|event| globs.is_match(&event.path))
13545                                            .collect::<Vec<_>>();
13546                                        this.lsp_notify_abs_paths_changed(
13547                                            language_server_id,
13548                                            matching_entries,
13549                                        );
13550                                        ControlFlow::Continue(())
13551                                    })
13552                                    .ok()?;
13553
13554                                if action.is_break() {
13555                                    break;
13556                                }
13557                            }
13558                            Some(())
13559                        })
13560                        .await;
13561                    }
13562                });
13563                (abs_path, (globset, task))
13564            })
13565            .collect();
13566        LanguageServerWatchedPaths {
13567            worktree_paths: self.worktree_paths,
13568            abs_paths,
13569        }
13570    }
13571}
13572
13573struct LspBufferSnapshot {
13574    version: i32,
13575    snapshot: TextBufferSnapshot,
13576}
13577
13578/// A prompt requested by LSP server.
13579#[derive(Clone, Debug)]
13580pub struct LanguageServerPromptRequest {
13581    pub id: usize,
13582    pub level: PromptLevel,
13583    pub message: String,
13584    pub actions: Vec<MessageActionItem>,
13585    pub lsp_name: String,
13586    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13587}
13588
13589impl LanguageServerPromptRequest {
13590    pub fn new(
13591        level: PromptLevel,
13592        message: String,
13593        actions: Vec<MessageActionItem>,
13594        lsp_name: String,
13595        response_channel: smol::channel::Sender<MessageActionItem>,
13596    ) -> Self {
13597        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13598        LanguageServerPromptRequest {
13599            id,
13600            level,
13601            message,
13602            actions,
13603            lsp_name,
13604            response_channel,
13605        }
13606    }
13607    pub async fn respond(self, index: usize) -> Option<()> {
13608        if let Some(response) = self.actions.into_iter().nth(index) {
13609            self.response_channel.send(response).await.ok()
13610        } else {
13611            None
13612        }
13613    }
13614
13615    #[cfg(any(test, feature = "test-support"))]
13616    pub fn test(
13617        level: PromptLevel,
13618        message: String,
13619        actions: Vec<MessageActionItem>,
13620        lsp_name: String,
13621    ) -> Self {
13622        let (tx, _rx) = smol::channel::unbounded();
13623        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13624    }
13625}
13626impl PartialEq for LanguageServerPromptRequest {
13627    fn eq(&self, other: &Self) -> bool {
13628        self.message == other.message && self.actions == other.actions
13629    }
13630}
13631
13632#[derive(Clone, Debug, PartialEq)]
13633pub enum LanguageServerLogType {
13634    Log(MessageType),
13635    Trace { verbose_info: Option<String> },
13636    Rpc { received: bool },
13637}
13638
13639impl LanguageServerLogType {
13640    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13641        match self {
13642            Self::Log(log_type) => {
13643                use proto::log_message::LogLevel;
13644                let level = match *log_type {
13645                    MessageType::ERROR => LogLevel::Error,
13646                    MessageType::WARNING => LogLevel::Warning,
13647                    MessageType::INFO => LogLevel::Info,
13648                    MessageType::LOG => LogLevel::Log,
13649                    other => {
13650                        log::warn!("Unknown lsp log message type: {other:?}");
13651                        LogLevel::Log
13652                    }
13653                };
13654                proto::language_server_log::LogType::Log(proto::LogMessage {
13655                    level: level as i32,
13656                })
13657            }
13658            Self::Trace { verbose_info } => {
13659                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13660                    verbose_info: verbose_info.to_owned(),
13661                })
13662            }
13663            Self::Rpc { received } => {
13664                let kind = if *received {
13665                    proto::rpc_message::Kind::Received
13666                } else {
13667                    proto::rpc_message::Kind::Sent
13668                };
13669                let kind = kind as i32;
13670                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13671            }
13672        }
13673    }
13674
13675    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13676        use proto::log_message::LogLevel;
13677        use proto::rpc_message;
13678        match log_type {
13679            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13680                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13681                    LogLevel::Error => MessageType::ERROR,
13682                    LogLevel::Warning => MessageType::WARNING,
13683                    LogLevel::Info => MessageType::INFO,
13684                    LogLevel::Log => MessageType::LOG,
13685                },
13686            ),
13687            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13688                verbose_info: trace_message.verbose_info,
13689            },
13690            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13691                received: match rpc_message::Kind::from_i32(message.kind)
13692                    .unwrap_or(rpc_message::Kind::Received)
13693                {
13694                    rpc_message::Kind::Received => true,
13695                    rpc_message::Kind::Sent => false,
13696                },
13697            },
13698        }
13699    }
13700}
13701
13702pub struct WorkspaceRefreshTask {
13703    refresh_tx: mpsc::Sender<()>,
13704    progress_tx: mpsc::Sender<()>,
13705    #[allow(dead_code)]
13706    task: Task<()>,
13707}
13708
13709pub enum LanguageServerState {
13710    Starting {
13711        startup: Task<Option<Arc<LanguageServer>>>,
13712        /// List of language servers that will be added to the workspace once it's initialization completes.
13713        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13714    },
13715
13716    Running {
13717        adapter: Arc<CachedLspAdapter>,
13718        server: Arc<LanguageServer>,
13719        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13720        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13721    },
13722}
13723
13724impl LanguageServerState {
13725    fn add_workspace_folder(&self, uri: Uri) {
13726        match self {
13727            LanguageServerState::Starting {
13728                pending_workspace_folders,
13729                ..
13730            } => {
13731                pending_workspace_folders.lock().insert(uri);
13732            }
13733            LanguageServerState::Running { server, .. } => {
13734                server.add_workspace_folder(uri);
13735            }
13736        }
13737    }
13738    fn _remove_workspace_folder(&self, uri: Uri) {
13739        match self {
13740            LanguageServerState::Starting {
13741                pending_workspace_folders,
13742                ..
13743            } => {
13744                pending_workspace_folders.lock().remove(&uri);
13745            }
13746            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13747        }
13748    }
13749}
13750
13751impl std::fmt::Debug for LanguageServerState {
13752    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13753        match self {
13754            LanguageServerState::Starting { .. } => {
13755                f.debug_struct("LanguageServerState::Starting").finish()
13756            }
13757            LanguageServerState::Running { .. } => {
13758                f.debug_struct("LanguageServerState::Running").finish()
13759            }
13760        }
13761    }
13762}
13763
13764#[derive(Clone, Debug, Serialize)]
13765pub struct LanguageServerProgress {
13766    pub is_disk_based_diagnostics_progress: bool,
13767    pub is_cancellable: bool,
13768    pub title: Option<String>,
13769    pub message: Option<String>,
13770    pub percentage: Option<usize>,
13771    #[serde(skip_serializing)]
13772    pub last_update_at: Instant,
13773}
13774
13775#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13776pub struct DiagnosticSummary {
13777    pub error_count: usize,
13778    pub warning_count: usize,
13779}
13780
13781impl DiagnosticSummary {
13782    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13783        let mut this = Self {
13784            error_count: 0,
13785            warning_count: 0,
13786        };
13787
13788        for entry in diagnostics {
13789            if entry.diagnostic.is_primary {
13790                match entry.diagnostic.severity {
13791                    DiagnosticSeverity::ERROR => this.error_count += 1,
13792                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13793                    _ => {}
13794                }
13795            }
13796        }
13797
13798        this
13799    }
13800
13801    pub fn is_empty(&self) -> bool {
13802        self.error_count == 0 && self.warning_count == 0
13803    }
13804
13805    pub fn to_proto(
13806        self,
13807        language_server_id: LanguageServerId,
13808        path: &RelPath,
13809    ) -> proto::DiagnosticSummary {
13810        proto::DiagnosticSummary {
13811            path: path.to_proto(),
13812            language_server_id: language_server_id.0 as u64,
13813            error_count: self.error_count as u32,
13814            warning_count: self.warning_count as u32,
13815        }
13816    }
13817}
13818
13819#[derive(Clone, Debug)]
13820pub enum CompletionDocumentation {
13821    /// There is no documentation for this completion.
13822    Undocumented,
13823    /// A single line of documentation.
13824    SingleLine(SharedString),
13825    /// Multiple lines of plain text documentation.
13826    MultiLinePlainText(SharedString),
13827    /// Markdown documentation.
13828    MultiLineMarkdown(SharedString),
13829    /// Both single line and multiple lines of plain text documentation.
13830    SingleLineAndMultiLinePlainText {
13831        single_line: SharedString,
13832        plain_text: Option<SharedString>,
13833    },
13834}
13835
13836impl CompletionDocumentation {
13837    #[cfg(any(test, feature = "test-support"))]
13838    pub fn text(&self) -> SharedString {
13839        match self {
13840            CompletionDocumentation::Undocumented => "".into(),
13841            CompletionDocumentation::SingleLine(s) => s.clone(),
13842            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13843            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13844            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13845                single_line.clone()
13846            }
13847        }
13848    }
13849}
13850
13851impl From<lsp::Documentation> for CompletionDocumentation {
13852    fn from(docs: lsp::Documentation) -> Self {
13853        match docs {
13854            lsp::Documentation::String(text) => {
13855                if text.lines().count() <= 1 {
13856                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
13857                } else {
13858                    CompletionDocumentation::MultiLinePlainText(text.into())
13859                }
13860            }
13861
13862            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13863                lsp::MarkupKind::PlainText => {
13864                    if value.lines().count() <= 1 {
13865                        CompletionDocumentation::SingleLine(value.into())
13866                    } else {
13867                        CompletionDocumentation::MultiLinePlainText(value.into())
13868                    }
13869                }
13870
13871                lsp::MarkupKind::Markdown => {
13872                    CompletionDocumentation::MultiLineMarkdown(value.into())
13873                }
13874            },
13875        }
13876    }
13877}
13878
13879pub enum ResolvedHint {
13880    Resolved(InlayHint),
13881    Resolving(Shared<Task<()>>),
13882}
13883
13884pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
13885    glob.components()
13886        .take_while(|component| match component {
13887            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13888            _ => true,
13889        })
13890        .collect()
13891}
13892
13893pub struct SshLspAdapter {
13894    name: LanguageServerName,
13895    binary: LanguageServerBinary,
13896    initialization_options: Option<String>,
13897    code_action_kinds: Option<Vec<CodeActionKind>>,
13898}
13899
13900impl SshLspAdapter {
13901    pub fn new(
13902        name: LanguageServerName,
13903        binary: LanguageServerBinary,
13904        initialization_options: Option<String>,
13905        code_action_kinds: Option<String>,
13906    ) -> Self {
13907        Self {
13908            name,
13909            binary,
13910            initialization_options,
13911            code_action_kinds: code_action_kinds
13912                .as_ref()
13913                .and_then(|c| serde_json::from_str(c).ok()),
13914        }
13915    }
13916}
13917
13918impl LspInstaller for SshLspAdapter {
13919    type BinaryVersion = ();
13920    async fn check_if_user_installed(
13921        &self,
13922        _: &dyn LspAdapterDelegate,
13923        _: Option<Toolchain>,
13924        _: &AsyncApp,
13925    ) -> Option<LanguageServerBinary> {
13926        Some(self.binary.clone())
13927    }
13928
13929    async fn cached_server_binary(
13930        &self,
13931        _: PathBuf,
13932        _: &dyn LspAdapterDelegate,
13933    ) -> Option<LanguageServerBinary> {
13934        None
13935    }
13936
13937    async fn fetch_latest_server_version(
13938        &self,
13939        _: &dyn LspAdapterDelegate,
13940        _: bool,
13941        _: &mut AsyncApp,
13942    ) -> Result<()> {
13943        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13944    }
13945
13946    async fn fetch_server_binary(
13947        &self,
13948        _: (),
13949        _: PathBuf,
13950        _: &dyn LspAdapterDelegate,
13951    ) -> Result<LanguageServerBinary> {
13952        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13953    }
13954}
13955
13956#[async_trait(?Send)]
13957impl LspAdapter for SshLspAdapter {
13958    fn name(&self) -> LanguageServerName {
13959        self.name.clone()
13960    }
13961
13962    async fn initialization_options(
13963        self: Arc<Self>,
13964        _: &Arc<dyn LspAdapterDelegate>,
13965    ) -> Result<Option<serde_json::Value>> {
13966        let Some(options) = &self.initialization_options else {
13967            return Ok(None);
13968        };
13969        let result = serde_json::from_str(options)?;
13970        Ok(result)
13971    }
13972
13973    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13974        self.code_action_kinds.clone()
13975    }
13976}
13977
13978pub fn language_server_settings<'a>(
13979    delegate: &'a dyn LspAdapterDelegate,
13980    language: &LanguageServerName,
13981    cx: &'a App,
13982) -> Option<&'a LspSettings> {
13983    language_server_settings_for(
13984        SettingsLocation {
13985            worktree_id: delegate.worktree_id(),
13986            path: RelPath::empty(),
13987        },
13988        language,
13989        cx,
13990    )
13991}
13992
13993pub fn language_server_settings_for<'a>(
13994    location: SettingsLocation<'a>,
13995    language: &LanguageServerName,
13996    cx: &'a App,
13997) -> Option<&'a LspSettings> {
13998    ProjectSettings::get(Some(location), cx).lsp.get(language)
13999}
14000
14001pub struct LocalLspAdapterDelegate {
14002    lsp_store: WeakEntity<LspStore>,
14003    worktree: worktree::Snapshot,
14004    fs: Arc<dyn Fs>,
14005    http_client: Arc<dyn HttpClient>,
14006    language_registry: Arc<LanguageRegistry>,
14007    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14008}
14009
14010impl LocalLspAdapterDelegate {
14011    pub fn new(
14012        language_registry: Arc<LanguageRegistry>,
14013        environment: &Entity<ProjectEnvironment>,
14014        lsp_store: WeakEntity<LspStore>,
14015        worktree: &Entity<Worktree>,
14016        http_client: Arc<dyn HttpClient>,
14017        fs: Arc<dyn Fs>,
14018        cx: &mut App,
14019    ) -> Arc<Self> {
14020        let load_shell_env_task =
14021            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14022
14023        Arc::new(Self {
14024            lsp_store,
14025            worktree: worktree.read(cx).snapshot(),
14026            fs,
14027            http_client,
14028            language_registry,
14029            load_shell_env_task,
14030        })
14031    }
14032
14033    pub fn from_local_lsp(
14034        local: &LocalLspStore,
14035        worktree: &Entity<Worktree>,
14036        cx: &mut App,
14037    ) -> Arc<Self> {
14038        Self::new(
14039            local.languages.clone(),
14040            &local.environment,
14041            local.weak.clone(),
14042            worktree,
14043            local.http_client.clone(),
14044            local.fs.clone(),
14045            cx,
14046        )
14047    }
14048}
14049
14050#[async_trait]
14051impl LspAdapterDelegate for LocalLspAdapterDelegate {
14052    fn show_notification(&self, message: &str, cx: &mut App) {
14053        self.lsp_store
14054            .update(cx, |_, cx| {
14055                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14056            })
14057            .ok();
14058    }
14059
14060    fn http_client(&self) -> Arc<dyn HttpClient> {
14061        self.http_client.clone()
14062    }
14063
14064    fn worktree_id(&self) -> WorktreeId {
14065        self.worktree.id()
14066    }
14067
14068    fn worktree_root_path(&self) -> &Path {
14069        self.worktree.abs_path().as_ref()
14070    }
14071
14072    fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
14073        self.worktree.resolve_relative_path(path)
14074    }
14075
14076    async fn shell_env(&self) -> HashMap<String, String> {
14077        let task = self.load_shell_env_task.clone();
14078        task.await.unwrap_or_default()
14079    }
14080
14081    async fn npm_package_installed_version(
14082        &self,
14083        package_name: &str,
14084    ) -> Result<Option<(PathBuf, Version)>> {
14085        let local_package_directory = self.worktree_root_path();
14086        let node_modules_directory = local_package_directory.join("node_modules");
14087
14088        if let Some(version) =
14089            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14090        {
14091            return Ok(Some((node_modules_directory, version)));
14092        }
14093        let Some(npm) = self.which("npm".as_ref()).await else {
14094            log::warn!(
14095                "Failed to find npm executable for {:?}",
14096                local_package_directory
14097            );
14098            return Ok(None);
14099        };
14100
14101        let env = self.shell_env().await;
14102        let output = util::command::new_smol_command(&npm)
14103            .args(["root", "-g"])
14104            .envs(env)
14105            .current_dir(local_package_directory)
14106            .output()
14107            .await?;
14108        let global_node_modules =
14109            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14110
14111        if let Some(version) =
14112            read_package_installed_version(global_node_modules.clone(), package_name).await?
14113        {
14114            return Ok(Some((global_node_modules, version)));
14115        }
14116        return Ok(None);
14117    }
14118
14119    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14120        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14121        if self.fs.is_file(&worktree_abs_path).await {
14122            worktree_abs_path.pop();
14123        }
14124
14125        let env = self.shell_env().await;
14126
14127        let shell_path = env.get("PATH").cloned();
14128
14129        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14130    }
14131
14132    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14133        let mut working_dir = self.worktree_root_path().to_path_buf();
14134        if self.fs.is_file(&working_dir).await {
14135            working_dir.pop();
14136        }
14137        let output = util::command::new_smol_command(&command.path)
14138            .args(command.arguments)
14139            .envs(command.env.clone().unwrap_or_default())
14140            .current_dir(working_dir)
14141            .output()
14142            .await?;
14143
14144        anyhow::ensure!(
14145            output.status.success(),
14146            "{}, stdout: {:?}, stderr: {:?}",
14147            output.status,
14148            String::from_utf8_lossy(&output.stdout),
14149            String::from_utf8_lossy(&output.stderr)
14150        );
14151        Ok(())
14152    }
14153
14154    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14155        self.language_registry
14156            .update_lsp_binary_status(server_name, status);
14157    }
14158
14159    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14160        self.language_registry
14161            .all_lsp_adapters()
14162            .into_iter()
14163            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14164            .collect()
14165    }
14166
14167    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14168        let dir = self.language_registry.language_server_download_dir(name)?;
14169
14170        if !dir.exists() {
14171            smol::fs::create_dir_all(&dir)
14172                .await
14173                .context("failed to create container directory")
14174                .log_err()?;
14175        }
14176
14177        Some(dir)
14178    }
14179
14180    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14181        let entry = self
14182            .worktree
14183            .entry_for_path(path)
14184            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14185        let abs_path = self.worktree.absolutize(&entry.path);
14186        self.fs.load(&abs_path).await
14187    }
14188}
14189
14190async fn populate_labels_for_symbols(
14191    symbols: Vec<CoreSymbol>,
14192    language_registry: &Arc<LanguageRegistry>,
14193    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14194    output: &mut Vec<Symbol>,
14195) {
14196    #[allow(clippy::mutable_key_type)]
14197    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14198
14199    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14200    for symbol in symbols {
14201        let Some(file_name) = symbol.path.file_name() else {
14202            continue;
14203        };
14204        let language = language_registry
14205            .load_language_for_file_path(Path::new(file_name))
14206            .await
14207            .ok()
14208            .or_else(|| {
14209                unknown_paths.insert(file_name.into());
14210                None
14211            });
14212        symbols_by_language
14213            .entry(language)
14214            .or_default()
14215            .push(symbol);
14216    }
14217
14218    for unknown_path in unknown_paths {
14219        log::info!("no language found for symbol in file {unknown_path:?}");
14220    }
14221
14222    let mut label_params = Vec::new();
14223    for (language, mut symbols) in symbols_by_language {
14224        label_params.clear();
14225        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14226            name: mem::take(&mut symbol.name),
14227            kind: symbol.kind,
14228            container_name: symbol.container_name.take(),
14229        }));
14230
14231        let mut labels = Vec::new();
14232        if let Some(language) = language {
14233            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14234                language_registry
14235                    .lsp_adapters(&language.name())
14236                    .first()
14237                    .cloned()
14238            });
14239            if let Some(lsp_adapter) = lsp_adapter {
14240                labels = lsp_adapter
14241                    .labels_for_symbols(&label_params, &language)
14242                    .await
14243                    .log_err()
14244                    .unwrap_or_default();
14245            }
14246        }
14247
14248        for (
14249            (
14250                symbol,
14251                language::Symbol {
14252                    name,
14253                    container_name,
14254                    ..
14255                },
14256            ),
14257            label,
14258        ) in symbols
14259            .into_iter()
14260            .zip(label_params.drain(..))
14261            .zip(labels.into_iter().chain(iter::repeat(None)))
14262        {
14263            output.push(Symbol {
14264                language_server_name: symbol.language_server_name,
14265                source_worktree_id: symbol.source_worktree_id,
14266                source_language_server_id: symbol.source_language_server_id,
14267                path: symbol.path,
14268                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14269                name,
14270                kind: symbol.kind,
14271                range: symbol.range,
14272                container_name,
14273            });
14274        }
14275    }
14276}
14277
14278fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14279    match server.capabilities().text_document_sync.as_ref()? {
14280        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14281            // Server wants didSave but didn't specify includeText.
14282            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14283            // Server doesn't want didSave at all.
14284            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14285            // Server provided SaveOptions.
14286            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14287                Some(save_options.include_text.unwrap_or(false))
14288            }
14289        },
14290        // We do not have any save info. Kind affects didChange only.
14291        lsp::TextDocumentSyncCapability::Kind(_) => None,
14292    }
14293}
14294
14295/// Completion items are displayed in a `UniformList`.
14296/// Usually, those items are single-line strings, but in LSP responses,
14297/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14298/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14299/// 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,
14300/// breaking the completions menu presentation.
14301///
14302/// 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.
14303pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14304    let mut new_text = String::with_capacity(label.text.len());
14305    let mut offset_map = vec![0; label.text.len() + 1];
14306    let mut last_char_was_space = false;
14307    let mut new_idx = 0;
14308    let chars = label.text.char_indices().fuse();
14309    let mut newlines_removed = false;
14310
14311    for (idx, c) in chars {
14312        offset_map[idx] = new_idx;
14313
14314        match c {
14315            '\n' if last_char_was_space => {
14316                newlines_removed = true;
14317            }
14318            '\t' | ' ' if last_char_was_space => {}
14319            '\n' if !last_char_was_space => {
14320                new_text.push(' ');
14321                new_idx += 1;
14322                last_char_was_space = true;
14323                newlines_removed = true;
14324            }
14325            ' ' | '\t' => {
14326                new_text.push(' ');
14327                new_idx += 1;
14328                last_char_was_space = true;
14329            }
14330            _ => {
14331                new_text.push(c);
14332                new_idx += c.len_utf8();
14333                last_char_was_space = false;
14334            }
14335        }
14336    }
14337    offset_map[label.text.len()] = new_idx;
14338
14339    // Only modify the label if newlines were removed.
14340    if !newlines_removed {
14341        return;
14342    }
14343
14344    let last_index = new_idx;
14345    let mut run_ranges_errors = Vec::new();
14346    label.runs.retain_mut(|(range, _)| {
14347        match offset_map.get(range.start) {
14348            Some(&start) => range.start = start,
14349            None => {
14350                run_ranges_errors.push(range.clone());
14351                return false;
14352            }
14353        }
14354
14355        match offset_map.get(range.end) {
14356            Some(&end) => range.end = end,
14357            None => {
14358                run_ranges_errors.push(range.clone());
14359                range.end = last_index;
14360            }
14361        }
14362        true
14363    });
14364    if !run_ranges_errors.is_empty() {
14365        log::error!(
14366            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14367            label.text
14368        );
14369    }
14370
14371    let mut wrong_filter_range = None;
14372    if label.filter_range == (0..label.text.len()) {
14373        label.filter_range = 0..new_text.len();
14374    } else {
14375        let mut original_filter_range = Some(label.filter_range.clone());
14376        match offset_map.get(label.filter_range.start) {
14377            Some(&start) => label.filter_range.start = start,
14378            None => {
14379                wrong_filter_range = original_filter_range.take();
14380                label.filter_range.start = last_index;
14381            }
14382        }
14383
14384        match offset_map.get(label.filter_range.end) {
14385            Some(&end) => label.filter_range.end = end,
14386            None => {
14387                wrong_filter_range = original_filter_range.take();
14388                label.filter_range.end = last_index;
14389            }
14390        }
14391    }
14392    if let Some(wrong_filter_range) = wrong_filter_range {
14393        log::error!(
14394            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14395            label.text
14396        );
14397    }
14398
14399    label.text = new_text;
14400}