lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13mod code_lens;
   14mod document_colors;
   15mod document_symbols;
   16mod folding_ranges;
   17mod inlay_hints;
   18pub mod json_language_server_ext;
   19pub mod log_store;
   20pub mod lsp_ext_command;
   21pub mod rust_analyzer_ext;
   22mod semantic_tokens;
   23pub mod vue_language_server_ext;
   24
   25use self::code_lens::CodeLensData;
   26use self::document_colors::DocumentColorData;
   27use self::document_symbols::DocumentSymbolsData;
   28use self::inlay_hints::BufferInlayHints;
   29use crate::{
   30    CodeAction, Completion, CompletionDisplayOptions, CompletionResponse, CompletionSource,
   31    CoreCompletion, Hover, InlayHint, InlayId, LocationLink, LspAction, LspPullDiagnostics,
   32    ManifestProvidersStore, Project, ProjectItem, ProjectPath, ProjectTransaction,
   33    PulledDiagnostics, ResolveState, Symbol,
   34    buffer_store::{BufferStore, BufferStoreEvent},
   35    environment::ProjectEnvironment,
   36    lsp_command::{self, *},
   37    lsp_store::{
   38        self,
   39        folding_ranges::FoldingRangeData,
   40        log_store::{GlobalLogStore, LanguageServerKind},
   41        semantic_tokens::{SemanticTokenConfig, SemanticTokensData},
   42    },
   43    manifest_tree::{
   44        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   45        ManifestTree,
   46    },
   47    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   48    project_settings::{BinarySettings, LspSettings, ProjectSettings},
   49    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   50    trusted_worktrees::{PathTrust, TrustedWorktrees, TrustedWorktreesEvent},
   51    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   52    yarn::YarnPathStore,
   53};
   54use anyhow::{Context as _, Result, anyhow};
   55use async_trait::async_trait;
   56use client::{TypedEnvelope, proto};
   57use clock::Global;
   58use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   59use futures::{
   60    AsyncWriteExt, Future, FutureExt, StreamExt,
   61    future::{Either, Shared, join_all, pending, select},
   62    select, select_biased,
   63    stream::FuturesUnordered,
   64};
   65use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   66use gpui::{
   67    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString,
   68    Subscription, Task, WeakEntity,
   69};
   70use http_client::HttpClient;
   71use itertools::Itertools as _;
   72use language::{
   73    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, Capability, CodeLabel,
   74    Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language,
   75    LanguageName, LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller,
   76    ManifestDelegate, ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16,
   77    Toolchain, Transaction, Unclipped,
   78    language_settings::{
   79        AllLanguageSettings, FormatOnSave, Formatter, LanguageSettings, all_language_settings,
   80        language_settings,
   81    },
   82    point_to_lsp,
   83    proto::{
   84        deserialize_anchor, deserialize_anchor_range, deserialize_version, serialize_anchor,
   85        serialize_anchor_range, serialize_version,
   86    },
   87    range_from_lsp, range_to_lsp,
   88    row_chunk::RowChunk,
   89};
   90use lsp::{
   91    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   92    DEFAULT_LSP_REQUEST_TIMEOUT, DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   93    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   94    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LanguageServer,
   95    LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId, LanguageServerName,
   96    LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType, OneOf,
   97    RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles,
   98    WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   99};
  100use node_runtime::read_package_installed_version;
  101use parking_lot::Mutex;
  102use postage::{mpsc, sink::Sink, stream::Stream, watch};
  103use rand::prelude::*;
  104use rpc::{
  105    AnyProtoClient, ErrorCode, ErrorExt as _,
  106    proto::{LspRequestId, LspRequestMessage as _},
  107};
  108use semver::Version;
  109use serde::Serialize;
  110use serde_json::Value;
  111use settings::{Settings, SettingsLocation, SettingsStore};
  112use sha2::{Digest, Sha256};
  113use snippet::Snippet;
  114use std::{
  115    any::TypeId,
  116    borrow::Cow,
  117    cell::RefCell,
  118    cmp::{Ordering, Reverse},
  119    collections::{VecDeque, hash_map},
  120    convert::TryInto,
  121    ffi::OsStr,
  122    future::ready,
  123    iter, mem,
  124    ops::{ControlFlow, Range},
  125    path::{self, Path, PathBuf},
  126    pin::pin,
  127    rc::Rc,
  128    sync::{
  129        Arc,
  130        atomic::{self, AtomicUsize},
  131    },
  132    time::{Duration, Instant},
  133    vec,
  134};
  135use sum_tree::Dimensions;
  136use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  137
  138use util::{
  139    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  140    paths::{PathStyle, SanitizedPath, UrlExt},
  141    post_inc,
  142    redact::redact_command,
  143    rel_path::RelPath,
  144};
  145
  146pub use document_colors::DocumentColors;
  147pub use folding_ranges::LspFoldingRange;
  148pub use fs::*;
  149pub use language::Location;
  150pub use lsp_store::inlay_hints::{CacheInlayHints, InvalidationStrategy};
  151#[cfg(any(test, feature = "test-support"))]
  152pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  153pub use semantic_tokens::{
  154    BufferSemanticToken, BufferSemanticTokens, RefreshForServer, SemanticTokenStylizer, TokenType,
  155};
  156
  157pub use worktree::{
  158    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  159    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  160};
  161
  162const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  163pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  164const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  165const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  166static NEXT_PROMPT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
  167
  168#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  169pub enum ProgressToken {
  170    Number(i32),
  171    String(SharedString),
  172}
  173
  174impl std::fmt::Display for ProgressToken {
  175    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  176        match self {
  177            Self::Number(number) => write!(f, "{number}"),
  178            Self::String(string) => write!(f, "{string}"),
  179        }
  180    }
  181}
  182
  183impl ProgressToken {
  184    fn from_lsp(value: lsp::NumberOrString) -> Self {
  185        match value {
  186            lsp::NumberOrString::Number(number) => Self::Number(number),
  187            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  188        }
  189    }
  190
  191    fn to_lsp(&self) -> lsp::NumberOrString {
  192        match self {
  193            Self::Number(number) => lsp::NumberOrString::Number(*number),
  194            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  195        }
  196    }
  197
  198    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  199        Some(match value.value? {
  200            proto::progress_token::Value::Number(number) => Self::Number(number),
  201            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  202        })
  203    }
  204
  205    fn to_proto(&self) -> proto::ProgressToken {
  206        proto::ProgressToken {
  207            value: Some(match self {
  208                Self::Number(number) => proto::progress_token::Value::Number(*number),
  209                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  210            }),
  211        }
  212    }
  213}
  214
  215#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  216pub enum FormatTrigger {
  217    Save,
  218    Manual,
  219}
  220
  221pub enum LspFormatTarget {
  222    Buffers,
  223    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  224}
  225
  226#[derive(Debug, Clone, PartialEq, Eq, Hash)]
  227pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  228
  229struct OpenLspBuffer(Entity<Buffer>);
  230
  231impl FormatTrigger {
  232    fn from_proto(value: i32) -> FormatTrigger {
  233        match value {
  234            0 => FormatTrigger::Save,
  235            1 => FormatTrigger::Manual,
  236            _ => FormatTrigger::Save,
  237        }
  238    }
  239}
  240
  241#[derive(Clone)]
  242struct UnifiedLanguageServer {
  243    id: LanguageServerId,
  244    project_roots: HashSet<Arc<RelPath>>,
  245}
  246
  247/// Settings that affect language server identity.
  248///
  249/// Dynamic settings (`LspSettings::settings`) are excluded because they can be
  250/// updated via `workspace/didChangeConfiguration` without restarting the server.
  251#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  252struct LanguageServerSeedSettings {
  253    binary: Option<BinarySettings>,
  254    initialization_options: Option<serde_json::Value>,
  255}
  256
  257#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  258struct LanguageServerSeed {
  259    worktree_id: WorktreeId,
  260    name: LanguageServerName,
  261    toolchain: Option<Toolchain>,
  262    settings: LanguageServerSeedSettings,
  263}
  264
  265#[derive(Debug)]
  266pub struct DocumentDiagnosticsUpdate<'a, D> {
  267    pub diagnostics: D,
  268    pub result_id: Option<SharedString>,
  269    pub registration_id: Option<SharedString>,
  270    pub server_id: LanguageServerId,
  271    pub disk_based_sources: Cow<'a, [String]>,
  272}
  273
  274pub struct DocumentDiagnostics {
  275    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  276    document_abs_path: PathBuf,
  277    version: Option<i32>,
  278}
  279
  280#[derive(Default, Debug)]
  281struct DynamicRegistrations {
  282    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  283    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  284}
  285
  286pub struct LocalLspStore {
  287    weak: WeakEntity<LspStore>,
  288    pub worktree_store: Entity<WorktreeStore>,
  289    toolchain_store: Entity<LocalToolchainStore>,
  290    http_client: Arc<dyn HttpClient>,
  291    environment: Entity<ProjectEnvironment>,
  292    fs: Arc<dyn Fs>,
  293    languages: Arc<LanguageRegistry>,
  294    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  295    yarn: Entity<YarnPathStore>,
  296    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  297    buffers_being_formatted: HashSet<BufferId>,
  298    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  299    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  300    watched_manifest_filenames: HashSet<ManifestName>,
  301    language_server_paths_watched_for_rename:
  302        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  303    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  304    supplementary_language_servers:
  305        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  306    prettier_store: Entity<PrettierStore>,
  307    next_diagnostic_group_id: usize,
  308    diagnostics: HashMap<
  309        WorktreeId,
  310        HashMap<
  311            Arc<RelPath>,
  312            Vec<(
  313                LanguageServerId,
  314                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  315            )>,
  316        >,
  317    >,
  318    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  319    _subscription: gpui::Subscription,
  320    lsp_tree: LanguageServerTree,
  321    registered_buffers: HashMap<BufferId, usize>,
  322    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  323    buffer_pull_diagnostics_result_ids: HashMap<
  324        LanguageServerId,
  325        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  326    >,
  327    workspace_pull_diagnostics_result_ids: HashMap<
  328        LanguageServerId,
  329        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  330    >,
  331    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  332
  333    buffers_to_refresh_hash_set: HashSet<BufferId>,
  334    buffers_to_refresh_queue: VecDeque<BufferId>,
  335    _background_diagnostics_worker: Shared<Task<()>>,
  336}
  337
  338impl LocalLspStore {
  339    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  340    pub fn running_language_server_for_id(
  341        &self,
  342        id: LanguageServerId,
  343    ) -> Option<&Arc<LanguageServer>> {
  344        let language_server_state = self.language_servers.get(&id)?;
  345
  346        match language_server_state {
  347            LanguageServerState::Running { server, .. } => Some(server),
  348            LanguageServerState::Starting { .. } => None,
  349        }
  350    }
  351
  352    fn get_or_insert_language_server(
  353        &mut self,
  354        worktree_handle: &Entity<Worktree>,
  355        delegate: Arc<LocalLspAdapterDelegate>,
  356        disposition: &Arc<LaunchDisposition>,
  357        language_name: &LanguageName,
  358        cx: &mut App,
  359    ) -> LanguageServerId {
  360        let key = LanguageServerSeed {
  361            worktree_id: worktree_handle.read(cx).id(),
  362            name: disposition.server_name.clone(),
  363            settings: LanguageServerSeedSettings {
  364                binary: disposition.settings.binary.clone(),
  365                initialization_options: disposition.settings.initialization_options.clone(),
  366            },
  367            toolchain: disposition.toolchain.clone(),
  368        };
  369        if let Some(state) = self.language_server_ids.get_mut(&key) {
  370            state.project_roots.insert(disposition.path.path.clone());
  371            state.id
  372        } else {
  373            let adapter = self
  374                .languages
  375                .lsp_adapters(language_name)
  376                .into_iter()
  377                .find(|adapter| adapter.name() == disposition.server_name)
  378                .expect("To find LSP adapter");
  379            let new_language_server_id = self.start_language_server(
  380                worktree_handle,
  381                delegate,
  382                adapter,
  383                disposition.settings.clone(),
  384                key.clone(),
  385                language_name.clone(),
  386                cx,
  387            );
  388            if let Some(state) = self.language_server_ids.get_mut(&key) {
  389                state.project_roots.insert(disposition.path.path.clone());
  390            } else {
  391                debug_assert!(
  392                    false,
  393                    "Expected `start_language_server` to ensure that `key` exists in a map"
  394                );
  395            }
  396            new_language_server_id
  397        }
  398    }
  399
  400    fn start_language_server(
  401        &mut self,
  402        worktree_handle: &Entity<Worktree>,
  403        delegate: Arc<LocalLspAdapterDelegate>,
  404        adapter: Arc<CachedLspAdapter>,
  405        settings: Arc<LspSettings>,
  406        key: LanguageServerSeed,
  407        language_name: LanguageName,
  408        cx: &mut App,
  409    ) -> LanguageServerId {
  410        let worktree = worktree_handle.read(cx);
  411
  412        let worktree_id = worktree.id();
  413        let worktree_abs_path = worktree.abs_path();
  414        let toolchain = key.toolchain.clone();
  415        let override_options = settings.initialization_options.clone();
  416
  417        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  418
  419        let server_id = self.languages.next_language_server_id();
  420        log::trace!(
  421            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  422            adapter.name.0
  423        );
  424
  425        let wait_until_worktree_trust =
  426            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  427                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  428                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  429                });
  430                if can_trust {
  431                    self.restricted_worktrees_tasks.remove(&worktree_id);
  432                    None
  433                } else {
  434                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  435                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  436                        hash_map::Entry::Vacant(v) => {
  437                            let (mut tx, rx) = watch::channel::<bool>();
  438                            let lsp_store = self.weak.clone();
  439                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  440                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  441                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  442                                        tx.blocking_send(true).ok();
  443                                        lsp_store
  444                                            .update(cx, |lsp_store, _| {
  445                                                if let Some(local_lsp_store) =
  446                                                    lsp_store.as_local_mut()
  447                                                {
  448                                                    local_lsp_store
  449                                                        .restricted_worktrees_tasks
  450                                                        .remove(&worktree_id);
  451                                                }
  452                                            })
  453                                            .ok();
  454                                    }
  455                                }
  456                            });
  457                            v.insert((subscription, rx.clone()));
  458                            Some(rx)
  459                        }
  460                    }
  461                }
  462            });
  463        let update_binary_status = wait_until_worktree_trust.is_none();
  464
  465        let binary = self.get_language_server_binary(
  466            worktree_abs_path.clone(),
  467            adapter.clone(),
  468            settings,
  469            toolchain.clone(),
  470            delegate.clone(),
  471            true,
  472            wait_until_worktree_trust,
  473            cx,
  474        );
  475        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  476
  477        let pending_server = cx.spawn({
  478            let adapter = adapter.clone();
  479            let server_name = adapter.name.clone();
  480            let stderr_capture = stderr_capture.clone();
  481            #[cfg(any(test, feature = "test-support"))]
  482            let lsp_store = self.weak.clone();
  483            let pending_workspace_folders = pending_workspace_folders.clone();
  484            async move |cx| {
  485                let binary = binary.await?;
  486                #[cfg(any(test, feature = "test-support"))]
  487                if let Some(server) = lsp_store
  488                    .update(&mut cx.clone(), |this, cx| {
  489                        this.languages.create_fake_language_server(
  490                            server_id,
  491                            &server_name,
  492                            binary.clone(),
  493                            &mut cx.to_async(),
  494                        )
  495                    })
  496                    .ok()
  497                    .flatten()
  498                {
  499                    return Ok(server);
  500                }
  501
  502                let code_action_kinds = adapter.code_action_kinds();
  503                lsp::LanguageServer::new(
  504                    stderr_capture,
  505                    server_id,
  506                    server_name,
  507                    binary,
  508                    &worktree_abs_path,
  509                    code_action_kinds,
  510                    Some(pending_workspace_folders),
  511                    cx,
  512                )
  513            }
  514        });
  515
  516        let startup = {
  517            let server_name = adapter.name.0.clone();
  518            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  519            let key = key.clone();
  520            let adapter = adapter.clone();
  521            let lsp_store = self.weak.clone();
  522            let pending_workspace_folders = pending_workspace_folders.clone();
  523            let pull_diagnostics = ProjectSettings::get_global(cx)
  524                .diagnostics
  525                .lsp_pull_diagnostics
  526                .enabled;
  527            let settings_location = SettingsLocation {
  528                worktree_id,
  529                path: RelPath::empty(),
  530            };
  531            let augments_syntax_tokens = AllLanguageSettings::get(Some(settings_location), cx)
  532                .language(Some(settings_location), Some(&language_name), cx)
  533                .semantic_tokens
  534                .use_tree_sitter();
  535            cx.spawn(async move |cx| {
  536                let result = async {
  537                    let language_server = pending_server.await?;
  538
  539                    let workspace_config = Self::workspace_configuration_for_adapter(
  540                        adapter.adapter.clone(),
  541                        &delegate,
  542                        toolchain,
  543                        None,
  544                        cx,
  545                    )
  546                    .await?;
  547
  548                    let mut initialization_options = Self::initialization_options_for_adapter(
  549                        adapter.adapter.clone(),
  550                        &delegate,
  551                        cx,
  552                    )
  553                    .await?;
  554
  555                    match (&mut initialization_options, override_options) {
  556                        (Some(initialization_options), Some(override_options)) => {
  557                            merge_json_value_into(override_options, initialization_options);
  558                        }
  559                        (None, override_options) => initialization_options = override_options,
  560                        _ => {}
  561                    }
  562
  563                    let initialization_params = cx.update(|cx| {
  564                        let mut params = language_server.default_initialize_params(
  565                            pull_diagnostics,
  566                            augments_syntax_tokens,
  567                            cx,
  568                        );
  569                        params.initialization_options = initialization_options;
  570                        adapter.adapter.prepare_initialize_params(params, cx)
  571                    })?;
  572
  573                    Self::setup_lsp_messages(
  574                        lsp_store.clone(),
  575                        &language_server,
  576                        delegate.clone(),
  577                        adapter.clone(),
  578                    );
  579
  580                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  581                        settings: workspace_config,
  582                    };
  583                    let language_server = cx
  584                        .update(|cx| {
  585                            let request_timeout = ProjectSettings::get_global(cx)
  586                                .global_lsp_settings
  587                                .get_request_timeout();
  588
  589                            language_server.initialize(
  590                                initialization_params,
  591                                Arc::new(did_change_configuration_params.clone()),
  592                                request_timeout,
  593                                cx,
  594                            )
  595                        })
  596                        .await
  597                        .inspect_err(|_| {
  598                            if let Some(lsp_store) = lsp_store.upgrade() {
  599                                lsp_store.update(cx, |lsp_store, cx| {
  600                                    lsp_store.cleanup_lsp_data(server_id);
  601                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  602                                });
  603                            }
  604                        })?;
  605
  606                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  607                        did_change_configuration_params,
  608                    )?;
  609
  610                    anyhow::Ok(language_server)
  611                }
  612                .await;
  613
  614                match result {
  615                    Ok(server) => {
  616                        lsp_store
  617                            .update(cx, |lsp_store, cx| {
  618                                lsp_store.insert_newly_running_language_server(
  619                                    adapter,
  620                                    server.clone(),
  621                                    server_id,
  622                                    key,
  623                                    pending_workspace_folders,
  624                                    cx,
  625                                );
  626                            })
  627                            .ok();
  628                        stderr_capture.lock().take();
  629                        Some(server)
  630                    }
  631
  632                    Err(err) => {
  633                        let log = stderr_capture.lock().take().unwrap_or_default();
  634                        delegate.update_status(
  635                            adapter.name(),
  636                            BinaryStatus::Failed {
  637                                error: if log.is_empty() {
  638                                    format!("{err:#}")
  639                                } else {
  640                                    format!("{err:#}\n-- stderr --\n{log}")
  641                                },
  642                            },
  643                        );
  644                        log::error!(
  645                            "Failed to start language server {server_name:?}: {}",
  646                            redact_command(&format!("{err:?}"))
  647                        );
  648                        if !log.is_empty() {
  649                            log::error!("server stderr: {}", redact_command(&log));
  650                        }
  651                        None
  652                    }
  653                }
  654            })
  655        };
  656        let state = LanguageServerState::Starting {
  657            startup,
  658            pending_workspace_folders,
  659        };
  660
  661        if update_binary_status {
  662            self.languages
  663                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  664        }
  665
  666        self.language_servers.insert(server_id, state);
  667        self.language_server_ids
  668            .entry(key)
  669            .or_insert(UnifiedLanguageServer {
  670                id: server_id,
  671                project_roots: Default::default(),
  672            });
  673        server_id
  674    }
  675
  676    fn get_language_server_binary(
  677        &self,
  678        worktree_abs_path: Arc<Path>,
  679        adapter: Arc<CachedLspAdapter>,
  680        settings: Arc<LspSettings>,
  681        toolchain: Option<Toolchain>,
  682        delegate: Arc<dyn LspAdapterDelegate>,
  683        allow_binary_download: bool,
  684        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  685        cx: &mut App,
  686    ) -> Task<Result<LanguageServerBinary>> {
  687        if let Some(settings) = &settings.binary
  688            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  689        {
  690            let settings = settings.clone();
  691            let languages = self.languages.clone();
  692            return cx.background_spawn(async move {
  693                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  694                    let already_trusted =  *wait_until_worktree_trust.borrow();
  695                    if !already_trusted {
  696                        log::info!(
  697                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  698                            adapter.name(),
  699                        );
  700                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  701                            if worktree_trusted {
  702                                break;
  703                            }
  704                        }
  705                        log::info!(
  706                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  707                            adapter.name(),
  708                        );
  709                    }
  710                    languages
  711                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  712                }
  713                let mut env = delegate.shell_env().await;
  714                env.extend(settings.env.unwrap_or_default());
  715
  716                Ok(LanguageServerBinary {
  717                    path: delegate.resolve_relative_path(path),
  718                    env: Some(env),
  719                    arguments: settings
  720                        .arguments
  721                        .unwrap_or_default()
  722                        .iter()
  723                        .map(Into::into)
  724                        .collect(),
  725                })
  726            });
  727        }
  728        let lsp_binary_options = LanguageServerBinaryOptions {
  729            allow_path_lookup: !settings
  730                .binary
  731                .as_ref()
  732                .and_then(|b| b.ignore_system_version)
  733                .unwrap_or_default(),
  734            allow_binary_download,
  735            pre_release: settings
  736                .fetch
  737                .as_ref()
  738                .and_then(|f| f.pre_release)
  739                .unwrap_or(false),
  740        };
  741
  742        cx.spawn(async move |cx| {
  743            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  744                let already_trusted =  *wait_until_worktree_trust.borrow();
  745                if !already_trusted {
  746                    log::info!(
  747                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  748                        adapter.name(),
  749                    );
  750                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  751                        if worktree_trusted {
  752                            break;
  753                        }
  754                    }
  755                    log::info!(
  756                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  757                            adapter.name(),
  758                    );
  759                }
  760            }
  761
  762            let (existing_binary, maybe_download_binary) = adapter
  763                .clone()
  764                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  765                .await
  766                .await;
  767
  768            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  769
  770            let mut binary = match (existing_binary, maybe_download_binary) {
  771                (binary, None) => binary?,
  772                (Err(_), Some(downloader)) => downloader.await?,
  773                (Ok(existing_binary), Some(downloader)) => {
  774                    let mut download_timeout = cx
  775                        .background_executor()
  776                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  777                        .fuse();
  778                    let mut downloader = downloader.fuse();
  779                    futures::select! {
  780                        _ = download_timeout => {
  781                            // Return existing binary and kick the existing work to the background.
  782                            cx.spawn(async move |_| downloader.await).detach();
  783                            Ok(existing_binary)
  784                        },
  785                        downloaded_or_existing_binary = downloader => {
  786                            // If download fails, this results in the existing binary.
  787                            downloaded_or_existing_binary
  788                        }
  789                    }?
  790                }
  791            };
  792            let mut shell_env = delegate.shell_env().await;
  793
  794            shell_env.extend(binary.env.unwrap_or_default());
  795
  796            if let Some(settings) = settings.binary.as_ref() {
  797                if let Some(arguments) = &settings.arguments {
  798                    binary.arguments = arguments.iter().map(Into::into).collect();
  799                }
  800                if let Some(env) = &settings.env {
  801                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  802                }
  803            }
  804
  805            binary.env = Some(shell_env);
  806            Ok(binary)
  807        })
  808    }
  809
  810    fn setup_lsp_messages(
  811        lsp_store: WeakEntity<LspStore>,
  812        language_server: &LanguageServer,
  813        delegate: Arc<dyn LspAdapterDelegate>,
  814        adapter: Arc<CachedLspAdapter>,
  815    ) {
  816        let name = language_server.name();
  817        let server_id = language_server.server_id();
  818        language_server
  819            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  820                let adapter = adapter.clone();
  821                let this = lsp_store.clone();
  822                move |mut params, cx| {
  823                    let adapter = adapter.clone();
  824                    if let Some(this) = this.upgrade() {
  825                        this.update(cx, |this, cx| {
  826                            {
  827                                let buffer = params
  828                                    .uri
  829                                    .to_file_path()
  830                                    .map(|file_path| this.get_buffer(&file_path, cx))
  831                                    .ok()
  832                                    .flatten();
  833                                adapter.process_diagnostics(&mut params, server_id, buffer);
  834                            }
  835
  836                            this.merge_lsp_diagnostics(
  837                                DiagnosticSourceKind::Pushed,
  838                                vec![DocumentDiagnosticsUpdate {
  839                                    server_id,
  840                                    diagnostics: params,
  841                                    result_id: None,
  842                                    disk_based_sources: Cow::Borrowed(
  843                                        &adapter.disk_based_diagnostic_sources,
  844                                    ),
  845                                    registration_id: None,
  846                                }],
  847                                |_, diagnostic, cx| match diagnostic.source_kind {
  848                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  849                                        adapter.retain_old_diagnostic(diagnostic, cx)
  850                                    }
  851                                    DiagnosticSourceKind::Pulled => true,
  852                                },
  853                                cx,
  854                            )
  855                            .log_err();
  856                        });
  857                    }
  858                }
  859            })
  860            .detach();
  861        language_server
  862            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  863                let adapter = adapter.adapter.clone();
  864                let delegate = delegate.clone();
  865                let this = lsp_store.clone();
  866                move |params, cx| {
  867                    let adapter = adapter.clone();
  868                    let delegate = delegate.clone();
  869                    let this = this.clone();
  870                    let mut cx = cx.clone();
  871                    async move {
  872                        let toolchain_for_id = this
  873                            .update(&mut cx, |this, _| {
  874                                this.as_local()?.language_server_ids.iter().find_map(
  875                                    |(seed, value)| {
  876                                        (value.id == server_id).then(|| seed.toolchain.clone())
  877                                    },
  878                                )
  879                            })?
  880                            .context("Expected the LSP store to be in a local mode")?;
  881
  882                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  883                        for item in &params.items {
  884                            let scope_uri = item.scope_uri.clone();
  885                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  886                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  887                            else {
  888                                // We've already queried workspace configuration of this URI.
  889                                continue;
  890                            };
  891                            let workspace_config = Self::workspace_configuration_for_adapter(
  892                                adapter.clone(),
  893                                &delegate,
  894                                toolchain_for_id.clone(),
  895                                scope_uri,
  896                                &mut cx,
  897                            )
  898                            .await?;
  899                            new_scope_uri.insert(workspace_config);
  900                        }
  901
  902                        Ok(params
  903                            .items
  904                            .into_iter()
  905                            .filter_map(|item| {
  906                                let workspace_config =
  907                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  908                                if let Some(section) = &item.section {
  909                                    Some(
  910                                        workspace_config
  911                                            .get(section)
  912                                            .cloned()
  913                                            .unwrap_or(serde_json::Value::Null),
  914                                    )
  915                                } else {
  916                                    Some(workspace_config.clone())
  917                                }
  918                            })
  919                            .collect())
  920                    }
  921                }
  922            })
  923            .detach();
  924
  925        language_server
  926            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  927                let this = lsp_store.clone();
  928                move |_, cx| {
  929                    let this = this.clone();
  930                    let cx = cx.clone();
  931                    async move {
  932                        let Some(server) =
  933                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  934                        else {
  935                            return Ok(None);
  936                        };
  937                        let root = server.workspace_folders();
  938                        Ok(Some(
  939                            root.into_iter()
  940                                .map(|uri| WorkspaceFolder {
  941                                    uri,
  942                                    name: Default::default(),
  943                                })
  944                                .collect(),
  945                        ))
  946                    }
  947                }
  948            })
  949            .detach();
  950        // Even though we don't have handling for these requests, respond to them to
  951        // avoid stalling any language server like `gopls` which waits for a response
  952        // to these requests when initializing.
  953        language_server
  954            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  955                let this = lsp_store.clone();
  956                move |params, cx| {
  957                    let this = this.clone();
  958                    let mut cx = cx.clone();
  959                    async move {
  960                        this.update(&mut cx, |this, _| {
  961                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  962                            {
  963                                status
  964                                    .progress_tokens
  965                                    .insert(ProgressToken::from_lsp(params.token));
  966                            }
  967                        })?;
  968
  969                        Ok(())
  970                    }
  971                }
  972            })
  973            .detach();
  974
  975        language_server
  976            .on_request::<lsp::request::RegisterCapability, _, _>({
  977                let lsp_store = lsp_store.clone();
  978                move |params, cx| {
  979                    let lsp_store = lsp_store.clone();
  980                    let mut cx = cx.clone();
  981                    async move {
  982                        lsp_store
  983                            .update(&mut cx, |lsp_store, cx| {
  984                                if lsp_store.as_local().is_some() {
  985                                    match lsp_store
  986                                        .register_server_capabilities(server_id, params, cx)
  987                                    {
  988                                        Ok(()) => {}
  989                                        Err(e) => {
  990                                            log::error!(
  991                                                "Failed to register server capabilities: {e:#}"
  992                                            );
  993                                        }
  994                                    };
  995                                }
  996                            })
  997                            .ok();
  998                        Ok(())
  999                    }
 1000                }
 1001            })
 1002            .detach();
 1003
 1004        language_server
 1005            .on_request::<lsp::request::UnregisterCapability, _, _>({
 1006                let lsp_store = lsp_store.clone();
 1007                move |params, cx| {
 1008                    let lsp_store = lsp_store.clone();
 1009                    let mut cx = cx.clone();
 1010                    async move {
 1011                        lsp_store
 1012                            .update(&mut cx, |lsp_store, cx| {
 1013                                if lsp_store.as_local().is_some() {
 1014                                    match lsp_store
 1015                                        .unregister_server_capabilities(server_id, params, cx)
 1016                                    {
 1017                                        Ok(()) => {}
 1018                                        Err(e) => {
 1019                                            log::error!(
 1020                                                "Failed to unregister server capabilities: {e:#}"
 1021                                            );
 1022                                        }
 1023                                    }
 1024                                }
 1025                            })
 1026                            .ok();
 1027                        Ok(())
 1028                    }
 1029                }
 1030            })
 1031            .detach();
 1032
 1033        language_server
 1034            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
 1035                let this = lsp_store.clone();
 1036                move |params, cx| {
 1037                    let mut cx = cx.clone();
 1038                    let this = this.clone();
 1039                    async move {
 1040                        LocalLspStore::on_lsp_workspace_edit(
 1041                            this.clone(),
 1042                            params,
 1043                            server_id,
 1044                            &mut cx,
 1045                        )
 1046                        .await
 1047                    }
 1048                }
 1049            })
 1050            .detach();
 1051
 1052        language_server
 1053            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1054                let lsp_store = lsp_store.clone();
 1055                let request_id = Arc::new(AtomicUsize::new(0));
 1056                move |(), cx| {
 1057                    let lsp_store = lsp_store.clone();
 1058                    let request_id = request_id.clone();
 1059                    let mut cx = cx.clone();
 1060                    async move {
 1061                        lsp_store
 1062                            .update(&mut cx, |lsp_store, cx| {
 1063                                let request_id =
 1064                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1065                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1066                                    server_id,
 1067                                    request_id,
 1068                                });
 1069                                lsp_store
 1070                                    .downstream_client
 1071                                    .as_ref()
 1072                                    .map(|(client, project_id)| {
 1073                                        client.send(proto::RefreshInlayHints {
 1074                                            project_id: *project_id,
 1075                                            server_id: server_id.to_proto(),
 1076                                            request_id: request_id.map(|id| id as u64),
 1077                                        })
 1078                                    })
 1079                            })?
 1080                            .transpose()?;
 1081                        Ok(())
 1082                    }
 1083                }
 1084            })
 1085            .detach();
 1086
 1087        language_server
 1088            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1089                let this = lsp_store.clone();
 1090                move |(), cx| {
 1091                    let this = this.clone();
 1092                    let mut cx = cx.clone();
 1093                    async move {
 1094                        this.update(&mut cx, |this, cx| {
 1095                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1096                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1097                                client.send(proto::RefreshCodeLens {
 1098                                    project_id: *project_id,
 1099                                })
 1100                            })
 1101                        })?
 1102                        .transpose()?;
 1103                        Ok(())
 1104                    }
 1105                }
 1106            })
 1107            .detach();
 1108
 1109        language_server
 1110            .on_request::<lsp::request::SemanticTokensRefresh, _, _>({
 1111                let lsp_store = lsp_store.clone();
 1112                let request_id = Arc::new(AtomicUsize::new(0));
 1113                move |(), cx| {
 1114                    let lsp_store = lsp_store.clone();
 1115                    let request_id = request_id.clone();
 1116                    let mut cx = cx.clone();
 1117                    async move {
 1118                        lsp_store
 1119                            .update(&mut cx, |lsp_store, cx| {
 1120                                let request_id =
 1121                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1122                                cx.emit(LspStoreEvent::RefreshSemanticTokens {
 1123                                    server_id,
 1124                                    request_id,
 1125                                });
 1126                                lsp_store
 1127                                    .downstream_client
 1128                                    .as_ref()
 1129                                    .map(|(client, project_id)| {
 1130                                        client.send(proto::RefreshSemanticTokens {
 1131                                            project_id: *project_id,
 1132                                            server_id: server_id.to_proto(),
 1133                                            request_id: request_id.map(|id| id as u64),
 1134                                        })
 1135                                    })
 1136                            })?
 1137                            .transpose()?;
 1138                        Ok(())
 1139                    }
 1140                }
 1141            })
 1142            .detach();
 1143
 1144        language_server
 1145            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1146                let this = lsp_store.clone();
 1147                move |(), cx| {
 1148                    let this = this.clone();
 1149                    let mut cx = cx.clone();
 1150                    async move {
 1151                        this.update(&mut cx, |lsp_store, cx| {
 1152                            lsp_store.pull_workspace_diagnostics(server_id);
 1153                            lsp_store
 1154                                .downstream_client
 1155                                .as_ref()
 1156                                .map(|(client, project_id)| {
 1157                                    client.send(proto::PullWorkspaceDiagnostics {
 1158                                        project_id: *project_id,
 1159                                        server_id: server_id.to_proto(),
 1160                                    })
 1161                                })
 1162                                .transpose()?;
 1163                            anyhow::Ok(
 1164                                lsp_store.pull_document_diagnostics_for_server(server_id, None, cx),
 1165                            )
 1166                        })??
 1167                        .await;
 1168                        Ok(())
 1169                    }
 1170                }
 1171            })
 1172            .detach();
 1173
 1174        language_server
 1175            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1176                let this = lsp_store.clone();
 1177                let name = name.to_string();
 1178                let adapter = adapter.clone();
 1179                move |params, cx| {
 1180                    let this = this.clone();
 1181                    let name = name.to_string();
 1182                    let adapter = adapter.clone();
 1183                    let mut cx = cx.clone();
 1184                    async move {
 1185                        let actions = params.actions.unwrap_or_default();
 1186                        let message = params.message.clone();
 1187                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1188                        let level = match params.typ {
 1189                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1190                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1191                            _ => PromptLevel::Info,
 1192                        };
 1193                        let request = LanguageServerPromptRequest::new(
 1194                            level,
 1195                            params.message,
 1196                            actions,
 1197                            name.clone(),
 1198                            tx,
 1199                        );
 1200
 1201                        let did_update = this
 1202                            .update(&mut cx, |_, cx| {
 1203                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1204                            })
 1205                            .is_ok();
 1206                        if did_update {
 1207                            let response = rx.recv().await.ok();
 1208                            if let Some(ref selected_action) = response {
 1209                                let context = language::PromptResponseContext {
 1210                                    message,
 1211                                    selected_action: selected_action.clone(),
 1212                                };
 1213                                adapter.process_prompt_response(&context, &mut cx)
 1214                            }
 1215
 1216                            Ok(response)
 1217                        } else {
 1218                            Ok(None)
 1219                        }
 1220                    }
 1221                }
 1222            })
 1223            .detach();
 1224        language_server
 1225            .on_notification::<lsp::notification::ShowMessage, _>({
 1226                let this = lsp_store.clone();
 1227                let name = name.to_string();
 1228                move |params, cx| {
 1229                    let this = this.clone();
 1230                    let name = name.to_string();
 1231                    let mut cx = cx.clone();
 1232
 1233                    let (tx, _) = smol::channel::bounded(1);
 1234                    let level = match params.typ {
 1235                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1236                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1237                        _ => PromptLevel::Info,
 1238                    };
 1239                    let request =
 1240                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1241
 1242                    let _ = this.update(&mut cx, |_, cx| {
 1243                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1244                    });
 1245                }
 1246            })
 1247            .detach();
 1248
 1249        let disk_based_diagnostics_progress_token =
 1250            adapter.disk_based_diagnostics_progress_token.clone();
 1251
 1252        language_server
 1253            .on_notification::<lsp::notification::Progress, _>({
 1254                let this = lsp_store.clone();
 1255                move |params, cx| {
 1256                    if let Some(this) = this.upgrade() {
 1257                        this.update(cx, |this, cx| {
 1258                            this.on_lsp_progress(
 1259                                params,
 1260                                server_id,
 1261                                disk_based_diagnostics_progress_token.clone(),
 1262                                cx,
 1263                            );
 1264                        });
 1265                    }
 1266                }
 1267            })
 1268            .detach();
 1269
 1270        language_server
 1271            .on_notification::<lsp::notification::LogMessage, _>({
 1272                let this = lsp_store.clone();
 1273                move |params, cx| {
 1274                    if let Some(this) = this.upgrade() {
 1275                        this.update(cx, |_, cx| {
 1276                            cx.emit(LspStoreEvent::LanguageServerLog(
 1277                                server_id,
 1278                                LanguageServerLogType::Log(params.typ),
 1279                                params.message,
 1280                            ));
 1281                        });
 1282                    }
 1283                }
 1284            })
 1285            .detach();
 1286
 1287        language_server
 1288            .on_notification::<lsp::notification::LogTrace, _>({
 1289                let this = lsp_store.clone();
 1290                move |params, cx| {
 1291                    let mut cx = cx.clone();
 1292                    if let Some(this) = this.upgrade() {
 1293                        this.update(&mut cx, |_, cx| {
 1294                            cx.emit(LspStoreEvent::LanguageServerLog(
 1295                                server_id,
 1296                                LanguageServerLogType::Trace {
 1297                                    verbose_info: params.verbose,
 1298                                },
 1299                                params.message,
 1300                            ));
 1301                        });
 1302                    }
 1303                }
 1304            })
 1305            .detach();
 1306
 1307        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1308        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1309        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1310        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1311    }
 1312
 1313    fn shutdown_language_servers_on_quit(&mut self) -> impl Future<Output = ()> + use<> {
 1314        let shutdown_futures = self
 1315            .language_servers
 1316            .drain()
 1317            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1318            .collect::<Vec<_>>();
 1319
 1320        async move {
 1321            join_all(shutdown_futures).await;
 1322        }
 1323    }
 1324
 1325    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1326        match server_state {
 1327            LanguageServerState::Running { server, .. } => {
 1328                if let Some(shutdown) = server.shutdown() {
 1329                    shutdown.await;
 1330                }
 1331            }
 1332            LanguageServerState::Starting { startup, .. } => {
 1333                if let Some(server) = startup.await
 1334                    && let Some(shutdown) = server.shutdown()
 1335                {
 1336                    shutdown.await;
 1337                }
 1338            }
 1339        }
 1340        Ok(())
 1341    }
 1342
 1343    fn language_servers_for_worktree(
 1344        &self,
 1345        worktree_id: WorktreeId,
 1346    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1347        self.language_server_ids
 1348            .iter()
 1349            .filter_map(move |(seed, state)| {
 1350                if seed.worktree_id != worktree_id {
 1351                    return None;
 1352                }
 1353
 1354                if let Some(LanguageServerState::Running { server, .. }) =
 1355                    self.language_servers.get(&state.id)
 1356                {
 1357                    Some(server)
 1358                } else {
 1359                    None
 1360                }
 1361            })
 1362    }
 1363
 1364    fn language_server_ids_for_project_path(
 1365        &self,
 1366        project_path: ProjectPath,
 1367        language: &Language,
 1368        cx: &mut App,
 1369    ) -> Vec<LanguageServerId> {
 1370        let Some(worktree) = self
 1371            .worktree_store
 1372            .read(cx)
 1373            .worktree_for_id(project_path.worktree_id, cx)
 1374        else {
 1375            return Vec::new();
 1376        };
 1377        let delegate: Arc<dyn ManifestDelegate> =
 1378            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1379
 1380        self.lsp_tree
 1381            .get(
 1382                project_path,
 1383                language.name(),
 1384                language.manifest(),
 1385                &delegate,
 1386                cx,
 1387            )
 1388            .collect::<Vec<_>>()
 1389    }
 1390
 1391    fn language_server_ids_for_buffer(
 1392        &self,
 1393        buffer: &Buffer,
 1394        cx: &mut App,
 1395    ) -> Vec<LanguageServerId> {
 1396        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1397            let worktree_id = file.worktree_id(cx);
 1398
 1399            let path: Arc<RelPath> = file
 1400                .path()
 1401                .parent()
 1402                .map(Arc::from)
 1403                .unwrap_or_else(|| file.path().clone());
 1404            let worktree_path = ProjectPath { worktree_id, path };
 1405            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1406        } else {
 1407            Vec::new()
 1408        }
 1409    }
 1410
 1411    fn language_servers_for_buffer<'a>(
 1412        &'a self,
 1413        buffer: &'a Buffer,
 1414        cx: &'a mut App,
 1415    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1416        self.language_server_ids_for_buffer(buffer, cx)
 1417            .into_iter()
 1418            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1419                LanguageServerState::Running {
 1420                    adapter, server, ..
 1421                } => Some((adapter, server)),
 1422                _ => None,
 1423            })
 1424    }
 1425
 1426    async fn execute_code_action_kind_locally(
 1427        lsp_store: WeakEntity<LspStore>,
 1428        mut buffers: Vec<Entity<Buffer>>,
 1429        kind: CodeActionKind,
 1430        push_to_history: bool,
 1431        cx: &mut AsyncApp,
 1432    ) -> anyhow::Result<ProjectTransaction> {
 1433        // Do not allow multiple concurrent code actions requests for the
 1434        // same buffer.
 1435        lsp_store.update(cx, |this, cx| {
 1436            let this = this.as_local_mut().unwrap();
 1437            buffers.retain(|buffer| {
 1438                this.buffers_being_formatted
 1439                    .insert(buffer.read(cx).remote_id())
 1440            });
 1441        })?;
 1442        let _cleanup = defer({
 1443            let this = lsp_store.clone();
 1444            let mut cx = cx.clone();
 1445            let buffers = &buffers;
 1446            move || {
 1447                this.update(&mut cx, |this, cx| {
 1448                    let this = this.as_local_mut().unwrap();
 1449                    for buffer in buffers {
 1450                        this.buffers_being_formatted
 1451                            .remove(&buffer.read(cx).remote_id());
 1452                    }
 1453                })
 1454                .ok();
 1455            }
 1456        });
 1457        let mut project_transaction = ProjectTransaction::default();
 1458
 1459        for buffer in &buffers {
 1460            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1461                buffer.update(cx, |buffer, cx| {
 1462                    lsp_store
 1463                        .as_local()
 1464                        .unwrap()
 1465                        .language_servers_for_buffer(buffer, cx)
 1466                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1467                        .collect::<Vec<_>>()
 1468                })
 1469            })?;
 1470            for (_, language_server) in adapters_and_servers.iter() {
 1471                let actions = Self::get_server_code_actions_from_action_kinds(
 1472                    &lsp_store,
 1473                    language_server.server_id(),
 1474                    vec![kind.clone()],
 1475                    buffer,
 1476                    cx,
 1477                )
 1478                .await?;
 1479                Self::execute_code_actions_on_server(
 1480                    &lsp_store,
 1481                    language_server,
 1482                    actions,
 1483                    push_to_history,
 1484                    &mut project_transaction,
 1485                    cx,
 1486                )
 1487                .await?;
 1488            }
 1489        }
 1490        Ok(project_transaction)
 1491    }
 1492
 1493    async fn format_locally(
 1494        lsp_store: WeakEntity<LspStore>,
 1495        mut buffers: Vec<FormattableBuffer>,
 1496        push_to_history: bool,
 1497        trigger: FormatTrigger,
 1498        logger: zlog::Logger,
 1499        cx: &mut AsyncApp,
 1500    ) -> anyhow::Result<ProjectTransaction> {
 1501        // Do not allow multiple concurrent formatting requests for the
 1502        // same buffer.
 1503        lsp_store.update(cx, |this, cx| {
 1504            let this = this.as_local_mut().unwrap();
 1505            buffers.retain(|buffer| {
 1506                this.buffers_being_formatted
 1507                    .insert(buffer.handle.read(cx).remote_id())
 1508            });
 1509        })?;
 1510
 1511        let _cleanup = defer({
 1512            let this = lsp_store.clone();
 1513            let mut cx = cx.clone();
 1514            let buffers = &buffers;
 1515            move || {
 1516                this.update(&mut cx, |this, cx| {
 1517                    let this = this.as_local_mut().unwrap();
 1518                    for buffer in buffers {
 1519                        this.buffers_being_formatted
 1520                            .remove(&buffer.handle.read(cx).remote_id());
 1521                    }
 1522                })
 1523                .ok();
 1524            }
 1525        });
 1526
 1527        let mut project_transaction = ProjectTransaction::default();
 1528
 1529        for buffer in &buffers {
 1530            zlog::debug!(
 1531                logger =>
 1532                "formatting buffer '{:?}'",
 1533                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1534            );
 1535            // Create an empty transaction to hold all of the formatting edits.
 1536            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1537                // ensure no transactions created while formatting are
 1538                // grouped with the previous transaction in the history
 1539                // based on the transaction group interval
 1540                buffer.finalize_last_transaction();
 1541                buffer
 1542                    .start_transaction()
 1543                    .context("transaction already open")?;
 1544                buffer.end_transaction(cx);
 1545                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1546                buffer.finalize_last_transaction();
 1547                anyhow::Ok(transaction_id)
 1548            })?;
 1549
 1550            let result = Self::format_buffer_locally(
 1551                lsp_store.clone(),
 1552                buffer,
 1553                formatting_transaction_id,
 1554                trigger,
 1555                logger,
 1556                cx,
 1557            )
 1558            .await;
 1559
 1560            buffer.handle.update(cx, |buffer, cx| {
 1561                let Some(formatting_transaction) =
 1562                    buffer.get_transaction(formatting_transaction_id).cloned()
 1563                else {
 1564                    zlog::warn!(logger => "no formatting transaction");
 1565                    return;
 1566                };
 1567                if formatting_transaction.edit_ids.is_empty() {
 1568                    zlog::debug!(logger => "no changes made while formatting");
 1569                    buffer.forget_transaction(formatting_transaction_id);
 1570                    return;
 1571                }
 1572                if !push_to_history {
 1573                    zlog::trace!(logger => "forgetting format transaction");
 1574                    buffer.forget_transaction(formatting_transaction.id);
 1575                }
 1576                project_transaction
 1577                    .0
 1578                    .insert(cx.entity(), formatting_transaction);
 1579            });
 1580
 1581            result?;
 1582        }
 1583
 1584        Ok(project_transaction)
 1585    }
 1586
 1587    async fn format_buffer_locally(
 1588        lsp_store: WeakEntity<LspStore>,
 1589        buffer: &FormattableBuffer,
 1590        formatting_transaction_id: clock::Lamport,
 1591        trigger: FormatTrigger,
 1592        logger: zlog::Logger,
 1593        cx: &mut AsyncApp,
 1594    ) -> Result<()> {
 1595        let (adapters_and_servers, settings, request_timeout) =
 1596            lsp_store.update(cx, |lsp_store, cx| {
 1597                buffer.handle.update(cx, |buffer, cx| {
 1598                    let adapters_and_servers = lsp_store
 1599                        .as_local()
 1600                        .unwrap()
 1601                        .language_servers_for_buffer(buffer, cx)
 1602                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1603                        .collect::<Vec<_>>();
 1604                    let settings =
 1605                        language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1606                            .into_owned();
 1607                    let request_timeout = ProjectSettings::get_global(cx)
 1608                        .global_lsp_settings
 1609                        .get_request_timeout();
 1610                    (adapters_and_servers, settings, request_timeout)
 1611                })
 1612            })?;
 1613
 1614        /// Apply edits to the buffer that will become part of the formatting transaction.
 1615        /// Fails if the buffer has been edited since the start of that transaction.
 1616        fn extend_formatting_transaction(
 1617            buffer: &FormattableBuffer,
 1618            formatting_transaction_id: text::TransactionId,
 1619            cx: &mut AsyncApp,
 1620            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1621        ) -> anyhow::Result<()> {
 1622            buffer.handle.update(cx, |buffer, cx| {
 1623                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1624                if last_transaction_id != Some(formatting_transaction_id) {
 1625                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1626                }
 1627                buffer.start_transaction();
 1628                operation(buffer, cx);
 1629                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1630                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1631                }
 1632                Ok(())
 1633            })
 1634        }
 1635
 1636        // handle whitespace formatting
 1637        if settings.remove_trailing_whitespace_on_save {
 1638            zlog::trace!(logger => "removing trailing whitespace");
 1639            let diff = buffer
 1640                .handle
 1641                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1642                .await;
 1643            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1644                buffer.apply_diff(diff, cx);
 1645            })?;
 1646        }
 1647
 1648        if settings.ensure_final_newline_on_save {
 1649            zlog::trace!(logger => "ensuring final newline");
 1650            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1651                buffer.ensure_final_newline(cx);
 1652            })?;
 1653        }
 1654
 1655        // Formatter for `code_actions_on_format` that runs before
 1656        // the rest of the formatters
 1657        let mut code_actions_on_format_formatters = None;
 1658        let should_run_code_actions_on_format = !matches!(
 1659            (trigger, &settings.format_on_save),
 1660            (FormatTrigger::Save, &FormatOnSave::Off)
 1661        );
 1662        if should_run_code_actions_on_format {
 1663            let have_code_actions_to_run_on_format = settings
 1664                .code_actions_on_format
 1665                .values()
 1666                .any(|enabled| *enabled);
 1667            if have_code_actions_to_run_on_format {
 1668                zlog::trace!(logger => "going to run code actions on format");
 1669                code_actions_on_format_formatters = Some(
 1670                    settings
 1671                        .code_actions_on_format
 1672                        .iter()
 1673                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1674                        .cloned()
 1675                        .map(Formatter::CodeAction)
 1676                        .collect::<Vec<_>>(),
 1677                );
 1678            }
 1679        }
 1680
 1681        let formatters = match (trigger, &settings.format_on_save) {
 1682            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1683            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1684                settings.formatter.as_ref()
 1685            }
 1686        };
 1687
 1688        let formatters = code_actions_on_format_formatters
 1689            .iter()
 1690            .flatten()
 1691            .chain(formatters);
 1692
 1693        for formatter in formatters {
 1694            let formatter = if formatter == &Formatter::Auto {
 1695                if settings.prettier.allowed {
 1696                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1697                    &Formatter::Prettier
 1698                } else {
 1699                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1700                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1701                }
 1702            } else {
 1703                formatter
 1704            };
 1705            match formatter {
 1706                Formatter::Auto => unreachable!("Auto resolved above"),
 1707                Formatter::Prettier => {
 1708                    let logger = zlog::scoped!(logger => "prettier");
 1709                    zlog::trace!(logger => "formatting");
 1710                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1711
 1712                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1713                        lsp_store.prettier_store().unwrap().downgrade()
 1714                    })?;
 1715                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1716                        .await
 1717                        .transpose()?;
 1718                    let Some(diff) = diff else {
 1719                        zlog::trace!(logger => "No changes");
 1720                        continue;
 1721                    };
 1722
 1723                    extend_formatting_transaction(
 1724                        buffer,
 1725                        formatting_transaction_id,
 1726                        cx,
 1727                        |buffer, cx| {
 1728                            buffer.apply_diff(diff, cx);
 1729                        },
 1730                    )?;
 1731                }
 1732                Formatter::External { command, arguments } => {
 1733                    let logger = zlog::scoped!(logger => "command");
 1734                    zlog::trace!(logger => "formatting");
 1735                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1736
 1737                    let diff = Self::format_via_external_command(
 1738                        buffer,
 1739                        &command,
 1740                        arguments.as_deref(),
 1741                        cx,
 1742                    )
 1743                    .await
 1744                    .with_context(|| {
 1745                        format!("Failed to format buffer via external command: {}", command)
 1746                    })?;
 1747                    let Some(diff) = diff else {
 1748                        zlog::trace!(logger => "No changes");
 1749                        continue;
 1750                    };
 1751
 1752                    extend_formatting_transaction(
 1753                        buffer,
 1754                        formatting_transaction_id,
 1755                        cx,
 1756                        |buffer, cx| {
 1757                            buffer.apply_diff(diff, cx);
 1758                        },
 1759                    )?;
 1760                }
 1761                Formatter::LanguageServer(specifier) => {
 1762                    let logger = zlog::scoped!(logger => "language-server");
 1763                    zlog::trace!(logger => "formatting");
 1764                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1765
 1766                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1767                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1768                        continue;
 1769                    };
 1770
 1771                    let language_server = match specifier {
 1772                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1773                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1774                                if adapter.name.0.as_ref() == name {
 1775                                    Some(server.clone())
 1776                                } else {
 1777                                    None
 1778                                }
 1779                            })
 1780                        }
 1781                        settings::LanguageServerFormatterSpecifier::Current => {
 1782                            adapters_and_servers.first().map(|e| e.1.clone())
 1783                        }
 1784                    };
 1785
 1786                    let Some(language_server) = language_server else {
 1787                        log::debug!(
 1788                            "No language server found to format buffer '{:?}'. Skipping",
 1789                            buffer_path_abs.as_path().to_string_lossy()
 1790                        );
 1791                        continue;
 1792                    };
 1793
 1794                    zlog::trace!(
 1795                        logger =>
 1796                        "Formatting buffer '{:?}' using language server '{:?}'",
 1797                        buffer_path_abs.as_path().to_string_lossy(),
 1798                        language_server.name()
 1799                    );
 1800
 1801                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1802                        zlog::trace!(logger => "formatting ranges");
 1803                        Self::format_ranges_via_lsp(
 1804                            &lsp_store,
 1805                            &buffer.handle,
 1806                            ranges,
 1807                            buffer_path_abs,
 1808                            &language_server,
 1809                            &settings,
 1810                            cx,
 1811                        )
 1812                        .await
 1813                        .context("Failed to format ranges via language server")?
 1814                    } else {
 1815                        zlog::trace!(logger => "formatting full");
 1816                        Self::format_via_lsp(
 1817                            &lsp_store,
 1818                            &buffer.handle,
 1819                            buffer_path_abs,
 1820                            &language_server,
 1821                            &settings,
 1822                            cx,
 1823                        )
 1824                        .await
 1825                        .context("failed to format via language server")?
 1826                    };
 1827
 1828                    if edits.is_empty() {
 1829                        zlog::trace!(logger => "No changes");
 1830                        continue;
 1831                    }
 1832                    extend_formatting_transaction(
 1833                        buffer,
 1834                        formatting_transaction_id,
 1835                        cx,
 1836                        |buffer, cx| {
 1837                            buffer.edit(edits, None, cx);
 1838                        },
 1839                    )?;
 1840                }
 1841                Formatter::CodeAction(code_action_name) => {
 1842                    let logger = zlog::scoped!(logger => "code-actions");
 1843                    zlog::trace!(logger => "formatting");
 1844                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1845
 1846                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1847                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1848                        continue;
 1849                    };
 1850
 1851                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1852                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1853
 1854                    let mut actions_and_servers = Vec::new();
 1855
 1856                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1857                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1858                            &lsp_store,
 1859                            language_server.server_id(),
 1860                            vec![code_action_kind.clone()],
 1861                            &buffer.handle,
 1862                            cx,
 1863                        )
 1864                        .await
 1865                        .with_context(|| {
 1866                            format!(
 1867                                "Failed to resolve code action {:?} with language server {}",
 1868                                code_action_kind,
 1869                                language_server.name()
 1870                            )
 1871                        });
 1872                        let Ok(actions) = actions_result else {
 1873                            // note: it may be better to set result to the error and break formatters here
 1874                            // but for now we try to execute the actions that we can resolve and skip the rest
 1875                            zlog::error!(
 1876                                logger =>
 1877                                "Failed to resolve code action {:?} with language server {}",
 1878                                code_action_kind,
 1879                                language_server.name()
 1880                            );
 1881                            continue;
 1882                        };
 1883                        for action in actions {
 1884                            actions_and_servers.push((action, index));
 1885                        }
 1886                    }
 1887
 1888                    if actions_and_servers.is_empty() {
 1889                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1890                        continue;
 1891                    }
 1892
 1893                    'actions: for (mut action, server_index) in actions_and_servers {
 1894                        let server = &adapters_and_servers[server_index].1;
 1895
 1896                        let describe_code_action = |action: &CodeAction| {
 1897                            format!(
 1898                                "code action '{}' with title \"{}\" on server {}",
 1899                                action
 1900                                    .lsp_action
 1901                                    .action_kind()
 1902                                    .unwrap_or("unknown".into())
 1903                                    .as_str(),
 1904                                action.lsp_action.title(),
 1905                                server.name(),
 1906                            )
 1907                        };
 1908
 1909                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1910
 1911                        if let Err(err) =
 1912                            Self::try_resolve_code_action(server, &mut action, request_timeout)
 1913                                .await
 1914                        {
 1915                            zlog::error!(
 1916                                logger =>
 1917                                "Failed to resolve {}. Error: {}",
 1918                                describe_code_action(&action),
 1919                                err
 1920                            );
 1921                            continue;
 1922                        }
 1923
 1924                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1925                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1926                            // but filters out and logs warnings for code actions that require unreasonably
 1927                            // difficult handling on our part, such as:
 1928                            // - applying edits that call commands
 1929                            //   which can result in arbitrary workspace edits being sent from the server that
 1930                            //   have no way of being tied back to the command that initiated them (i.e. we
 1931                            //   can't know which edits are part of the format request, or if the server is done sending
 1932                            //   actions in response to the command)
 1933                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1934                            //   as we then would need to handle such changes correctly in the local history as well
 1935                            //   as the remote history through the ProjectTransaction
 1936                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1937                            // Supporting these actions is not impossible, but not supported as of yet.
 1938                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1939                                zlog::trace!(
 1940                                    logger =>
 1941                                    "No changes for code action. Skipping {}",
 1942                                    describe_code_action(&action),
 1943                                );
 1944                                continue;
 1945                            }
 1946
 1947                            let mut operations = Vec::new();
 1948                            if let Some(document_changes) = edit.document_changes {
 1949                                match document_changes {
 1950                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1951                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1952                                    ),
 1953                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1954                                }
 1955                            } else if let Some(changes) = edit.changes {
 1956                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1957                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1958                                        text_document:
 1959                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1960                                                uri,
 1961                                                version: None,
 1962                                            },
 1963                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1964                                    })
 1965                                }));
 1966                            }
 1967
 1968                            let mut edits = Vec::with_capacity(operations.len());
 1969
 1970                            if operations.is_empty() {
 1971                                zlog::trace!(
 1972                                    logger =>
 1973                                    "No changes for code action. Skipping {}",
 1974                                    describe_code_action(&action),
 1975                                );
 1976                                continue;
 1977                            }
 1978                            for operation in operations {
 1979                                let op = match operation {
 1980                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1981                                    lsp::DocumentChangeOperation::Op(_) => {
 1982                                        zlog::warn!(
 1983                                            logger =>
 1984                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1985                                            describe_code_action(&action),
 1986                                        );
 1987                                        continue 'actions;
 1988                                    }
 1989                                };
 1990                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1991                                    zlog::warn!(
 1992                                        logger =>
 1993                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1994                                        &op.text_document.uri,
 1995                                        describe_code_action(&action),
 1996                                    );
 1997                                    continue 'actions;
 1998                                };
 1999                                if &file_path != buffer_path_abs {
 2000                                    zlog::warn!(
 2001                                        logger =>
 2002                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 2003                                        file_path,
 2004                                        buffer_path_abs,
 2005                                        describe_code_action(&action),
 2006                                    );
 2007                                    continue 'actions;
 2008                                }
 2009
 2010                                let mut lsp_edits = Vec::new();
 2011                                for edit in op.edits {
 2012                                    match edit {
 2013                                        Edit::Plain(edit) => {
 2014                                            if !lsp_edits.contains(&edit) {
 2015                                                lsp_edits.push(edit);
 2016                                            }
 2017                                        }
 2018                                        Edit::Annotated(edit) => {
 2019                                            if !lsp_edits.contains(&edit.text_edit) {
 2020                                                lsp_edits.push(edit.text_edit);
 2021                                            }
 2022                                        }
 2023                                        Edit::Snippet(_) => {
 2024                                            zlog::warn!(
 2025                                                logger =>
 2026                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 2027                                                describe_code_action(&action),
 2028                                            );
 2029                                            continue 'actions;
 2030                                        }
 2031                                    }
 2032                                }
 2033                                let edits_result = lsp_store
 2034                                    .update(cx, |lsp_store, cx| {
 2035                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 2036                                            &buffer.handle,
 2037                                            lsp_edits,
 2038                                            server.server_id(),
 2039                                            op.text_document.version,
 2040                                            cx,
 2041                                        )
 2042                                    })?
 2043                                    .await;
 2044                                let Ok(resolved_edits) = edits_result else {
 2045                                    zlog::warn!(
 2046                                        logger =>
 2047                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 2048                                        buffer_path_abs.as_path(),
 2049                                        describe_code_action(&action),
 2050                                    );
 2051                                    continue 'actions;
 2052                                };
 2053                                edits.extend(resolved_edits);
 2054                            }
 2055
 2056                            if edits.is_empty() {
 2057                                zlog::warn!(logger => "No edits resolved from LSP");
 2058                                continue;
 2059                            }
 2060
 2061                            extend_formatting_transaction(
 2062                                buffer,
 2063                                formatting_transaction_id,
 2064                                cx,
 2065                                |buffer, cx| {
 2066                                    zlog::info!(
 2067                                        "Applying edits {edits:?}. Content: {:?}",
 2068                                        buffer.text()
 2069                                    );
 2070                                    buffer.edit(edits, None, cx);
 2071                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 2072                                },
 2073                            )?;
 2074                        }
 2075
 2076                        // bail early if command is invalid
 2077                        let Some(command) = action.lsp_action.command() else {
 2078                            continue;
 2079                        };
 2080
 2081                        zlog::warn!(
 2082                            logger =>
 2083                            "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 2084                            &command.command,
 2085                        );
 2086
 2087                        let server_capabilities = server.capabilities();
 2088                        let available_commands = server_capabilities
 2089                            .execute_command_provider
 2090                            .as_ref()
 2091                            .map(|options| options.commands.as_slice())
 2092                            .unwrap_or_default();
 2093                        if !available_commands.contains(&command.command) {
 2094                            zlog::warn!(
 2095                                logger =>
 2096                                "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2097                                command.command,
 2098                                server.name(),
 2099                            );
 2100                            continue;
 2101                        }
 2102
 2103                        // noop so we just ensure buffer hasn't been edited since resolving code actions
 2104                        extend_formatting_transaction(
 2105                            buffer,
 2106                            formatting_transaction_id,
 2107                            cx,
 2108                            |_, _| {},
 2109                        )?;
 2110                        zlog::info!(logger => "Executing command {}", &command.command);
 2111
 2112                        lsp_store.update(cx, |this, _| {
 2113                            this.as_local_mut()
 2114                                .unwrap()
 2115                                .last_workspace_edits_by_language_server
 2116                                .remove(&server.server_id());
 2117                        })?;
 2118
 2119                        let execute_command_result = server
 2120                            .request::<lsp::request::ExecuteCommand>(
 2121                                lsp::ExecuteCommandParams {
 2122                                    command: command.command.clone(),
 2123                                    arguments: command.arguments.clone().unwrap_or_default(),
 2124                                    ..Default::default()
 2125                                },
 2126                                request_timeout,
 2127                            )
 2128                            .await
 2129                            .into_response();
 2130
 2131                        if execute_command_result.is_err() {
 2132                            zlog::error!(
 2133                                logger =>
 2134                                "Failed to execute command '{}' as part of {}",
 2135                                &command.command,
 2136                                describe_code_action(&action),
 2137                            );
 2138                            continue 'actions;
 2139                        }
 2140
 2141                        let mut project_transaction_command = lsp_store.update(cx, |this, _| {
 2142                            this.as_local_mut()
 2143                                .unwrap()
 2144                                .last_workspace_edits_by_language_server
 2145                                .remove(&server.server_id())
 2146                                .unwrap_or_default()
 2147                        })?;
 2148
 2149                        if let Some(transaction) =
 2150                            project_transaction_command.0.remove(&buffer.handle)
 2151                        {
 2152                            zlog::trace!(
 2153                                logger =>
 2154                                "Successfully captured {} edits that resulted from command {}",
 2155                                transaction.edit_ids.len(),
 2156                                &command.command,
 2157                            );
 2158                            let transaction_id_project_transaction = transaction.id;
 2159                            buffer.handle.update(cx, |buffer, _| {
 2160                                // it may have been removed from history if push_to_history was
 2161                                // false in deserialize_workspace_edit. If so push it so we
 2162                                // can merge it with the format transaction
 2163                                // and pop the combined transaction off the history stack
 2164                                // later if push_to_history is false
 2165                                if buffer.get_transaction(transaction.id).is_none() {
 2166                                    buffer.push_transaction(transaction, Instant::now());
 2167                                }
 2168                                buffer.merge_transactions(
 2169                                    transaction_id_project_transaction,
 2170                                    formatting_transaction_id,
 2171                                );
 2172                            });
 2173                        }
 2174
 2175                        if project_transaction_command.0.is_empty() {
 2176                            continue;
 2177                        }
 2178
 2179                        let mut extra_buffers = String::new();
 2180                        for buffer in project_transaction_command.0.keys() {
 2181                            buffer.read_with(cx, |b, cx| {
 2182                                let Some(path) = b.project_path(cx) else {
 2183                                    return;
 2184                                };
 2185
 2186                                if !extra_buffers.is_empty() {
 2187                                    extra_buffers.push_str(", ");
 2188                                }
 2189                                extra_buffers.push_str(path.path.as_unix_str());
 2190                            });
 2191                        }
 2192                        zlog::warn!(
 2193                            logger =>
 2194                            "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2195                            &command.command,
 2196                            extra_buffers,
 2197                        );
 2198                        // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2199                        // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2200                        // add it so it's included, and merge it into the format transaction when its created later
 2201                    }
 2202                }
 2203            }
 2204        }
 2205
 2206        Ok(())
 2207    }
 2208
 2209    pub async fn format_ranges_via_lsp(
 2210        this: &WeakEntity<LspStore>,
 2211        buffer_handle: &Entity<Buffer>,
 2212        ranges: &[Range<Anchor>],
 2213        abs_path: &Path,
 2214        language_server: &Arc<LanguageServer>,
 2215        settings: &LanguageSettings,
 2216        cx: &mut AsyncApp,
 2217    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2218        let capabilities = &language_server.capabilities();
 2219        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2220        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2221            anyhow::bail!(
 2222                "{} language server does not support range formatting",
 2223                language_server.name()
 2224            );
 2225        }
 2226
 2227        let uri = file_path_to_lsp_url(abs_path)?;
 2228        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2229
 2230        let request_timeout = cx.update(|app| {
 2231            ProjectSettings::get_global(app)
 2232                .global_lsp_settings
 2233                .get_request_timeout()
 2234        });
 2235        let lsp_edits = {
 2236            let mut lsp_ranges = Vec::new();
 2237            this.update(cx, |_this, cx| {
 2238                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2239                // not have been sent to the language server. This seems like a fairly systemic
 2240                // issue, though, the resolution probably is not specific to formatting.
 2241                //
 2242                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2243                // LSP.
 2244                let snapshot = buffer_handle.read(cx).snapshot();
 2245                for range in ranges {
 2246                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2247                }
 2248                anyhow::Ok(())
 2249            })??;
 2250
 2251            let mut edits = None;
 2252            for range in lsp_ranges {
 2253                if let Some(mut edit) = language_server
 2254                    .request::<lsp::request::RangeFormatting>(
 2255                        lsp::DocumentRangeFormattingParams {
 2256                            text_document: text_document.clone(),
 2257                            range,
 2258                            options: lsp_command::lsp_formatting_options(settings),
 2259                            work_done_progress_params: Default::default(),
 2260                        },
 2261                        request_timeout,
 2262                    )
 2263                    .await
 2264                    .into_response()?
 2265                {
 2266                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2267                }
 2268            }
 2269            edits
 2270        };
 2271
 2272        if let Some(lsp_edits) = lsp_edits {
 2273            this.update(cx, |this, cx| {
 2274                this.as_local_mut().unwrap().edits_from_lsp(
 2275                    buffer_handle,
 2276                    lsp_edits,
 2277                    language_server.server_id(),
 2278                    None,
 2279                    cx,
 2280                )
 2281            })?
 2282            .await
 2283        } else {
 2284            Ok(Vec::with_capacity(0))
 2285        }
 2286    }
 2287
 2288    async fn format_via_lsp(
 2289        this: &WeakEntity<LspStore>,
 2290        buffer: &Entity<Buffer>,
 2291        abs_path: &Path,
 2292        language_server: &Arc<LanguageServer>,
 2293        settings: &LanguageSettings,
 2294        cx: &mut AsyncApp,
 2295    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2296        let logger = zlog::scoped!("lsp_format");
 2297        zlog::debug!(logger => "Formatting via LSP");
 2298
 2299        let uri = file_path_to_lsp_url(abs_path)?;
 2300        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2301        let capabilities = &language_server.capabilities();
 2302
 2303        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2304        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2305
 2306        let request_timeout = cx.update(|app| {
 2307            ProjectSettings::get_global(app)
 2308                .global_lsp_settings
 2309                .get_request_timeout()
 2310        });
 2311
 2312        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2313            let _timer = zlog::time!(logger => "format-full");
 2314            language_server
 2315                .request::<lsp::request::Formatting>(
 2316                    lsp::DocumentFormattingParams {
 2317                        text_document,
 2318                        options: lsp_command::lsp_formatting_options(settings),
 2319                        work_done_progress_params: Default::default(),
 2320                    },
 2321                    request_timeout,
 2322                )
 2323                .await
 2324                .into_response()?
 2325        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2326            let _timer = zlog::time!(logger => "format-range");
 2327            let buffer_start = lsp::Position::new(0, 0);
 2328            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2329            language_server
 2330                .request::<lsp::request::RangeFormatting>(
 2331                    lsp::DocumentRangeFormattingParams {
 2332                        text_document: text_document.clone(),
 2333                        range: lsp::Range::new(buffer_start, buffer_end),
 2334                        options: lsp_command::lsp_formatting_options(settings),
 2335                        work_done_progress_params: Default::default(),
 2336                    },
 2337                    request_timeout,
 2338                )
 2339                .await
 2340                .into_response()?
 2341        } else {
 2342            None
 2343        };
 2344
 2345        if let Some(lsp_edits) = lsp_edits {
 2346            this.update(cx, |this, cx| {
 2347                this.as_local_mut().unwrap().edits_from_lsp(
 2348                    buffer,
 2349                    lsp_edits,
 2350                    language_server.server_id(),
 2351                    None,
 2352                    cx,
 2353                )
 2354            })?
 2355            .await
 2356        } else {
 2357            Ok(Vec::with_capacity(0))
 2358        }
 2359    }
 2360
 2361    async fn format_via_external_command(
 2362        buffer: &FormattableBuffer,
 2363        command: &str,
 2364        arguments: Option<&[String]>,
 2365        cx: &mut AsyncApp,
 2366    ) -> Result<Option<Diff>> {
 2367        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2368            let file = File::from_dyn(buffer.file())?;
 2369            let worktree = file.worktree.read(cx);
 2370            let mut worktree_path = worktree.abs_path().to_path_buf();
 2371            if worktree.root_entry()?.is_file() {
 2372                worktree_path.pop();
 2373            }
 2374            Some(worktree_path)
 2375        });
 2376
 2377        use util::command::Stdio;
 2378        let mut child = util::command::new_command(command);
 2379
 2380        if let Some(buffer_env) = buffer.env.as_ref() {
 2381            child.envs(buffer_env);
 2382        }
 2383
 2384        if let Some(working_dir_path) = working_dir_path {
 2385            child.current_dir(working_dir_path);
 2386        }
 2387
 2388        if let Some(arguments) = arguments {
 2389            child.args(arguments.iter().map(|arg| {
 2390                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2391                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2392                } else {
 2393                    arg.replace("{buffer_path}", "Untitled")
 2394                }
 2395            }));
 2396        }
 2397
 2398        let mut child = child
 2399            .stdin(Stdio::piped())
 2400            .stdout(Stdio::piped())
 2401            .stderr(Stdio::piped())
 2402            .spawn()?;
 2403
 2404        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2405        let text = buffer
 2406            .handle
 2407            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2408        for chunk in text.chunks() {
 2409            stdin.write_all(chunk.as_bytes()).await?;
 2410        }
 2411        stdin.flush().await?;
 2412
 2413        let output = child.output().await?;
 2414        anyhow::ensure!(
 2415            output.status.success(),
 2416            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2417            output.status.code(),
 2418            String::from_utf8_lossy(&output.stdout),
 2419            String::from_utf8_lossy(&output.stderr),
 2420        );
 2421
 2422        let stdout = String::from_utf8(output.stdout)?;
 2423        Ok(Some(
 2424            buffer
 2425                .handle
 2426                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2427                .await,
 2428        ))
 2429    }
 2430
 2431    async fn try_resolve_code_action(
 2432        lang_server: &LanguageServer,
 2433        action: &mut CodeAction,
 2434        request_timeout: Duration,
 2435    ) -> anyhow::Result<()> {
 2436        match &mut action.lsp_action {
 2437            LspAction::Action(lsp_action) => {
 2438                if !action.resolved
 2439                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2440                    && lsp_action.data.is_some()
 2441                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2442                {
 2443                    **lsp_action = lang_server
 2444                        .request::<lsp::request::CodeActionResolveRequest>(
 2445                            *lsp_action.clone(),
 2446                            request_timeout,
 2447                        )
 2448                        .await
 2449                        .into_response()?;
 2450                }
 2451            }
 2452            LspAction::CodeLens(lens) => {
 2453                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2454                    *lens = lang_server
 2455                        .request::<lsp::request::CodeLensResolve>(lens.clone(), request_timeout)
 2456                        .await
 2457                        .into_response()?;
 2458                }
 2459            }
 2460            LspAction::Command(_) => {}
 2461        }
 2462
 2463        action.resolved = true;
 2464        anyhow::Ok(())
 2465    }
 2466
 2467    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2468        let buffer = buffer_handle.read(cx);
 2469
 2470        let file = buffer.file().cloned();
 2471
 2472        let Some(file) = File::from_dyn(file.as_ref()) else {
 2473            return;
 2474        };
 2475        if !file.is_local() {
 2476            return;
 2477        }
 2478        let path = ProjectPath::from_file(file, cx);
 2479        let worktree_id = file.worktree_id(cx);
 2480        let language = buffer.language().cloned();
 2481
 2482        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2483            for (server_id, diagnostics) in
 2484                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2485            {
 2486                self.update_buffer_diagnostics(
 2487                    buffer_handle,
 2488                    server_id,
 2489                    None,
 2490                    None,
 2491                    None,
 2492                    Vec::new(),
 2493                    diagnostics,
 2494                    cx,
 2495                )
 2496                .log_err();
 2497            }
 2498        }
 2499        let Some(language) = language else {
 2500            return;
 2501        };
 2502        let Some(snapshot) = self
 2503            .worktree_store
 2504            .read(cx)
 2505            .worktree_for_id(worktree_id, cx)
 2506            .map(|worktree| worktree.read(cx).snapshot())
 2507        else {
 2508            return;
 2509        };
 2510        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2511
 2512        for server_id in
 2513            self.lsp_tree
 2514                .get(path, language.name(), language.manifest(), &delegate, cx)
 2515        {
 2516            let server = self
 2517                .language_servers
 2518                .get(&server_id)
 2519                .and_then(|server_state| {
 2520                    if let LanguageServerState::Running { server, .. } = server_state {
 2521                        Some(server.clone())
 2522                    } else {
 2523                        None
 2524                    }
 2525                });
 2526            let server = match server {
 2527                Some(server) => server,
 2528                None => continue,
 2529            };
 2530
 2531            buffer_handle.update(cx, |buffer, cx| {
 2532                buffer.set_completion_triggers(
 2533                    server.server_id(),
 2534                    server
 2535                        .capabilities()
 2536                        .completion_provider
 2537                        .as_ref()
 2538                        .and_then(|provider| {
 2539                            provider
 2540                                .trigger_characters
 2541                                .as_ref()
 2542                                .map(|characters| characters.iter().cloned().collect())
 2543                        })
 2544                        .unwrap_or_default(),
 2545                    cx,
 2546                );
 2547            });
 2548        }
 2549    }
 2550
 2551    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2552        buffer.update(cx, |buffer, cx| {
 2553            let Some(language) = buffer.language() else {
 2554                return;
 2555            };
 2556            let path = ProjectPath {
 2557                worktree_id: old_file.worktree_id(cx),
 2558                path: old_file.path.clone(),
 2559            };
 2560            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2561                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2562                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2563            }
 2564        });
 2565    }
 2566
 2567    fn update_buffer_diagnostics(
 2568        &mut self,
 2569        buffer: &Entity<Buffer>,
 2570        server_id: LanguageServerId,
 2571        registration_id: Option<Option<SharedString>>,
 2572        result_id: Option<SharedString>,
 2573        version: Option<i32>,
 2574        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2575        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2576        cx: &mut Context<LspStore>,
 2577    ) -> Result<()> {
 2578        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2579            Ordering::Equal
 2580                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2581                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2582                .then_with(|| a.severity.cmp(&b.severity))
 2583                .then_with(|| a.message.cmp(&b.message))
 2584        }
 2585
 2586        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2587        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2588        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2589
 2590        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2591            Ordering::Equal
 2592                .then_with(|| a.range.start.cmp(&b.range.start))
 2593                .then_with(|| b.range.end.cmp(&a.range.end))
 2594                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2595        });
 2596
 2597        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2598
 2599        let edits_since_save = std::cell::LazyCell::new(|| {
 2600            let saved_version = buffer.read(cx).saved_version();
 2601            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2602        });
 2603
 2604        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2605
 2606        for (new_diagnostic, entry) in diagnostics {
 2607            let start;
 2608            let end;
 2609            if new_diagnostic && entry.diagnostic.is_disk_based {
 2610                // Some diagnostics are based on files on disk instead of buffers'
 2611                // current contents. Adjust these diagnostics' ranges to reflect
 2612                // any unsaved edits.
 2613                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2614                // and were properly adjusted on reuse.
 2615                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2616                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2617            } else {
 2618                start = entry.range.start;
 2619                end = entry.range.end;
 2620            }
 2621
 2622            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2623                ..snapshot.clip_point_utf16(end, Bias::Right);
 2624
 2625            // Expand empty ranges by one codepoint
 2626            if range.start == range.end {
 2627                // This will be go to the next boundary when being clipped
 2628                range.end.column += 1;
 2629                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2630                if range.start == range.end && range.end.column > 0 {
 2631                    range.start.column -= 1;
 2632                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2633                }
 2634            }
 2635
 2636            sanitized_diagnostics.push(DiagnosticEntry {
 2637                range,
 2638                diagnostic: entry.diagnostic,
 2639            });
 2640        }
 2641        drop(edits_since_save);
 2642
 2643        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2644        buffer.update(cx, |buffer, cx| {
 2645            if let Some(registration_id) = registration_id {
 2646                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2647                    self.buffer_pull_diagnostics_result_ids
 2648                        .entry(server_id)
 2649                        .or_default()
 2650                        .entry(registration_id)
 2651                        .or_default()
 2652                        .insert(abs_path, result_id);
 2653                }
 2654            }
 2655
 2656            buffer.update_diagnostics(server_id, set, cx)
 2657        });
 2658
 2659        Ok(())
 2660    }
 2661
 2662    fn register_language_server_for_invisible_worktree(
 2663        &mut self,
 2664        worktree: &Entity<Worktree>,
 2665        language_server_id: LanguageServerId,
 2666        cx: &mut App,
 2667    ) {
 2668        let worktree = worktree.read(cx);
 2669        let worktree_id = worktree.id();
 2670        debug_assert!(!worktree.is_visible());
 2671        let Some(mut origin_seed) = self
 2672            .language_server_ids
 2673            .iter()
 2674            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2675        else {
 2676            return;
 2677        };
 2678        origin_seed.worktree_id = worktree_id;
 2679        self.language_server_ids
 2680            .entry(origin_seed)
 2681            .or_insert_with(|| UnifiedLanguageServer {
 2682                id: language_server_id,
 2683                project_roots: Default::default(),
 2684            });
 2685    }
 2686
 2687    fn register_buffer_with_language_servers(
 2688        &mut self,
 2689        buffer_handle: &Entity<Buffer>,
 2690        only_register_servers: HashSet<LanguageServerSelector>,
 2691        cx: &mut Context<LspStore>,
 2692    ) {
 2693        let buffer = buffer_handle.read(cx);
 2694        let buffer_id = buffer.remote_id();
 2695
 2696        let Some(file) = File::from_dyn(buffer.file()) else {
 2697            return;
 2698        };
 2699        if !file.is_local() {
 2700            return;
 2701        }
 2702
 2703        let abs_path = file.abs_path(cx);
 2704        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2705            return;
 2706        };
 2707        let initial_snapshot = buffer.text_snapshot();
 2708        let worktree_id = file.worktree_id(cx);
 2709
 2710        let Some(language) = buffer.language().cloned() else {
 2711            return;
 2712        };
 2713        let path: Arc<RelPath> = file
 2714            .path()
 2715            .parent()
 2716            .map(Arc::from)
 2717            .unwrap_or_else(|| file.path().clone());
 2718        let Some(worktree) = self
 2719            .worktree_store
 2720            .read(cx)
 2721            .worktree_for_id(worktree_id, cx)
 2722        else {
 2723            return;
 2724        };
 2725        let language_name = language.name();
 2726        let (reused, delegate, servers) = self
 2727            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2728            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2729            .unwrap_or_else(|| {
 2730                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2731                let delegate: Arc<dyn ManifestDelegate> =
 2732                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2733
 2734                let servers = self
 2735                    .lsp_tree
 2736                    .walk(
 2737                        ProjectPath { worktree_id, path },
 2738                        language.name(),
 2739                        language.manifest(),
 2740                        &delegate,
 2741                        cx,
 2742                    )
 2743                    .collect::<Vec<_>>();
 2744                (false, lsp_delegate, servers)
 2745            });
 2746        let servers_and_adapters = servers
 2747            .into_iter()
 2748            .filter_map(|server_node| {
 2749                if reused && server_node.server_id().is_none() {
 2750                    return None;
 2751                }
 2752                if !only_register_servers.is_empty() {
 2753                    if let Some(server_id) = server_node.server_id()
 2754                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2755                    {
 2756                        return None;
 2757                    }
 2758                    if let Some(name) = server_node.name()
 2759                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2760                    {
 2761                        return None;
 2762                    }
 2763                }
 2764
 2765                let server_id = server_node.server_id_or_init(|disposition| {
 2766                    let path = &disposition.path;
 2767
 2768                    {
 2769                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2770
 2771                        let server_id = self.get_or_insert_language_server(
 2772                            &worktree,
 2773                            delegate.clone(),
 2774                            disposition,
 2775                            &language_name,
 2776                            cx,
 2777                        );
 2778
 2779                        if let Some(state) = self.language_servers.get(&server_id)
 2780                            && let Ok(uri) = uri
 2781                        {
 2782                            state.add_workspace_folder(uri);
 2783                        };
 2784                        server_id
 2785                    }
 2786                })?;
 2787                let server_state = self.language_servers.get(&server_id)?;
 2788                if let LanguageServerState::Running {
 2789                    server, adapter, ..
 2790                } = server_state
 2791                {
 2792                    Some((server.clone(), adapter.clone()))
 2793                } else {
 2794                    None
 2795                }
 2796            })
 2797            .collect::<Vec<_>>();
 2798        for (server, adapter) in servers_and_adapters {
 2799            buffer_handle.update(cx, |buffer, cx| {
 2800                buffer.set_completion_triggers(
 2801                    server.server_id(),
 2802                    server
 2803                        .capabilities()
 2804                        .completion_provider
 2805                        .as_ref()
 2806                        .and_then(|provider| {
 2807                            provider
 2808                                .trigger_characters
 2809                                .as_ref()
 2810                                .map(|characters| characters.iter().cloned().collect())
 2811                        })
 2812                        .unwrap_or_default(),
 2813                    cx,
 2814                );
 2815            });
 2816
 2817            let snapshot = LspBufferSnapshot {
 2818                version: 0,
 2819                snapshot: initial_snapshot.clone(),
 2820            };
 2821
 2822            let mut registered = false;
 2823            self.buffer_snapshots
 2824                .entry(buffer_id)
 2825                .or_default()
 2826                .entry(server.server_id())
 2827                .or_insert_with(|| {
 2828                    registered = true;
 2829                    server.register_buffer(
 2830                        uri.clone(),
 2831                        adapter.language_id(&language.name()),
 2832                        0,
 2833                        initial_snapshot.text(),
 2834                    );
 2835
 2836                    vec![snapshot]
 2837                });
 2838
 2839            self.buffers_opened_in_servers
 2840                .entry(buffer_id)
 2841                .or_default()
 2842                .insert(server.server_id());
 2843            if registered {
 2844                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2845                    language_server_id: server.server_id(),
 2846                    name: None,
 2847                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2848                        proto::RegisteredForBuffer {
 2849                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2850                            buffer_id: buffer_id.to_proto(),
 2851                        },
 2852                    ),
 2853                });
 2854            }
 2855        }
 2856    }
 2857
 2858    fn reuse_existing_language_server<'lang_name>(
 2859        &self,
 2860        server_tree: &LanguageServerTree,
 2861        worktree: &Entity<Worktree>,
 2862        language_name: &'lang_name LanguageName,
 2863        cx: &mut App,
 2864    ) -> Option<(
 2865        Arc<LocalLspAdapterDelegate>,
 2866        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2867    )> {
 2868        if worktree.read(cx).is_visible() {
 2869            return None;
 2870        }
 2871
 2872        let worktree_store = self.worktree_store.read(cx);
 2873        let servers = server_tree
 2874            .instances
 2875            .iter()
 2876            .filter(|(worktree_id, _)| {
 2877                worktree_store
 2878                    .worktree_for_id(**worktree_id, cx)
 2879                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2880            })
 2881            .flat_map(|(worktree_id, servers)| {
 2882                servers
 2883                    .roots
 2884                    .iter()
 2885                    .flat_map(|(_, language_servers)| language_servers)
 2886                    .map(move |(_, (server_node, server_languages))| {
 2887                        (worktree_id, server_node, server_languages)
 2888                    })
 2889                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2890                    .map(|(worktree_id, server_node, _)| {
 2891                        (
 2892                            *worktree_id,
 2893                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2894                        )
 2895                    })
 2896            })
 2897            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2898                acc.entry(worktree_id)
 2899                    .or_insert_with(Vec::new)
 2900                    .push(server_node);
 2901                acc
 2902            })
 2903            .into_values()
 2904            .max_by_key(|servers| servers.len())?;
 2905
 2906        let worktree_id = worktree.read(cx).id();
 2907        let apply = move |tree: &mut LanguageServerTree| {
 2908            for server_node in &servers {
 2909                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2910            }
 2911            servers
 2912        };
 2913
 2914        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2915        Some((delegate, apply))
 2916    }
 2917
 2918    pub(crate) fn unregister_old_buffer_from_language_servers(
 2919        &mut self,
 2920        buffer: &Entity<Buffer>,
 2921        old_file: &File,
 2922        cx: &mut App,
 2923    ) {
 2924        let old_path = match old_file.as_local() {
 2925            Some(local) => local.abs_path(cx),
 2926            None => return,
 2927        };
 2928
 2929        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2930            debug_panic!("{old_path:?} is not parseable as an URI");
 2931            return;
 2932        };
 2933        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2934    }
 2935
 2936    pub(crate) fn unregister_buffer_from_language_servers(
 2937        &mut self,
 2938        buffer: &Entity<Buffer>,
 2939        file_url: &lsp::Uri,
 2940        cx: &mut App,
 2941    ) {
 2942        buffer.update(cx, |buffer, cx| {
 2943            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2944
 2945            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2946                if snapshots
 2947                    .as_mut()
 2948                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2949                {
 2950                    language_server.unregister_buffer(file_url.clone());
 2951                }
 2952            }
 2953        });
 2954    }
 2955
 2956    fn buffer_snapshot_for_lsp_version(
 2957        &mut self,
 2958        buffer: &Entity<Buffer>,
 2959        server_id: LanguageServerId,
 2960        version: Option<i32>,
 2961        cx: &App,
 2962    ) -> Result<TextBufferSnapshot> {
 2963        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2964
 2965        if let Some(version) = version {
 2966            let buffer_id = buffer.read(cx).remote_id();
 2967            let snapshots = if let Some(snapshots) = self
 2968                .buffer_snapshots
 2969                .get_mut(&buffer_id)
 2970                .and_then(|m| m.get_mut(&server_id))
 2971            {
 2972                snapshots
 2973            } else if version == 0 {
 2974                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2975                // We detect this case and treat it as if the version was `None`.
 2976                return Ok(buffer.read(cx).text_snapshot());
 2977            } else {
 2978                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2979            };
 2980
 2981            let found_snapshot = snapshots
 2982                    .binary_search_by_key(&version, |e| e.version)
 2983                    .map(|ix| snapshots[ix].snapshot.clone())
 2984                    .map_err(|_| {
 2985                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2986                    })?;
 2987
 2988            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2989            Ok(found_snapshot)
 2990        } else {
 2991            Ok((buffer.read(cx)).text_snapshot())
 2992        }
 2993    }
 2994
 2995    async fn get_server_code_actions_from_action_kinds(
 2996        lsp_store: &WeakEntity<LspStore>,
 2997        language_server_id: LanguageServerId,
 2998        code_action_kinds: Vec<lsp::CodeActionKind>,
 2999        buffer: &Entity<Buffer>,
 3000        cx: &mut AsyncApp,
 3001    ) -> Result<Vec<CodeAction>> {
 3002        let actions = lsp_store
 3003            .update(cx, move |this, cx| {
 3004                let request = GetCodeActions {
 3005                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 3006                    kinds: Some(code_action_kinds),
 3007                };
 3008                let server = LanguageServerToQuery::Other(language_server_id);
 3009                this.request_lsp(buffer.clone(), server, request, cx)
 3010            })?
 3011            .await?;
 3012        Ok(actions)
 3013    }
 3014
 3015    pub async fn execute_code_actions_on_server(
 3016        lsp_store: &WeakEntity<LspStore>,
 3017        language_server: &Arc<LanguageServer>,
 3018        actions: Vec<CodeAction>,
 3019        push_to_history: bool,
 3020        project_transaction: &mut ProjectTransaction,
 3021        cx: &mut AsyncApp,
 3022    ) -> anyhow::Result<()> {
 3023        let request_timeout = cx.update(|app| {
 3024            ProjectSettings::get_global(app)
 3025                .global_lsp_settings
 3026                .get_request_timeout()
 3027        });
 3028
 3029        for mut action in actions {
 3030            Self::try_resolve_code_action(language_server, &mut action, request_timeout)
 3031                .await
 3032                .context("resolving a formatting code action")?;
 3033
 3034            if let Some(edit) = action.lsp_action.edit() {
 3035                if edit.changes.is_none() && edit.document_changes.is_none() {
 3036                    continue;
 3037                }
 3038
 3039                let new = Self::deserialize_workspace_edit(
 3040                    lsp_store.upgrade().context("project dropped")?,
 3041                    edit.clone(),
 3042                    push_to_history,
 3043                    language_server.clone(),
 3044                    cx,
 3045                )
 3046                .await?;
 3047                project_transaction.0.extend(new.0);
 3048            }
 3049
 3050            let Some(command) = action.lsp_action.command() else {
 3051                continue;
 3052            };
 3053
 3054            let server_capabilities = language_server.capabilities();
 3055            let available_commands = server_capabilities
 3056                .execute_command_provider
 3057                .as_ref()
 3058                .map(|options| options.commands.as_slice())
 3059                .unwrap_or_default();
 3060            if !available_commands.contains(&command.command) {
 3061                log::warn!(
 3062                    "Cannot execute a command {} not listed in the language server capabilities",
 3063                    command.command
 3064                );
 3065                continue;
 3066            }
 3067
 3068            lsp_store.update(cx, |lsp_store, _| {
 3069                if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 3070                    mode.last_workspace_edits_by_language_server
 3071                        .remove(&language_server.server_id());
 3072                }
 3073            })?;
 3074
 3075            language_server
 3076                .request::<lsp::request::ExecuteCommand>(
 3077                    lsp::ExecuteCommandParams {
 3078                        command: command.command.clone(),
 3079                        arguments: command.arguments.clone().unwrap_or_default(),
 3080                        ..Default::default()
 3081                    },
 3082                    request_timeout,
 3083                )
 3084                .await
 3085                .into_response()
 3086                .context("execute command")?;
 3087
 3088            lsp_store.update(cx, |this, _| {
 3089                if let LspStoreMode::Local(mode) = &mut this.mode {
 3090                    project_transaction.0.extend(
 3091                        mode.last_workspace_edits_by_language_server
 3092                            .remove(&language_server.server_id())
 3093                            .unwrap_or_default()
 3094                            .0,
 3095                    )
 3096                }
 3097            })?;
 3098        }
 3099        Ok(())
 3100    }
 3101
 3102    pub async fn deserialize_text_edits(
 3103        this: Entity<LspStore>,
 3104        buffer_to_edit: Entity<Buffer>,
 3105        edits: Vec<lsp::TextEdit>,
 3106        push_to_history: bool,
 3107        _: Arc<CachedLspAdapter>,
 3108        language_server: Arc<LanguageServer>,
 3109        cx: &mut AsyncApp,
 3110    ) -> Result<Option<Transaction>> {
 3111        let edits = this
 3112            .update(cx, |this, cx| {
 3113                this.as_local_mut().unwrap().edits_from_lsp(
 3114                    &buffer_to_edit,
 3115                    edits,
 3116                    language_server.server_id(),
 3117                    None,
 3118                    cx,
 3119                )
 3120            })
 3121            .await?;
 3122
 3123        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3124            buffer.finalize_last_transaction();
 3125            buffer.start_transaction();
 3126            for (range, text) in edits {
 3127                buffer.edit([(range, text)], None, cx);
 3128            }
 3129
 3130            if buffer.end_transaction(cx).is_some() {
 3131                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3132                if !push_to_history {
 3133                    buffer.forget_transaction(transaction.id);
 3134                }
 3135                Some(transaction)
 3136            } else {
 3137                None
 3138            }
 3139        });
 3140
 3141        Ok(transaction)
 3142    }
 3143
 3144    #[allow(clippy::type_complexity)]
 3145    pub fn edits_from_lsp(
 3146        &mut self,
 3147        buffer: &Entity<Buffer>,
 3148        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3149        server_id: LanguageServerId,
 3150        version: Option<i32>,
 3151        cx: &mut Context<LspStore>,
 3152    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3153        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3154        cx.background_spawn(async move {
 3155            let snapshot = snapshot?;
 3156            let mut lsp_edits = lsp_edits
 3157                .into_iter()
 3158                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3159                .collect::<Vec<_>>();
 3160
 3161            lsp_edits.sort_unstable_by_key(|(range, _)| (range.start, range.end));
 3162
 3163            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3164            let mut edits = Vec::new();
 3165            while let Some((range, mut new_text)) = lsp_edits.next() {
 3166                // Clip invalid ranges provided by the language server.
 3167                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3168                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3169
 3170                // Combine any LSP edits that are adjacent.
 3171                //
 3172                // Also, combine LSP edits that are separated from each other by only
 3173                // a newline. This is important because for some code actions,
 3174                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3175                // are separated by unchanged newline characters.
 3176                //
 3177                // In order for the diffing logic below to work properly, any edits that
 3178                // cancel each other out must be combined into one.
 3179                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3180                    if next_range.start.0 > range.end {
 3181                        if next_range.start.0.row > range.end.row + 1
 3182                            || next_range.start.0.column > 0
 3183                            || snapshot.clip_point_utf16(
 3184                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3185                                Bias::Left,
 3186                            ) > range.end
 3187                        {
 3188                            break;
 3189                        }
 3190                        new_text.push('\n');
 3191                    }
 3192                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3193                    new_text.push_str(next_text);
 3194                    lsp_edits.next();
 3195                }
 3196
 3197                // For multiline edits, perform a diff of the old and new text so that
 3198                // we can identify the changes more precisely, preserving the locations
 3199                // of any anchors positioned in the unchanged regions.
 3200                if range.end.row > range.start.row {
 3201                    let offset = range.start.to_offset(&snapshot);
 3202                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3203                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3204                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3205                        (
 3206                            snapshot.anchor_after(offset + range.start)
 3207                                ..snapshot.anchor_before(offset + range.end),
 3208                            replacement,
 3209                        )
 3210                    }));
 3211                } else if range.end == range.start {
 3212                    let anchor = snapshot.anchor_after(range.start);
 3213                    edits.push((anchor..anchor, new_text.into()));
 3214                } else {
 3215                    let edit_start = snapshot.anchor_after(range.start);
 3216                    let edit_end = snapshot.anchor_before(range.end);
 3217                    edits.push((edit_start..edit_end, new_text.into()));
 3218                }
 3219            }
 3220
 3221            Ok(edits)
 3222        })
 3223    }
 3224
 3225    pub(crate) async fn deserialize_workspace_edit(
 3226        this: Entity<LspStore>,
 3227        edit: lsp::WorkspaceEdit,
 3228        push_to_history: bool,
 3229        language_server: Arc<LanguageServer>,
 3230        cx: &mut AsyncApp,
 3231    ) -> Result<ProjectTransaction> {
 3232        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3233
 3234        let mut operations = Vec::new();
 3235        if let Some(document_changes) = edit.document_changes {
 3236            match document_changes {
 3237                lsp::DocumentChanges::Edits(edits) => {
 3238                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3239                }
 3240                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3241            }
 3242        } else if let Some(changes) = edit.changes {
 3243            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3244                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3245                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3246                        uri,
 3247                        version: None,
 3248                    },
 3249                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3250                })
 3251            }));
 3252        }
 3253
 3254        let mut project_transaction = ProjectTransaction::default();
 3255        for operation in operations {
 3256            match operation {
 3257                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3258                    let abs_path = op
 3259                        .uri
 3260                        .to_file_path()
 3261                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3262
 3263                    if let Some(parent_path) = abs_path.parent() {
 3264                        fs.create_dir(parent_path).await?;
 3265                    }
 3266                    if abs_path.ends_with("/") {
 3267                        fs.create_dir(&abs_path).await?;
 3268                    } else {
 3269                        fs.create_file(
 3270                            &abs_path,
 3271                            op.options
 3272                                .map(|options| fs::CreateOptions {
 3273                                    overwrite: options.overwrite.unwrap_or(false),
 3274                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3275                                })
 3276                                .unwrap_or_default(),
 3277                        )
 3278                        .await?;
 3279                    }
 3280                }
 3281
 3282                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3283                    let source_abs_path = op
 3284                        .old_uri
 3285                        .to_file_path()
 3286                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3287                    let target_abs_path = op
 3288                        .new_uri
 3289                        .to_file_path()
 3290                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3291
 3292                    let options = fs::RenameOptions {
 3293                        overwrite: op
 3294                            .options
 3295                            .as_ref()
 3296                            .and_then(|options| options.overwrite)
 3297                            .unwrap_or(false),
 3298                        ignore_if_exists: op
 3299                            .options
 3300                            .as_ref()
 3301                            .and_then(|options| options.ignore_if_exists)
 3302                            .unwrap_or(false),
 3303                        create_parents: true,
 3304                    };
 3305
 3306                    fs.rename(&source_abs_path, &target_abs_path, options)
 3307                        .await?;
 3308                }
 3309
 3310                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3311                    let abs_path = op
 3312                        .uri
 3313                        .to_file_path()
 3314                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3315                    let options = op
 3316                        .options
 3317                        .map(|options| fs::RemoveOptions {
 3318                            recursive: options.recursive.unwrap_or(false),
 3319                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3320                        })
 3321                        .unwrap_or_default();
 3322                    if abs_path.ends_with("/") {
 3323                        fs.remove_dir(&abs_path, options).await?;
 3324                    } else {
 3325                        fs.remove_file(&abs_path, options).await?;
 3326                    }
 3327                }
 3328
 3329                lsp::DocumentChangeOperation::Edit(op) => {
 3330                    let buffer_to_edit = this
 3331                        .update(cx, |this, cx| {
 3332                            this.open_local_buffer_via_lsp(
 3333                                op.text_document.uri.clone(),
 3334                                language_server.server_id(),
 3335                                cx,
 3336                            )
 3337                        })
 3338                        .await?;
 3339
 3340                    let edits = this
 3341                        .update(cx, |this, cx| {
 3342                            let path = buffer_to_edit.read(cx).project_path(cx);
 3343                            let active_entry = this.active_entry;
 3344                            let is_active_entry = path.is_some_and(|project_path| {
 3345                                this.worktree_store
 3346                                    .read(cx)
 3347                                    .entry_for_path(&project_path, cx)
 3348                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3349                            });
 3350                            let local = this.as_local_mut().unwrap();
 3351
 3352                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3353                            for edit in op.edits {
 3354                                match edit {
 3355                                    Edit::Plain(edit) => {
 3356                                        if !edits.contains(&edit) {
 3357                                            edits.push(edit)
 3358                                        }
 3359                                    }
 3360                                    Edit::Annotated(edit) => {
 3361                                        if !edits.contains(&edit.text_edit) {
 3362                                            edits.push(edit.text_edit)
 3363                                        }
 3364                                    }
 3365                                    Edit::Snippet(edit) => {
 3366                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3367                                        else {
 3368                                            continue;
 3369                                        };
 3370
 3371                                        if is_active_entry {
 3372                                            snippet_edits.push((edit.range, snippet));
 3373                                        } else {
 3374                                            // Since this buffer is not focused, apply a normal edit.
 3375                                            let new_edit = TextEdit {
 3376                                                range: edit.range,
 3377                                                new_text: snippet.text,
 3378                                            };
 3379                                            if !edits.contains(&new_edit) {
 3380                                                edits.push(new_edit);
 3381                                            }
 3382                                        }
 3383                                    }
 3384                                }
 3385                            }
 3386                            if !snippet_edits.is_empty() {
 3387                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3388                                let version = if let Some(buffer_version) = op.text_document.version
 3389                                {
 3390                                    local
 3391                                        .buffer_snapshot_for_lsp_version(
 3392                                            &buffer_to_edit,
 3393                                            language_server.server_id(),
 3394                                            Some(buffer_version),
 3395                                            cx,
 3396                                        )
 3397                                        .ok()
 3398                                        .map(|snapshot| snapshot.version)
 3399                                } else {
 3400                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3401                                };
 3402
 3403                                let most_recent_edit =
 3404                                    version.and_then(|version| version.most_recent());
 3405                                // Check if the edit that triggered that edit has been made by this participant.
 3406
 3407                                if let Some(most_recent_edit) = most_recent_edit {
 3408                                    cx.emit(LspStoreEvent::SnippetEdit {
 3409                                        buffer_id,
 3410                                        edits: snippet_edits,
 3411                                        most_recent_edit,
 3412                                    });
 3413                                }
 3414                            }
 3415
 3416                            local.edits_from_lsp(
 3417                                &buffer_to_edit,
 3418                                edits,
 3419                                language_server.server_id(),
 3420                                op.text_document.version,
 3421                                cx,
 3422                            )
 3423                        })
 3424                        .await?;
 3425
 3426                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3427                        buffer.finalize_last_transaction();
 3428                        buffer.start_transaction();
 3429                        for (range, text) in edits {
 3430                            buffer.edit([(range, text)], None, cx);
 3431                        }
 3432
 3433                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3434                            if push_to_history {
 3435                                buffer.finalize_last_transaction();
 3436                                buffer.get_transaction(transaction_id).cloned()
 3437                            } else {
 3438                                buffer.forget_transaction(transaction_id)
 3439                            }
 3440                        })
 3441                    });
 3442                    if let Some(transaction) = transaction {
 3443                        project_transaction.0.insert(buffer_to_edit, transaction);
 3444                    }
 3445                }
 3446            }
 3447        }
 3448
 3449        Ok(project_transaction)
 3450    }
 3451
 3452    async fn on_lsp_workspace_edit(
 3453        this: WeakEntity<LspStore>,
 3454        params: lsp::ApplyWorkspaceEditParams,
 3455        server_id: LanguageServerId,
 3456        cx: &mut AsyncApp,
 3457    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3458        let this = this.upgrade().context("project project closed")?;
 3459        let language_server = this
 3460            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3461            .context("language server not found")?;
 3462        let transaction = Self::deserialize_workspace_edit(
 3463            this.clone(),
 3464            params.edit,
 3465            true,
 3466            language_server.clone(),
 3467            cx,
 3468        )
 3469        .await
 3470        .log_err();
 3471        this.update(cx, |this, cx| {
 3472            if let Some(transaction) = transaction {
 3473                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3474
 3475                this.as_local_mut()
 3476                    .unwrap()
 3477                    .last_workspace_edits_by_language_server
 3478                    .insert(server_id, transaction);
 3479            }
 3480        });
 3481        Ok(lsp::ApplyWorkspaceEditResponse {
 3482            applied: true,
 3483            failed_change: None,
 3484            failure_reason: None,
 3485        })
 3486    }
 3487
 3488    fn remove_worktree(
 3489        &mut self,
 3490        id_to_remove: WorktreeId,
 3491        cx: &mut Context<LspStore>,
 3492    ) -> Vec<LanguageServerId> {
 3493        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3494        self.diagnostics.remove(&id_to_remove);
 3495        self.prettier_store.update(cx, |prettier_store, cx| {
 3496            prettier_store.remove_worktree(id_to_remove, cx);
 3497        });
 3498
 3499        let mut servers_to_remove = BTreeSet::default();
 3500        let mut servers_to_preserve = HashSet::default();
 3501        for (seed, state) in &self.language_server_ids {
 3502            if seed.worktree_id == id_to_remove {
 3503                servers_to_remove.insert(state.id);
 3504            } else {
 3505                servers_to_preserve.insert(state.id);
 3506            }
 3507        }
 3508        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3509        self.language_server_ids
 3510            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3511        for server_id_to_remove in &servers_to_remove {
 3512            self.language_server_watched_paths
 3513                .remove(server_id_to_remove);
 3514            self.language_server_paths_watched_for_rename
 3515                .remove(server_id_to_remove);
 3516            self.last_workspace_edits_by_language_server
 3517                .remove(server_id_to_remove);
 3518            self.language_servers.remove(server_id_to_remove);
 3519            self.buffer_pull_diagnostics_result_ids
 3520                .remove(server_id_to_remove);
 3521            self.workspace_pull_diagnostics_result_ids
 3522                .remove(server_id_to_remove);
 3523            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3524                buffer_servers.remove(server_id_to_remove);
 3525            }
 3526            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3527        }
 3528        servers_to_remove.into_iter().collect()
 3529    }
 3530
 3531    fn rebuild_watched_paths_inner<'a>(
 3532        &'a self,
 3533        language_server_id: LanguageServerId,
 3534        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3535        cx: &mut Context<LspStore>,
 3536    ) -> LanguageServerWatchedPathsBuilder {
 3537        let worktrees = self
 3538            .worktree_store
 3539            .read(cx)
 3540            .worktrees()
 3541            .filter_map(|worktree| {
 3542                self.language_servers_for_worktree(worktree.read(cx).id())
 3543                    .find(|server| server.server_id() == language_server_id)
 3544                    .map(|_| worktree)
 3545            })
 3546            .collect::<Vec<_>>();
 3547
 3548        let mut worktree_globs = HashMap::default();
 3549        let mut abs_globs = HashMap::default();
 3550        log::trace!(
 3551            "Processing new watcher paths for language server with id {}",
 3552            language_server_id
 3553        );
 3554
 3555        for watcher in watchers {
 3556            if let Some((worktree, literal_prefix, pattern)) =
 3557                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3558            {
 3559                worktree.update(cx, |worktree, _| {
 3560                    if let Some((tree, glob)) =
 3561                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3562                    {
 3563                        tree.add_path_prefix_to_scan(literal_prefix);
 3564                        worktree_globs
 3565                            .entry(tree.id())
 3566                            .or_insert_with(GlobSetBuilder::new)
 3567                            .add(glob);
 3568                    }
 3569                });
 3570            } else {
 3571                let (path, pattern) = match &watcher.glob_pattern {
 3572                    lsp::GlobPattern::String(s) => {
 3573                        let watcher_path = SanitizedPath::new(s);
 3574                        let path = glob_literal_prefix(watcher_path.as_path());
 3575                        let pattern = watcher_path
 3576                            .as_path()
 3577                            .strip_prefix(&path)
 3578                            .map(|p| p.to_string_lossy().into_owned())
 3579                            .unwrap_or_else(|e| {
 3580                                debug_panic!(
 3581                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3582                                    s,
 3583                                    path.display(),
 3584                                    e
 3585                                );
 3586                                watcher_path.as_path().to_string_lossy().into_owned()
 3587                            });
 3588                        (path, pattern)
 3589                    }
 3590                    lsp::GlobPattern::Relative(rp) => {
 3591                        let Ok(mut base_uri) = match &rp.base_uri {
 3592                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3593                            lsp::OneOf::Right(base_uri) => base_uri,
 3594                        }
 3595                        .to_file_path() else {
 3596                            continue;
 3597                        };
 3598
 3599                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3600                        let pattern = Path::new(&rp.pattern)
 3601                            .strip_prefix(&path)
 3602                            .map(|p| p.to_string_lossy().into_owned())
 3603                            .unwrap_or_else(|e| {
 3604                                debug_panic!(
 3605                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3606                                    rp.pattern,
 3607                                    path.display(),
 3608                                    e
 3609                                );
 3610                                rp.pattern.clone()
 3611                            });
 3612                        base_uri.push(path);
 3613                        (base_uri, pattern)
 3614                    }
 3615                };
 3616
 3617                if let Some(glob) = Glob::new(&pattern).log_err() {
 3618                    if !path
 3619                        .components()
 3620                        .any(|c| matches!(c, path::Component::Normal(_)))
 3621                    {
 3622                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3623                        // rather than adding a new watcher for `/`.
 3624                        for worktree in &worktrees {
 3625                            worktree_globs
 3626                                .entry(worktree.read(cx).id())
 3627                                .or_insert_with(GlobSetBuilder::new)
 3628                                .add(glob.clone());
 3629                        }
 3630                    } else {
 3631                        abs_globs
 3632                            .entry(path.into())
 3633                            .or_insert_with(GlobSetBuilder::new)
 3634                            .add(glob);
 3635                    }
 3636                }
 3637            }
 3638        }
 3639
 3640        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3641        for (worktree_id, builder) in worktree_globs {
 3642            if let Ok(globset) = builder.build() {
 3643                watch_builder.watch_worktree(worktree_id, globset);
 3644            }
 3645        }
 3646        for (abs_path, builder) in abs_globs {
 3647            if let Ok(globset) = builder.build() {
 3648                watch_builder.watch_abs_path(abs_path, globset);
 3649            }
 3650        }
 3651        watch_builder
 3652    }
 3653
 3654    fn worktree_and_path_for_file_watcher(
 3655        worktrees: &[Entity<Worktree>],
 3656        watcher: &FileSystemWatcher,
 3657        cx: &App,
 3658    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3659        worktrees.iter().find_map(|worktree| {
 3660            let tree = worktree.read(cx);
 3661            let worktree_root_path = tree.abs_path();
 3662            let path_style = tree.path_style();
 3663            match &watcher.glob_pattern {
 3664                lsp::GlobPattern::String(s) => {
 3665                    let watcher_path = SanitizedPath::new(s);
 3666                    let relative = watcher_path
 3667                        .as_path()
 3668                        .strip_prefix(&worktree_root_path)
 3669                        .ok()?;
 3670                    let literal_prefix = glob_literal_prefix(relative);
 3671                    Some((
 3672                        worktree.clone(),
 3673                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3674                        relative.to_string_lossy().into_owned(),
 3675                    ))
 3676                }
 3677                lsp::GlobPattern::Relative(rp) => {
 3678                    let base_uri = match &rp.base_uri {
 3679                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3680                        lsp::OneOf::Right(base_uri) => base_uri,
 3681                    }
 3682                    .to_file_path()
 3683                    .ok()?;
 3684                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3685                    let mut literal_prefix = relative.to_owned();
 3686                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3687                    Some((
 3688                        worktree.clone(),
 3689                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3690                        rp.pattern.clone(),
 3691                    ))
 3692                }
 3693            }
 3694        })
 3695    }
 3696
 3697    fn rebuild_watched_paths(
 3698        &mut self,
 3699        language_server_id: LanguageServerId,
 3700        cx: &mut Context<LspStore>,
 3701    ) {
 3702        let Some(registrations) = self
 3703            .language_server_dynamic_registrations
 3704            .get(&language_server_id)
 3705        else {
 3706            return;
 3707        };
 3708
 3709        let watch_builder = self.rebuild_watched_paths_inner(
 3710            language_server_id,
 3711            registrations.did_change_watched_files.values().flatten(),
 3712            cx,
 3713        );
 3714        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3715        self.language_server_watched_paths
 3716            .insert(language_server_id, watcher);
 3717
 3718        cx.notify();
 3719    }
 3720
 3721    fn on_lsp_did_change_watched_files(
 3722        &mut self,
 3723        language_server_id: LanguageServerId,
 3724        registration_id: &str,
 3725        params: DidChangeWatchedFilesRegistrationOptions,
 3726        cx: &mut Context<LspStore>,
 3727    ) {
 3728        let registrations = self
 3729            .language_server_dynamic_registrations
 3730            .entry(language_server_id)
 3731            .or_default();
 3732
 3733        registrations
 3734            .did_change_watched_files
 3735            .insert(registration_id.to_string(), params.watchers);
 3736
 3737        self.rebuild_watched_paths(language_server_id, cx);
 3738    }
 3739
 3740    fn on_lsp_unregister_did_change_watched_files(
 3741        &mut self,
 3742        language_server_id: LanguageServerId,
 3743        registration_id: &str,
 3744        cx: &mut Context<LspStore>,
 3745    ) {
 3746        let registrations = self
 3747            .language_server_dynamic_registrations
 3748            .entry(language_server_id)
 3749            .or_default();
 3750
 3751        if registrations
 3752            .did_change_watched_files
 3753            .remove(registration_id)
 3754            .is_some()
 3755        {
 3756            log::info!(
 3757                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3758                language_server_id,
 3759                registration_id
 3760            );
 3761        } else {
 3762            log::warn!(
 3763                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3764                language_server_id,
 3765                registration_id
 3766            );
 3767        }
 3768
 3769        self.rebuild_watched_paths(language_server_id, cx);
 3770    }
 3771
 3772    async fn initialization_options_for_adapter(
 3773        adapter: Arc<dyn LspAdapter>,
 3774        delegate: &Arc<dyn LspAdapterDelegate>,
 3775        cx: &mut AsyncApp,
 3776    ) -> Result<Option<serde_json::Value>> {
 3777        let Some(mut initialization_config) =
 3778            adapter.clone().initialization_options(delegate, cx).await?
 3779        else {
 3780            return Ok(None);
 3781        };
 3782
 3783        for other_adapter in delegate.registered_lsp_adapters() {
 3784            if other_adapter.name() == adapter.name() {
 3785                continue;
 3786            }
 3787            if let Ok(Some(target_config)) = other_adapter
 3788                .clone()
 3789                .additional_initialization_options(adapter.name(), delegate)
 3790                .await
 3791            {
 3792                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3793            }
 3794        }
 3795
 3796        Ok(Some(initialization_config))
 3797    }
 3798
 3799    async fn workspace_configuration_for_adapter(
 3800        adapter: Arc<dyn LspAdapter>,
 3801        delegate: &Arc<dyn LspAdapterDelegate>,
 3802        toolchain: Option<Toolchain>,
 3803        requested_uri: Option<Uri>,
 3804        cx: &mut AsyncApp,
 3805    ) -> Result<serde_json::Value> {
 3806        let mut workspace_config = adapter
 3807            .clone()
 3808            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3809            .await?;
 3810
 3811        for other_adapter in delegate.registered_lsp_adapters() {
 3812            if other_adapter.name() == adapter.name() {
 3813                continue;
 3814            }
 3815            if let Ok(Some(target_config)) = other_adapter
 3816                .clone()
 3817                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3818                .await
 3819            {
 3820                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3821            }
 3822        }
 3823
 3824        Ok(workspace_config)
 3825    }
 3826
 3827    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3828        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3829            Some(server.clone())
 3830        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3831            Some(Arc::clone(server))
 3832        } else {
 3833            None
 3834        }
 3835    }
 3836}
 3837
 3838fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3839    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3840        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3841            language_server_id: server.server_id(),
 3842            name: Some(server.name()),
 3843            message: proto::update_language_server::Variant::MetadataUpdated(
 3844                proto::ServerMetadataUpdated {
 3845                    capabilities: Some(capabilities),
 3846                    binary: Some(proto::LanguageServerBinaryInfo {
 3847                        path: server.binary().path.to_string_lossy().into_owned(),
 3848                        arguments: server
 3849                            .binary()
 3850                            .arguments
 3851                            .iter()
 3852                            .map(|arg| arg.to_string_lossy().into_owned())
 3853                            .collect(),
 3854                    }),
 3855                    configuration: serde_json::to_string(server.configuration()).ok(),
 3856                    workspace_folders: server
 3857                        .workspace_folders()
 3858                        .iter()
 3859                        .map(|uri| uri.to_string())
 3860                        .collect(),
 3861                },
 3862            ),
 3863        });
 3864    }
 3865}
 3866
 3867#[derive(Debug)]
 3868pub struct FormattableBuffer {
 3869    handle: Entity<Buffer>,
 3870    abs_path: Option<PathBuf>,
 3871    env: Option<HashMap<String, String>>,
 3872    ranges: Option<Vec<Range<Anchor>>>,
 3873}
 3874
 3875pub struct RemoteLspStore {
 3876    upstream_client: Option<AnyProtoClient>,
 3877    upstream_project_id: u64,
 3878}
 3879
 3880pub(crate) enum LspStoreMode {
 3881    Local(LocalLspStore),   // ssh host and collab host
 3882    Remote(RemoteLspStore), // collab guest
 3883}
 3884
 3885impl LspStoreMode {
 3886    fn is_local(&self) -> bool {
 3887        matches!(self, LspStoreMode::Local(_))
 3888    }
 3889}
 3890
 3891pub struct LspStore {
 3892    mode: LspStoreMode,
 3893    last_formatting_failure: Option<String>,
 3894    downstream_client: Option<(AnyProtoClient, u64)>,
 3895    nonce: u128,
 3896    buffer_store: Entity<BufferStore>,
 3897    worktree_store: Entity<WorktreeStore>,
 3898    pub languages: Arc<LanguageRegistry>,
 3899    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3900    active_entry: Option<ProjectEntryId>,
 3901    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3902    _maintain_buffer_languages: Task<()>,
 3903    diagnostic_summaries:
 3904        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3905    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3906    semantic_token_config: SemanticTokenConfig,
 3907    lsp_data: HashMap<BufferId, BufferLspData>,
 3908    next_hint_id: Arc<AtomicUsize>,
 3909}
 3910
 3911#[derive(Debug)]
 3912pub struct BufferLspData {
 3913    buffer_version: Global,
 3914    document_colors: Option<DocumentColorData>,
 3915    code_lens: Option<CodeLensData>,
 3916    semantic_tokens: Option<SemanticTokensData>,
 3917    folding_ranges: Option<FoldingRangeData>,
 3918    document_symbols: Option<DocumentSymbolsData>,
 3919    inlay_hints: BufferInlayHints,
 3920    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3921    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3922}
 3923
 3924#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3925struct LspKey {
 3926    request_type: TypeId,
 3927    server_queried: Option<LanguageServerId>,
 3928}
 3929
 3930impl BufferLspData {
 3931    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3932        Self {
 3933            buffer_version: buffer.read(cx).version(),
 3934            document_colors: None,
 3935            code_lens: None,
 3936            semantic_tokens: None,
 3937            folding_ranges: None,
 3938            document_symbols: None,
 3939            inlay_hints: BufferInlayHints::new(buffer, cx),
 3940            lsp_requests: HashMap::default(),
 3941            chunk_lsp_requests: HashMap::default(),
 3942        }
 3943    }
 3944
 3945    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3946        if let Some(document_colors) = &mut self.document_colors {
 3947            document_colors.remove_server_data(for_server);
 3948        }
 3949
 3950        if let Some(code_lens) = &mut self.code_lens {
 3951            code_lens.remove_server_data(for_server);
 3952        }
 3953
 3954        self.inlay_hints.remove_server_data(for_server);
 3955
 3956        if let Some(semantic_tokens) = &mut self.semantic_tokens {
 3957            semantic_tokens.raw_tokens.servers.remove(&for_server);
 3958            semantic_tokens
 3959                .latest_invalidation_requests
 3960                .remove(&for_server);
 3961        }
 3962
 3963        if let Some(folding_ranges) = &mut self.folding_ranges {
 3964            folding_ranges.ranges.remove(&for_server);
 3965        }
 3966
 3967        if let Some(document_symbols) = &mut self.document_symbols {
 3968            document_symbols.remove_server_data(for_server);
 3969        }
 3970    }
 3971
 3972    #[cfg(any(test, feature = "test-support"))]
 3973    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3974        &self.inlay_hints
 3975    }
 3976}
 3977
 3978#[derive(Debug)]
 3979pub enum LspStoreEvent {
 3980    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3981    LanguageServerRemoved(LanguageServerId),
 3982    LanguageServerUpdate {
 3983        language_server_id: LanguageServerId,
 3984        name: Option<LanguageServerName>,
 3985        message: proto::update_language_server::Variant,
 3986    },
 3987    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3988    LanguageServerPrompt(LanguageServerPromptRequest),
 3989    LanguageDetected {
 3990        buffer: Entity<Buffer>,
 3991        new_language: Option<Arc<Language>>,
 3992    },
 3993    Notification(String),
 3994    RefreshInlayHints {
 3995        server_id: LanguageServerId,
 3996        request_id: Option<usize>,
 3997    },
 3998    RefreshSemanticTokens {
 3999        server_id: LanguageServerId,
 4000        request_id: Option<usize>,
 4001    },
 4002    RefreshCodeLens,
 4003    DiagnosticsUpdated {
 4004        server_id: LanguageServerId,
 4005        paths: Vec<ProjectPath>,
 4006    },
 4007    DiskBasedDiagnosticsStarted {
 4008        language_server_id: LanguageServerId,
 4009    },
 4010    DiskBasedDiagnosticsFinished {
 4011        language_server_id: LanguageServerId,
 4012    },
 4013    SnippetEdit {
 4014        buffer_id: BufferId,
 4015        edits: Vec<(lsp::Range, Snippet)>,
 4016        most_recent_edit: clock::Lamport,
 4017    },
 4018    WorkspaceEditApplied(ProjectTransaction),
 4019}
 4020
 4021#[derive(Clone, Debug, Serialize)]
 4022pub struct LanguageServerStatus {
 4023    pub name: LanguageServerName,
 4024    pub server_version: Option<SharedString>,
 4025    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 4026    pub has_pending_diagnostic_updates: bool,
 4027    pub progress_tokens: HashSet<ProgressToken>,
 4028    pub worktree: Option<WorktreeId>,
 4029    pub binary: Option<LanguageServerBinary>,
 4030    pub configuration: Option<Value>,
 4031    pub workspace_folders: BTreeSet<Uri>,
 4032    pub process_id: Option<u32>,
 4033}
 4034
 4035#[derive(Clone, Debug)]
 4036struct CoreSymbol {
 4037    pub language_server_name: LanguageServerName,
 4038    pub source_worktree_id: WorktreeId,
 4039    pub source_language_server_id: LanguageServerId,
 4040    pub path: SymbolLocation,
 4041    pub name: String,
 4042    pub kind: lsp::SymbolKind,
 4043    pub range: Range<Unclipped<PointUtf16>>,
 4044    pub container_name: Option<String>,
 4045}
 4046
 4047#[derive(Clone, Debug, PartialEq, Eq)]
 4048pub enum SymbolLocation {
 4049    InProject(ProjectPath),
 4050    OutsideProject {
 4051        abs_path: Arc<Path>,
 4052        signature: [u8; 32],
 4053    },
 4054}
 4055
 4056impl SymbolLocation {
 4057    fn file_name(&self) -> Option<&str> {
 4058        match self {
 4059            Self::InProject(path) => path.path.file_name(),
 4060            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 4061        }
 4062    }
 4063}
 4064
 4065impl LspStore {
 4066    pub fn init(client: &AnyProtoClient) {
 4067        client.add_entity_request_handler(Self::handle_lsp_query);
 4068        client.add_entity_message_handler(Self::handle_lsp_query_response);
 4069        client.add_entity_request_handler(Self::handle_restart_language_servers);
 4070        client.add_entity_request_handler(Self::handle_stop_language_servers);
 4071        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 4072        client.add_entity_message_handler(Self::handle_start_language_server);
 4073        client.add_entity_message_handler(Self::handle_update_language_server);
 4074        client.add_entity_message_handler(Self::handle_language_server_log);
 4075        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 4076        client.add_entity_request_handler(Self::handle_format_buffers);
 4077        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 4078        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 4079        client.add_entity_request_handler(Self::handle_apply_code_action);
 4080        client.add_entity_request_handler(Self::handle_get_project_symbols);
 4081        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 4082        client.add_entity_request_handler(Self::handle_get_color_presentation);
 4083        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 4084        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 4085        client.add_entity_request_handler(Self::handle_refresh_semantic_tokens);
 4086        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 4087        client.add_entity_request_handler(Self::handle_on_type_formatting);
 4088        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 4089        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 4090        client.add_entity_request_handler(Self::handle_rename_project_entry);
 4091        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 4092        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 4093        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 4094        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 4095        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 4096        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 4097        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 4098
 4099        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 4100        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 4101        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 4102        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 4103        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 4104        client.add_entity_request_handler(
 4105            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 4106        );
 4107        client.add_entity_request_handler(
 4108            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 4109        );
 4110        client.add_entity_request_handler(
 4111            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 4112        );
 4113    }
 4114
 4115    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 4116        match &self.mode {
 4117            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 4118            _ => None,
 4119        }
 4120    }
 4121
 4122    pub fn as_local(&self) -> Option<&LocalLspStore> {
 4123        match &self.mode {
 4124            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4125            _ => None,
 4126        }
 4127    }
 4128
 4129    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 4130        match &mut self.mode {
 4131            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4132            _ => None,
 4133        }
 4134    }
 4135
 4136    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4137        match &self.mode {
 4138            LspStoreMode::Remote(RemoteLspStore {
 4139                upstream_client: Some(upstream_client),
 4140                upstream_project_id,
 4141                ..
 4142            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4143
 4144            LspStoreMode::Remote(RemoteLspStore {
 4145                upstream_client: None,
 4146                ..
 4147            }) => None,
 4148            LspStoreMode::Local(_) => None,
 4149        }
 4150    }
 4151
 4152    pub fn new_local(
 4153        buffer_store: Entity<BufferStore>,
 4154        worktree_store: Entity<WorktreeStore>,
 4155        prettier_store: Entity<PrettierStore>,
 4156        toolchain_store: Entity<LocalToolchainStore>,
 4157        environment: Entity<ProjectEnvironment>,
 4158        manifest_tree: Entity<ManifestTree>,
 4159        languages: Arc<LanguageRegistry>,
 4160        http_client: Arc<dyn HttpClient>,
 4161        fs: Arc<dyn Fs>,
 4162        cx: &mut Context<Self>,
 4163    ) -> Self {
 4164        let yarn = YarnPathStore::new(fs.clone(), cx);
 4165        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4166            .detach();
 4167        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4168            .detach();
 4169        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4170            .detach();
 4171        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4172            .detach();
 4173        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4174            .detach();
 4175        subscribe_to_binary_statuses(&languages, cx).detach();
 4176
 4177        let _maintain_workspace_config = {
 4178            let (sender, receiver) = watch::channel();
 4179            (Self::maintain_workspace_config(receiver, cx), sender)
 4180        };
 4181
 4182        Self {
 4183            mode: LspStoreMode::Local(LocalLspStore {
 4184                weak: cx.weak_entity(),
 4185                worktree_store: worktree_store.clone(),
 4186
 4187                supplementary_language_servers: Default::default(),
 4188                languages: languages.clone(),
 4189                language_server_ids: Default::default(),
 4190                language_servers: Default::default(),
 4191                last_workspace_edits_by_language_server: Default::default(),
 4192                language_server_watched_paths: Default::default(),
 4193                language_server_paths_watched_for_rename: Default::default(),
 4194                language_server_dynamic_registrations: Default::default(),
 4195                buffers_being_formatted: Default::default(),
 4196                buffers_to_refresh_hash_set: HashSet::default(),
 4197                buffers_to_refresh_queue: VecDeque::new(),
 4198                _background_diagnostics_worker: Task::ready(()).shared(),
 4199                buffer_snapshots: Default::default(),
 4200                prettier_store,
 4201                environment,
 4202                http_client,
 4203                fs,
 4204                yarn,
 4205                next_diagnostic_group_id: Default::default(),
 4206                diagnostics: Default::default(),
 4207                _subscription: cx.on_app_quit(|this, _| {
 4208                    this.as_local_mut()
 4209                        .unwrap()
 4210                        .shutdown_language_servers_on_quit()
 4211                }),
 4212                lsp_tree: LanguageServerTree::new(
 4213                    manifest_tree,
 4214                    languages.clone(),
 4215                    toolchain_store.clone(),
 4216                ),
 4217                toolchain_store,
 4218                registered_buffers: HashMap::default(),
 4219                buffers_opened_in_servers: HashMap::default(),
 4220                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4221                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4222                restricted_worktrees_tasks: HashMap::default(),
 4223                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4224                    .manifest_file_names(),
 4225            }),
 4226            last_formatting_failure: None,
 4227            downstream_client: None,
 4228            buffer_store,
 4229            worktree_store,
 4230            languages: languages.clone(),
 4231            language_server_statuses: Default::default(),
 4232            nonce: StdRng::from_os_rng().random(),
 4233            diagnostic_summaries: HashMap::default(),
 4234            lsp_server_capabilities: HashMap::default(),
 4235            semantic_token_config: SemanticTokenConfig::new(cx),
 4236            lsp_data: HashMap::default(),
 4237            next_hint_id: Arc::default(),
 4238            active_entry: None,
 4239            _maintain_workspace_config,
 4240            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4241        }
 4242    }
 4243
 4244    fn send_lsp_proto_request<R: LspCommand>(
 4245        &self,
 4246        buffer: Entity<Buffer>,
 4247        client: AnyProtoClient,
 4248        upstream_project_id: u64,
 4249        request: R,
 4250        cx: &mut Context<LspStore>,
 4251    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4252        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4253            return Task::ready(Ok(R::Response::default()));
 4254        }
 4255        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4256        cx.spawn(async move |this, cx| {
 4257            let response = client.request(message).await?;
 4258            let this = this.upgrade().context("project dropped")?;
 4259            request
 4260                .response_from_proto(response, this, buffer, cx.clone())
 4261                .await
 4262        })
 4263    }
 4264
 4265    pub(super) fn new_remote(
 4266        buffer_store: Entity<BufferStore>,
 4267        worktree_store: Entity<WorktreeStore>,
 4268        languages: Arc<LanguageRegistry>,
 4269        upstream_client: AnyProtoClient,
 4270        project_id: u64,
 4271        cx: &mut Context<Self>,
 4272    ) -> Self {
 4273        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4274            .detach();
 4275        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4276            .detach();
 4277        subscribe_to_binary_statuses(&languages, cx).detach();
 4278        let _maintain_workspace_config = {
 4279            let (sender, receiver) = watch::channel();
 4280            (Self::maintain_workspace_config(receiver, cx), sender)
 4281        };
 4282        Self {
 4283            mode: LspStoreMode::Remote(RemoteLspStore {
 4284                upstream_client: Some(upstream_client),
 4285                upstream_project_id: project_id,
 4286            }),
 4287            downstream_client: None,
 4288            last_formatting_failure: None,
 4289            buffer_store,
 4290            worktree_store,
 4291            languages: languages.clone(),
 4292            language_server_statuses: Default::default(),
 4293            nonce: StdRng::from_os_rng().random(),
 4294            diagnostic_summaries: HashMap::default(),
 4295            lsp_server_capabilities: HashMap::default(),
 4296            semantic_token_config: SemanticTokenConfig::new(cx),
 4297            next_hint_id: Arc::default(),
 4298            lsp_data: HashMap::default(),
 4299            active_entry: None,
 4300
 4301            _maintain_workspace_config,
 4302            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4303        }
 4304    }
 4305
 4306    fn on_buffer_store_event(
 4307        &mut self,
 4308        _: Entity<BufferStore>,
 4309        event: &BufferStoreEvent,
 4310        cx: &mut Context<Self>,
 4311    ) {
 4312        match event {
 4313            BufferStoreEvent::BufferAdded(buffer) => {
 4314                self.on_buffer_added(buffer, cx).log_err();
 4315            }
 4316            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4317                let buffer_id = buffer.read(cx).remote_id();
 4318                if let Some(local) = self.as_local_mut()
 4319                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4320                {
 4321                    local.reset_buffer(buffer, old_file, cx);
 4322
 4323                    if local.registered_buffers.contains_key(&buffer_id) {
 4324                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4325                    }
 4326                }
 4327
 4328                self.detect_language_for_buffer(buffer, cx);
 4329                if let Some(local) = self.as_local_mut() {
 4330                    local.initialize_buffer(buffer, cx);
 4331                    if local.registered_buffers.contains_key(&buffer_id) {
 4332                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4333                    }
 4334                }
 4335            }
 4336            _ => {}
 4337        }
 4338    }
 4339
 4340    fn on_worktree_store_event(
 4341        &mut self,
 4342        _: Entity<WorktreeStore>,
 4343        event: &WorktreeStoreEvent,
 4344        cx: &mut Context<Self>,
 4345    ) {
 4346        match event {
 4347            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4348                if !worktree.read(cx).is_local() {
 4349                    return;
 4350                }
 4351                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4352                    worktree::Event::UpdatedEntries(changes) => {
 4353                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4354                    }
 4355                    worktree::Event::UpdatedGitRepositories(_)
 4356                    | worktree::Event::DeletedEntry(_) => {}
 4357                })
 4358                .detach()
 4359            }
 4360            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4361            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4362                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4363            }
 4364            WorktreeStoreEvent::WorktreeReleased(..)
 4365            | WorktreeStoreEvent::WorktreeOrderChanged
 4366            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4367            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4368            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4369        }
 4370    }
 4371
 4372    fn on_prettier_store_event(
 4373        &mut self,
 4374        _: Entity<PrettierStore>,
 4375        event: &PrettierStoreEvent,
 4376        cx: &mut Context<Self>,
 4377    ) {
 4378        match event {
 4379            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4380                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4381            }
 4382            PrettierStoreEvent::LanguageServerAdded {
 4383                new_server_id,
 4384                name,
 4385                prettier_server,
 4386            } => {
 4387                self.register_supplementary_language_server(
 4388                    *new_server_id,
 4389                    name.clone(),
 4390                    prettier_server.clone(),
 4391                    cx,
 4392                );
 4393            }
 4394        }
 4395    }
 4396
 4397    fn on_toolchain_store_event(
 4398        &mut self,
 4399        _: Entity<LocalToolchainStore>,
 4400        event: &ToolchainStoreEvent,
 4401        _: &mut Context<Self>,
 4402    ) {
 4403        if let ToolchainStoreEvent::ToolchainActivated = event {
 4404            self.request_workspace_config_refresh()
 4405        }
 4406    }
 4407
 4408    fn request_workspace_config_refresh(&mut self) {
 4409        *self._maintain_workspace_config.1.borrow_mut() = ();
 4410    }
 4411
 4412    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4413        self.as_local().map(|local| local.prettier_store.clone())
 4414    }
 4415
 4416    fn on_buffer_event(
 4417        &mut self,
 4418        buffer: Entity<Buffer>,
 4419        event: &language::BufferEvent,
 4420        cx: &mut Context<Self>,
 4421    ) {
 4422        match event {
 4423            language::BufferEvent::Edited => {
 4424                self.on_buffer_edited(buffer, cx);
 4425            }
 4426
 4427            language::BufferEvent::Saved => {
 4428                self.on_buffer_saved(buffer, cx);
 4429            }
 4430
 4431            _ => {}
 4432        }
 4433    }
 4434
 4435    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4436        buffer
 4437            .read(cx)
 4438            .set_language_registry(self.languages.clone());
 4439
 4440        cx.subscribe(buffer, |this, buffer, event, cx| {
 4441            this.on_buffer_event(buffer, event, cx);
 4442        })
 4443        .detach();
 4444
 4445        self.detect_language_for_buffer(buffer, cx);
 4446        if let Some(local) = self.as_local_mut() {
 4447            local.initialize_buffer(buffer, cx);
 4448        }
 4449
 4450        Ok(())
 4451    }
 4452
 4453    pub fn refresh_background_diagnostics_for_buffers(
 4454        &mut self,
 4455        buffers: HashSet<BufferId>,
 4456        cx: &mut Context<Self>,
 4457    ) -> Shared<Task<()>> {
 4458        let Some(local) = self.as_local_mut() else {
 4459            return Task::ready(()).shared();
 4460        };
 4461        for buffer in buffers {
 4462            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4463                local.buffers_to_refresh_queue.push_back(buffer);
 4464                if local.buffers_to_refresh_queue.len() == 1 {
 4465                    local._background_diagnostics_worker =
 4466                        Self::background_diagnostics_worker(cx).shared();
 4467                }
 4468            }
 4469        }
 4470
 4471        local._background_diagnostics_worker.clone()
 4472    }
 4473
 4474    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4475        let buffer_store = self.buffer_store.clone();
 4476        let local = self.as_local_mut()?;
 4477        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4478            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4479            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4480                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4481            }
 4482        }
 4483        None
 4484    }
 4485
 4486    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4487        cx.spawn(async move |this, cx| {
 4488            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4489                task.await.log_err();
 4490            }
 4491        })
 4492    }
 4493
 4494    pub(crate) fn register_buffer_with_language_servers(
 4495        &mut self,
 4496        buffer: &Entity<Buffer>,
 4497        only_register_servers: HashSet<LanguageServerSelector>,
 4498        ignore_refcounts: bool,
 4499        cx: &mut Context<Self>,
 4500    ) -> OpenLspBufferHandle {
 4501        let buffer_id = buffer.read(cx).remote_id();
 4502        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4503        if let Some(local) = self.as_local_mut() {
 4504            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4505            if !ignore_refcounts {
 4506                *refcount += 1;
 4507            }
 4508
 4509            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4510            // 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
 4511            // 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
 4512            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4513            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4514                return handle;
 4515            };
 4516            if !file.is_local() {
 4517                return handle;
 4518            }
 4519
 4520            if ignore_refcounts || *refcount == 1 {
 4521                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4522            }
 4523            if !ignore_refcounts {
 4524                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4525                    let refcount = {
 4526                        let local = lsp_store.as_local_mut().unwrap();
 4527                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4528                            debug_panic!("bad refcounting");
 4529                            return;
 4530                        };
 4531
 4532                        *refcount -= 1;
 4533                        *refcount
 4534                    };
 4535                    if refcount == 0 {
 4536                        lsp_store.lsp_data.remove(&buffer_id);
 4537                        let local = lsp_store.as_local_mut().unwrap();
 4538                        local.registered_buffers.remove(&buffer_id);
 4539
 4540                        local.buffers_opened_in_servers.remove(&buffer_id);
 4541                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4542                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4543
 4544                            let buffer_abs_path = file.abs_path(cx);
 4545                            for (_, buffer_pull_diagnostics_result_ids) in
 4546                                &mut local.buffer_pull_diagnostics_result_ids
 4547                            {
 4548                                buffer_pull_diagnostics_result_ids.retain(
 4549                                    |_, buffer_result_ids| {
 4550                                        buffer_result_ids.remove(&buffer_abs_path);
 4551                                        !buffer_result_ids.is_empty()
 4552                                    },
 4553                                );
 4554                            }
 4555
 4556                            let diagnostic_updates = local
 4557                                .language_servers
 4558                                .keys()
 4559                                .cloned()
 4560                                .map(|server_id| DocumentDiagnosticsUpdate {
 4561                                    diagnostics: DocumentDiagnostics {
 4562                                        document_abs_path: buffer_abs_path.clone(),
 4563                                        version: None,
 4564                                        diagnostics: Vec::new(),
 4565                                    },
 4566                                    result_id: None,
 4567                                    registration_id: None,
 4568                                    server_id,
 4569                                    disk_based_sources: Cow::Borrowed(&[]),
 4570                                })
 4571                                .collect::<Vec<_>>();
 4572
 4573                            lsp_store
 4574                                .merge_diagnostic_entries(
 4575                                    diagnostic_updates,
 4576                                    |_, diagnostic, _| {
 4577                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4578                                    },
 4579                                    cx,
 4580                                )
 4581                                .context("Clearing diagnostics for the closed buffer")
 4582                                .log_err();
 4583                        }
 4584                    }
 4585                })
 4586                .detach();
 4587            }
 4588        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4589            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4590            cx.background_spawn(async move {
 4591                upstream_client
 4592                    .request(proto::RegisterBufferWithLanguageServers {
 4593                        project_id: upstream_project_id,
 4594                        buffer_id,
 4595                        only_servers: only_register_servers
 4596                            .into_iter()
 4597                            .map(|selector| {
 4598                                let selector = match selector {
 4599                                    LanguageServerSelector::Id(language_server_id) => {
 4600                                        proto::language_server_selector::Selector::ServerId(
 4601                                            language_server_id.to_proto(),
 4602                                        )
 4603                                    }
 4604                                    LanguageServerSelector::Name(language_server_name) => {
 4605                                        proto::language_server_selector::Selector::Name(
 4606                                            language_server_name.to_string(),
 4607                                        )
 4608                                    }
 4609                                };
 4610                                proto::LanguageServerSelector {
 4611                                    selector: Some(selector),
 4612                                }
 4613                            })
 4614                            .collect(),
 4615                    })
 4616                    .await
 4617            })
 4618            .detach();
 4619        } else {
 4620            // Our remote connection got closed
 4621        }
 4622        handle
 4623    }
 4624
 4625    fn maintain_buffer_languages(
 4626        languages: Arc<LanguageRegistry>,
 4627        cx: &mut Context<Self>,
 4628    ) -> Task<()> {
 4629        let mut subscription = languages.subscribe();
 4630        let mut prev_reload_count = languages.reload_count();
 4631        cx.spawn(async move |this, cx| {
 4632            while let Some(()) = subscription.next().await {
 4633                if let Some(this) = this.upgrade() {
 4634                    // If the language registry has been reloaded, then remove and
 4635                    // re-assign the languages on all open buffers.
 4636                    let reload_count = languages.reload_count();
 4637                    if reload_count > prev_reload_count {
 4638                        prev_reload_count = reload_count;
 4639                        this.update(cx, |this, cx| {
 4640                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4641                                for buffer in buffer_store.buffers() {
 4642                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4643                                    {
 4644                                        buffer.update(cx, |buffer, cx| {
 4645                                            buffer.set_language_async(None, cx)
 4646                                        });
 4647                                        if let Some(local) = this.as_local_mut() {
 4648                                            local.reset_buffer(&buffer, &f, cx);
 4649
 4650                                            if local
 4651                                                .registered_buffers
 4652                                                .contains_key(&buffer.read(cx).remote_id())
 4653                                                && let Some(file_url) =
 4654                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4655                                            {
 4656                                                local.unregister_buffer_from_language_servers(
 4657                                                    &buffer, &file_url, cx,
 4658                                                );
 4659                                            }
 4660                                        }
 4661                                    }
 4662                                }
 4663                            });
 4664                        });
 4665                    }
 4666
 4667                    this.update(cx, |this, cx| {
 4668                        let mut plain_text_buffers = Vec::new();
 4669                        let mut buffers_with_unknown_injections = Vec::new();
 4670                        for handle in this.buffer_store.read(cx).buffers() {
 4671                            let buffer = handle.read(cx);
 4672                            if buffer.language().is_none()
 4673                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4674                            {
 4675                                plain_text_buffers.push(handle);
 4676                            } else if buffer.contains_unknown_injections() {
 4677                                buffers_with_unknown_injections.push(handle);
 4678                            }
 4679                        }
 4680
 4681                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4682                        // and reused later in the invisible worktrees.
 4683                        plain_text_buffers.sort_by_key(|buffer| {
 4684                            Reverse(
 4685                                File::from_dyn(buffer.read(cx).file())
 4686                                    .map(|file| file.worktree.read(cx).is_visible()),
 4687                            )
 4688                        });
 4689
 4690                        for buffer in plain_text_buffers {
 4691                            this.detect_language_for_buffer(&buffer, cx);
 4692                            if let Some(local) = this.as_local_mut() {
 4693                                local.initialize_buffer(&buffer, cx);
 4694                                if local
 4695                                    .registered_buffers
 4696                                    .contains_key(&buffer.read(cx).remote_id())
 4697                                {
 4698                                    local.register_buffer_with_language_servers(
 4699                                        &buffer,
 4700                                        HashSet::default(),
 4701                                        cx,
 4702                                    );
 4703                                }
 4704                            }
 4705                        }
 4706
 4707                        for buffer in buffers_with_unknown_injections {
 4708                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4709                        }
 4710                    });
 4711                }
 4712            }
 4713        })
 4714    }
 4715
 4716    fn detect_language_for_buffer(
 4717        &mut self,
 4718        buffer_handle: &Entity<Buffer>,
 4719        cx: &mut Context<Self>,
 4720    ) -> Option<language::AvailableLanguage> {
 4721        // If the buffer has a language, set it and start the language server if we haven't already.
 4722        let buffer = buffer_handle.read(cx);
 4723        let file = buffer.file()?;
 4724
 4725        let content = buffer.as_rope();
 4726        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4727        if let Some(available_language) = &available_language {
 4728            if let Some(Ok(Ok(new_language))) = self
 4729                .languages
 4730                .load_language(available_language)
 4731                .now_or_never()
 4732            {
 4733                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4734            }
 4735        } else {
 4736            cx.emit(LspStoreEvent::LanguageDetected {
 4737                buffer: buffer_handle.clone(),
 4738                new_language: None,
 4739            });
 4740        }
 4741
 4742        available_language
 4743    }
 4744
 4745    pub(crate) fn set_language_for_buffer(
 4746        &mut self,
 4747        buffer_entity: &Entity<Buffer>,
 4748        new_language: Arc<Language>,
 4749        cx: &mut Context<Self>,
 4750    ) {
 4751        let buffer = buffer_entity.read(cx);
 4752        let buffer_file = buffer.file().cloned();
 4753        let buffer_id = buffer.remote_id();
 4754        if let Some(local_store) = self.as_local_mut()
 4755            && local_store.registered_buffers.contains_key(&buffer_id)
 4756            && let Some(abs_path) =
 4757                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4758            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4759        {
 4760            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4761        }
 4762        buffer_entity.update(cx, |buffer, cx| {
 4763            if buffer
 4764                .language()
 4765                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4766            {
 4767                buffer.set_language_async(Some(new_language.clone()), cx);
 4768            }
 4769        });
 4770
 4771        let settings =
 4772            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4773        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4774
 4775        let worktree_id = if let Some(file) = buffer_file {
 4776            let worktree = file.worktree.clone();
 4777
 4778            if let Some(local) = self.as_local_mut()
 4779                && local.registered_buffers.contains_key(&buffer_id)
 4780            {
 4781                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4782            }
 4783            Some(worktree.read(cx).id())
 4784        } else {
 4785            None
 4786        };
 4787
 4788        if settings.prettier.allowed
 4789            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4790        {
 4791            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4792            if let Some(prettier_store) = prettier_store {
 4793                prettier_store.update(cx, |prettier_store, cx| {
 4794                    prettier_store.install_default_prettier(
 4795                        worktree_id,
 4796                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4797                        cx,
 4798                    )
 4799                })
 4800            }
 4801        }
 4802
 4803        cx.emit(LspStoreEvent::LanguageDetected {
 4804            buffer: buffer_entity.clone(),
 4805            new_language: Some(new_language),
 4806        })
 4807    }
 4808
 4809    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4810        self.buffer_store.clone()
 4811    }
 4812
 4813    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4814        self.active_entry = active_entry;
 4815    }
 4816
 4817    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4818        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4819            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4820        {
 4821            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4822                summaries
 4823                    .iter()
 4824                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4825            });
 4826            if let Some(summary) = summaries.next() {
 4827                client
 4828                    .send(proto::UpdateDiagnosticSummary {
 4829                        project_id: downstream_project_id,
 4830                        worktree_id: worktree.id().to_proto(),
 4831                        summary: Some(summary),
 4832                        more_summaries: summaries.collect(),
 4833                    })
 4834                    .log_err();
 4835            }
 4836        }
 4837    }
 4838
 4839    fn is_capable_for_proto_request<R>(
 4840        &self,
 4841        buffer: &Entity<Buffer>,
 4842        request: &R,
 4843        cx: &App,
 4844    ) -> bool
 4845    where
 4846        R: LspCommand,
 4847    {
 4848        self.check_if_capable_for_proto_request(
 4849            buffer,
 4850            |capabilities| {
 4851                request.check_capabilities(AdapterServerCapabilities {
 4852                    server_capabilities: capabilities.clone(),
 4853                    code_action_kinds: None,
 4854                })
 4855            },
 4856            cx,
 4857        )
 4858    }
 4859
 4860    fn check_if_capable_for_proto_request<F>(
 4861        &self,
 4862        buffer: &Entity<Buffer>,
 4863        check: F,
 4864        cx: &App,
 4865    ) -> bool
 4866    where
 4867        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4868    {
 4869        let Some(language) = buffer.read(cx).language().cloned() else {
 4870            return false;
 4871        };
 4872        let registered_language_servers = self
 4873            .languages
 4874            .lsp_adapters(&language.name())
 4875            .into_iter()
 4876            .map(|lsp_adapter| lsp_adapter.name())
 4877            .collect::<HashSet<_>>();
 4878        self.language_server_statuses
 4879            .iter()
 4880            .filter_map(|(server_id, server_status)| {
 4881                // Include servers that are either registered for this language OR
 4882                // available to be loaded (for SSH remote mode where adapters like
 4883                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4884                // but only loaded on the server side)
 4885                let is_relevant = registered_language_servers.contains(&server_status.name)
 4886                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4887                is_relevant.then_some(server_id)
 4888            })
 4889            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4890            .any(check)
 4891    }
 4892
 4893    fn all_capable_for_proto_request<F>(
 4894        &self,
 4895        buffer: &Entity<Buffer>,
 4896        mut check: F,
 4897        cx: &App,
 4898    ) -> Vec<lsp::LanguageServerId>
 4899    where
 4900        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4901    {
 4902        let Some(language) = buffer.read(cx).language().cloned() else {
 4903            return Vec::default();
 4904        };
 4905        let registered_language_servers = self
 4906            .languages
 4907            .lsp_adapters(&language.name())
 4908            .into_iter()
 4909            .map(|lsp_adapter| lsp_adapter.name())
 4910            .collect::<HashSet<_>>();
 4911        self.language_server_statuses
 4912            .iter()
 4913            .filter_map(|(server_id, server_status)| {
 4914                // Include servers that are either registered for this language OR
 4915                // available to be loaded (for SSH remote mode where adapters like
 4916                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4917                // but only loaded on the server side)
 4918                let is_relevant = registered_language_servers.contains(&server_status.name)
 4919                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4920                is_relevant.then_some((server_id, &server_status.name))
 4921            })
 4922            .filter_map(|(server_id, server_name)| {
 4923                self.lsp_server_capabilities
 4924                    .get(server_id)
 4925                    .map(|c| (server_id, server_name, c))
 4926            })
 4927            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4928            .map(|(server_id, _, _)| *server_id)
 4929            .collect()
 4930    }
 4931
 4932    pub fn request_lsp<R>(
 4933        &mut self,
 4934        buffer: Entity<Buffer>,
 4935        server: LanguageServerToQuery,
 4936        request: R,
 4937        cx: &mut Context<Self>,
 4938    ) -> Task<Result<R::Response>>
 4939    where
 4940        R: LspCommand,
 4941        <R::LspRequest as lsp::request::Request>::Result: Send,
 4942        <R::LspRequest as lsp::request::Request>::Params: Send,
 4943    {
 4944        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4945            return self.send_lsp_proto_request(
 4946                buffer,
 4947                upstream_client,
 4948                upstream_project_id,
 4949                request,
 4950                cx,
 4951            );
 4952        }
 4953
 4954        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4955            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4956                local
 4957                    .language_servers_for_buffer(buffer, cx)
 4958                    .find(|(_, server)| {
 4959                        request.check_capabilities(server.adapter_server_capabilities())
 4960                    })
 4961                    .map(|(_, server)| server.clone())
 4962            }),
 4963            LanguageServerToQuery::Other(id) => self
 4964                .language_server_for_local_buffer(buffer, id, cx)
 4965                .and_then(|(_, server)| {
 4966                    request
 4967                        .check_capabilities(server.adapter_server_capabilities())
 4968                        .then(|| Arc::clone(server))
 4969                }),
 4970        }) else {
 4971            return Task::ready(Ok(Default::default()));
 4972        };
 4973
 4974        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4975
 4976        let Some(file) = file else {
 4977            return Task::ready(Ok(Default::default()));
 4978        };
 4979
 4980        let lsp_params = match request.to_lsp_params_or_response(
 4981            &file.abs_path(cx),
 4982            buffer.read(cx),
 4983            &language_server,
 4984            cx,
 4985        ) {
 4986            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4987            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4988            Err(err) => {
 4989                let message = format!(
 4990                    "{} via {} failed: {}",
 4991                    request.display_name(),
 4992                    language_server.name(),
 4993                    err
 4994                );
 4995                // rust-analyzer likes to error with this when its still loading up
 4996                if !message.ends_with("content modified") {
 4997                    log::warn!("{message}");
 4998                }
 4999                return Task::ready(Err(anyhow!(message)));
 5000            }
 5001        };
 5002
 5003        let status = request.status();
 5004        let request_timeout = ProjectSettings::get_global(cx)
 5005            .global_lsp_settings
 5006            .get_request_timeout();
 5007
 5008        cx.spawn(async move |this, cx| {
 5009            let lsp_request = language_server.request::<R::LspRequest>(lsp_params, request_timeout);
 5010
 5011            let id = lsp_request.id();
 5012            let _cleanup = if status.is_some() {
 5013                cx.update(|cx| {
 5014                    this.update(cx, |this, cx| {
 5015                        this.on_lsp_work_start(
 5016                            language_server.server_id(),
 5017                            ProgressToken::Number(id),
 5018                            LanguageServerProgress {
 5019                                is_disk_based_diagnostics_progress: false,
 5020                                is_cancellable: false,
 5021                                title: None,
 5022                                message: status.clone(),
 5023                                percentage: None,
 5024                                last_update_at: cx.background_executor().now(),
 5025                            },
 5026                            cx,
 5027                        );
 5028                    })
 5029                })
 5030                .log_err();
 5031
 5032                Some(defer(|| {
 5033                    cx.update(|cx| {
 5034                        this.update(cx, |this, cx| {
 5035                            this.on_lsp_work_end(
 5036                                language_server.server_id(),
 5037                                ProgressToken::Number(id),
 5038                                cx,
 5039                            );
 5040                        })
 5041                    })
 5042                    .log_err();
 5043                }))
 5044            } else {
 5045                None
 5046            };
 5047
 5048            let result = lsp_request.await.into_response();
 5049
 5050            let response = result.map_err(|err| {
 5051                let message = format!(
 5052                    "{} via {} failed: {}",
 5053                    request.display_name(),
 5054                    language_server.name(),
 5055                    err
 5056                );
 5057                // rust-analyzer likes to error with this when its still loading up
 5058                if !message.ends_with("content modified") {
 5059                    log::warn!("{message}");
 5060                }
 5061                anyhow::anyhow!(message)
 5062            })?;
 5063
 5064            request
 5065                .response_from_lsp(
 5066                    response,
 5067                    this.upgrade().context("no app context")?,
 5068                    buffer,
 5069                    language_server.server_id(),
 5070                    cx.clone(),
 5071                )
 5072                .await
 5073        })
 5074    }
 5075
 5076    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 5077        let mut language_formatters_to_check = Vec::new();
 5078        for buffer in self.buffer_store.read(cx).buffers() {
 5079            let buffer = buffer.read(cx);
 5080            let buffer_file = File::from_dyn(buffer.file());
 5081            let buffer_language = buffer.language();
 5082            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 5083            if buffer_language.is_some() {
 5084                language_formatters_to_check.push((
 5085                    buffer_file.map(|f| f.worktree_id(cx)),
 5086                    settings.into_owned(),
 5087                ));
 5088            }
 5089        }
 5090
 5091        self.request_workspace_config_refresh();
 5092
 5093        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 5094            prettier_store.update(cx, |prettier_store, cx| {
 5095                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 5096            })
 5097        }
 5098
 5099        let new_semantic_token_rules = crate::project_settings::ProjectSettings::get_global(cx)
 5100            .global_lsp_settings
 5101            .semantic_token_rules
 5102            .clone();
 5103        self.semantic_token_config
 5104            .update_rules(new_semantic_token_rules);
 5105        // Always clear cached stylizers so that changes to language-specific
 5106        // semantic token rules (e.g. from extension install/uninstall) are
 5107        // picked up. Stylizers are recreated lazily, so this is cheap.
 5108        self.semantic_token_config.clear_stylizers();
 5109
 5110        let new_global_semantic_tokens_mode =
 5111            all_language_settings(None, cx).defaults.semantic_tokens;
 5112        if self
 5113            .semantic_token_config
 5114            .update_global_mode(new_global_semantic_tokens_mode)
 5115        {
 5116            self.restart_all_language_servers(cx);
 5117        }
 5118
 5119        cx.notify();
 5120    }
 5121
 5122    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 5123        let buffer_store = self.buffer_store.clone();
 5124        let Some(local) = self.as_local_mut() else {
 5125            return;
 5126        };
 5127        let mut adapters = BTreeMap::default();
 5128        let get_adapter = {
 5129            let languages = local.languages.clone();
 5130            let environment = local.environment.clone();
 5131            let weak = local.weak.clone();
 5132            let worktree_store = local.worktree_store.clone();
 5133            let http_client = local.http_client.clone();
 5134            let fs = local.fs.clone();
 5135            move |worktree_id, cx: &mut App| {
 5136                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 5137                Some(LocalLspAdapterDelegate::new(
 5138                    languages.clone(),
 5139                    &environment,
 5140                    weak.clone(),
 5141                    &worktree,
 5142                    http_client.clone(),
 5143                    fs.clone(),
 5144                    cx,
 5145                ))
 5146            }
 5147        };
 5148
 5149        let mut messages_to_report = Vec::new();
 5150        let (new_tree, to_stop) = {
 5151            let mut rebase = local.lsp_tree.rebase();
 5152            let buffers = buffer_store
 5153                .read(cx)
 5154                .buffers()
 5155                .filter_map(|buffer| {
 5156                    let raw_buffer = buffer.read(cx);
 5157                    if !local
 5158                        .registered_buffers
 5159                        .contains_key(&raw_buffer.remote_id())
 5160                    {
 5161                        return None;
 5162                    }
 5163                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5164                    let language = raw_buffer.language().cloned()?;
 5165                    Some((file, language, raw_buffer.remote_id()))
 5166                })
 5167                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5168            for (file, language, buffer_id) in buffers {
 5169                let worktree_id = file.worktree_id(cx);
 5170                let Some(worktree) = local
 5171                    .worktree_store
 5172                    .read(cx)
 5173                    .worktree_for_id(worktree_id, cx)
 5174                else {
 5175                    continue;
 5176                };
 5177
 5178                if let Some((_, apply)) = local.reuse_existing_language_server(
 5179                    rebase.server_tree(),
 5180                    &worktree,
 5181                    &language.name(),
 5182                    cx,
 5183                ) {
 5184                    (apply)(rebase.server_tree());
 5185                } else if let Some(lsp_delegate) = adapters
 5186                    .entry(worktree_id)
 5187                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5188                    .clone()
 5189                {
 5190                    let delegate =
 5191                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5192                    let path = file
 5193                        .path()
 5194                        .parent()
 5195                        .map(Arc::from)
 5196                        .unwrap_or_else(|| file.path().clone());
 5197                    let worktree_path = ProjectPath { worktree_id, path };
 5198                    let abs_path = file.abs_path(cx);
 5199                    let nodes = rebase
 5200                        .walk(
 5201                            worktree_path,
 5202                            language.name(),
 5203                            language.manifest(),
 5204                            delegate.clone(),
 5205                            cx,
 5206                        )
 5207                        .collect::<Vec<_>>();
 5208                    for node in nodes {
 5209                        let server_id = node.server_id_or_init(|disposition| {
 5210                            let path = &disposition.path;
 5211                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5212                            let key = LanguageServerSeed {
 5213                                worktree_id,
 5214                                name: disposition.server_name.clone(),
 5215                                settings: LanguageServerSeedSettings {
 5216                                    binary: disposition.settings.binary.clone(),
 5217                                    initialization_options: disposition
 5218                                        .settings
 5219                                        .initialization_options
 5220                                        .clone(),
 5221                                },
 5222                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5223                                    path.worktree_id,
 5224                                    &path.path,
 5225                                    language.name(),
 5226                                ),
 5227                            };
 5228                            local.language_server_ids.remove(&key);
 5229
 5230                            let server_id = local.get_or_insert_language_server(
 5231                                &worktree,
 5232                                lsp_delegate.clone(),
 5233                                disposition,
 5234                                &language.name(),
 5235                                cx,
 5236                            );
 5237                            if let Some(state) = local.language_servers.get(&server_id)
 5238                                && let Ok(uri) = uri
 5239                            {
 5240                                state.add_workspace_folder(uri);
 5241                            };
 5242                            server_id
 5243                        });
 5244
 5245                        if let Some(language_server_id) = server_id {
 5246                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5247                                language_server_id,
 5248                                name: node.name(),
 5249                                message:
 5250                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5251                                        proto::RegisteredForBuffer {
 5252                                            buffer_abs_path: abs_path
 5253                                                .to_string_lossy()
 5254                                                .into_owned(),
 5255                                            buffer_id: buffer_id.to_proto(),
 5256                                        },
 5257                                    ),
 5258                            });
 5259                        }
 5260                    }
 5261                } else {
 5262                    continue;
 5263                }
 5264            }
 5265            rebase.finish()
 5266        };
 5267        for message in messages_to_report {
 5268            cx.emit(message);
 5269        }
 5270        local.lsp_tree = new_tree;
 5271        for (id, _) in to_stop {
 5272            self.stop_local_language_server(id, cx).detach();
 5273        }
 5274    }
 5275
 5276    pub fn apply_code_action(
 5277        &self,
 5278        buffer_handle: Entity<Buffer>,
 5279        mut action: CodeAction,
 5280        push_to_history: bool,
 5281        cx: &mut Context<Self>,
 5282    ) -> Task<Result<ProjectTransaction>> {
 5283        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5284            let request = proto::ApplyCodeAction {
 5285                project_id,
 5286                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5287                action: Some(Self::serialize_code_action(&action)),
 5288            };
 5289            let buffer_store = self.buffer_store();
 5290            cx.spawn(async move |_, cx| {
 5291                let response = upstream_client
 5292                    .request(request)
 5293                    .await?
 5294                    .transaction
 5295                    .context("missing transaction")?;
 5296
 5297                buffer_store
 5298                    .update(cx, |buffer_store, cx| {
 5299                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5300                    })
 5301                    .await
 5302            })
 5303        } else if self.mode.is_local() {
 5304            let Some((_, lang_server, request_timeout)) = buffer_handle.update(cx, |buffer, cx| {
 5305                let request_timeout = ProjectSettings::get_global(cx)
 5306                    .global_lsp_settings
 5307                    .get_request_timeout();
 5308                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5309                    .map(|(adapter, server)| (adapter.clone(), server.clone(), request_timeout))
 5310            }) else {
 5311                return Task::ready(Ok(ProjectTransaction::default()));
 5312            };
 5313
 5314            cx.spawn(async move |this, cx| {
 5315                LocalLspStore::try_resolve_code_action(&lang_server, &mut action, request_timeout)
 5316                    .await
 5317                    .context("resolving a code action")?;
 5318                if let Some(edit) = action.lsp_action.edit()
 5319                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5320                        return LocalLspStore::deserialize_workspace_edit(
 5321                            this.upgrade().context("no app present")?,
 5322                            edit.clone(),
 5323                            push_to_history,
 5324
 5325                            lang_server.clone(),
 5326                            cx,
 5327                        )
 5328                        .await;
 5329                    }
 5330
 5331                let Some(command) = action.lsp_action.command() else {
 5332                    return Ok(ProjectTransaction::default())
 5333                };
 5334
 5335                let server_capabilities = lang_server.capabilities();
 5336                let available_commands = server_capabilities
 5337                    .execute_command_provider
 5338                    .as_ref()
 5339                    .map(|options| options.commands.as_slice())
 5340                    .unwrap_or_default();
 5341
 5342                if !available_commands.contains(&command.command) {
 5343                    log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5344                    return Ok(ProjectTransaction::default())
 5345                }
 5346
 5347                let request_timeout = cx.update(|app|
 5348                    ProjectSettings::get_global(app)
 5349                    .global_lsp_settings
 5350                    .get_request_timeout()
 5351                );
 5352
 5353                this.update(cx, |this, _| {
 5354                    this.as_local_mut()
 5355                        .unwrap()
 5356                        .last_workspace_edits_by_language_server
 5357                        .remove(&lang_server.server_id());
 5358                })?;
 5359
 5360                let _result = lang_server
 5361                    .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5362                        command: command.command.clone(),
 5363                        arguments: command.arguments.clone().unwrap_or_default(),
 5364                        ..lsp::ExecuteCommandParams::default()
 5365                    }, request_timeout)
 5366                    .await.into_response()
 5367                    .context("execute command")?;
 5368
 5369                return this.update(cx, |this, _| {
 5370                    this.as_local_mut()
 5371                        .unwrap()
 5372                        .last_workspace_edits_by_language_server
 5373                        .remove(&lang_server.server_id())
 5374                        .unwrap_or_default()
 5375                });
 5376            })
 5377        } else {
 5378            Task::ready(Err(anyhow!("no upstream client and not local")))
 5379        }
 5380    }
 5381
 5382    pub fn apply_code_action_kind(
 5383        &mut self,
 5384        buffers: HashSet<Entity<Buffer>>,
 5385        kind: CodeActionKind,
 5386        push_to_history: bool,
 5387        cx: &mut Context<Self>,
 5388    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5389        if self.as_local().is_some() {
 5390            cx.spawn(async move |lsp_store, cx| {
 5391                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5392                let result = LocalLspStore::execute_code_action_kind_locally(
 5393                    lsp_store.clone(),
 5394                    buffers,
 5395                    kind,
 5396                    push_to_history,
 5397                    cx,
 5398                )
 5399                .await;
 5400                lsp_store.update(cx, |lsp_store, _| {
 5401                    lsp_store.update_last_formatting_failure(&result);
 5402                })?;
 5403                result
 5404            })
 5405        } else if let Some((client, project_id)) = self.upstream_client() {
 5406            let buffer_store = self.buffer_store();
 5407            cx.spawn(async move |lsp_store, cx| {
 5408                let result = client
 5409                    .request(proto::ApplyCodeActionKind {
 5410                        project_id,
 5411                        kind: kind.as_str().to_owned(),
 5412                        buffer_ids: buffers
 5413                            .iter()
 5414                            .map(|buffer| {
 5415                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5416                            })
 5417                            .collect(),
 5418                    })
 5419                    .await
 5420                    .and_then(|result| result.transaction.context("missing transaction"));
 5421                lsp_store.update(cx, |lsp_store, _| {
 5422                    lsp_store.update_last_formatting_failure(&result);
 5423                })?;
 5424
 5425                let transaction_response = result?;
 5426                buffer_store
 5427                    .update(cx, |buffer_store, cx| {
 5428                        buffer_store.deserialize_project_transaction(
 5429                            transaction_response,
 5430                            push_to_history,
 5431                            cx,
 5432                        )
 5433                    })
 5434                    .await
 5435            })
 5436        } else {
 5437            Task::ready(Ok(ProjectTransaction::default()))
 5438        }
 5439    }
 5440
 5441    pub fn resolved_hint(
 5442        &mut self,
 5443        buffer_id: BufferId,
 5444        id: InlayId,
 5445        cx: &mut Context<Self>,
 5446    ) -> Option<ResolvedHint> {
 5447        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5448
 5449        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5450        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5451        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5452        let (server_id, resolve_data) = match &hint.resolve_state {
 5453            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5454            ResolveState::Resolving => {
 5455                return Some(ResolvedHint::Resolving(
 5456                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5457                ));
 5458            }
 5459            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5460        };
 5461
 5462        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5463        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5464        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5465            id,
 5466            cx.spawn(async move |lsp_store, cx| {
 5467                let resolved_hint = resolve_task.await;
 5468                lsp_store
 5469                    .update(cx, |lsp_store, _| {
 5470                        if let Some(old_inlay_hint) = lsp_store
 5471                            .lsp_data
 5472                            .get_mut(&buffer_id)
 5473                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5474                        {
 5475                            match resolved_hint {
 5476                                Ok(resolved_hint) => {
 5477                                    *old_inlay_hint = resolved_hint;
 5478                                }
 5479                                Err(e) => {
 5480                                    old_inlay_hint.resolve_state =
 5481                                        ResolveState::CanResolve(server_id, resolve_data);
 5482                                    log::error!("Inlay hint resolve failed: {e:#}");
 5483                                }
 5484                            }
 5485                        }
 5486                    })
 5487                    .ok();
 5488            })
 5489            .shared(),
 5490        );
 5491        debug_assert!(
 5492            previous_task.is_none(),
 5493            "Did not change hint's resolve state after spawning its resolve"
 5494        );
 5495        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5496        None
 5497    }
 5498
 5499    pub(crate) fn linked_edits(
 5500        &mut self,
 5501        buffer: &Entity<Buffer>,
 5502        position: Anchor,
 5503        cx: &mut Context<Self>,
 5504    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5505        let snapshot = buffer.read(cx).snapshot();
 5506        let scope = snapshot.language_scope_at(position);
 5507        let Some(server_id) = self
 5508            .as_local()
 5509            .and_then(|local| {
 5510                buffer.update(cx, |buffer, cx| {
 5511                    local
 5512                        .language_servers_for_buffer(buffer, cx)
 5513                        .filter(|(_, server)| {
 5514                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5515                        })
 5516                        .filter(|(adapter, _)| {
 5517                            scope
 5518                                .as_ref()
 5519                                .map(|scope| scope.language_allowed(&adapter.name))
 5520                                .unwrap_or(true)
 5521                        })
 5522                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5523                        .next()
 5524                })
 5525            })
 5526            .or_else(|| {
 5527                self.upstream_client()
 5528                    .is_some()
 5529                    .then_some(LanguageServerToQuery::FirstCapable)
 5530            })
 5531            .filter(|_| {
 5532                maybe!({
 5533                    let language = buffer.read(cx).language_at(position)?;
 5534                    Some(
 5535                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5536                            .linked_edits,
 5537                    )
 5538                }) == Some(true)
 5539            })
 5540        else {
 5541            return Task::ready(Ok(Vec::new()));
 5542        };
 5543
 5544        self.request_lsp(
 5545            buffer.clone(),
 5546            server_id,
 5547            LinkedEditingRange { position },
 5548            cx,
 5549        )
 5550    }
 5551
 5552    fn apply_on_type_formatting(
 5553        &mut self,
 5554        buffer: Entity<Buffer>,
 5555        position: Anchor,
 5556        trigger: String,
 5557        cx: &mut Context<Self>,
 5558    ) -> Task<Result<Option<Transaction>>> {
 5559        if let Some((client, project_id)) = self.upstream_client() {
 5560            if !self.check_if_capable_for_proto_request(
 5561                &buffer,
 5562                |capabilities| {
 5563                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5564                },
 5565                cx,
 5566            ) {
 5567                return Task::ready(Ok(None));
 5568            }
 5569            let request = proto::OnTypeFormatting {
 5570                project_id,
 5571                buffer_id: buffer.read(cx).remote_id().into(),
 5572                position: Some(serialize_anchor(&position)),
 5573                trigger,
 5574                version: serialize_version(&buffer.read(cx).version()),
 5575            };
 5576            cx.background_spawn(async move {
 5577                client
 5578                    .request(request)
 5579                    .await?
 5580                    .transaction
 5581                    .map(language::proto::deserialize_transaction)
 5582                    .transpose()
 5583            })
 5584        } else if let Some(local) = self.as_local_mut() {
 5585            let buffer_id = buffer.read(cx).remote_id();
 5586            local.buffers_being_formatted.insert(buffer_id);
 5587            cx.spawn(async move |this, cx| {
 5588                let _cleanup = defer({
 5589                    let this = this.clone();
 5590                    let mut cx = cx.clone();
 5591                    move || {
 5592                        this.update(&mut cx, |this, _| {
 5593                            if let Some(local) = this.as_local_mut() {
 5594                                local.buffers_being_formatted.remove(&buffer_id);
 5595                            }
 5596                        })
 5597                        .ok();
 5598                    }
 5599                });
 5600
 5601                buffer
 5602                    .update(cx, |buffer, _| {
 5603                        buffer.wait_for_edits(Some(position.timestamp()))
 5604                    })
 5605                    .await?;
 5606                this.update(cx, |this, cx| {
 5607                    let position = position.to_point_utf16(buffer.read(cx));
 5608                    this.on_type_format(buffer, position, trigger, false, cx)
 5609                })?
 5610                .await
 5611            })
 5612        } else {
 5613            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5614        }
 5615    }
 5616
 5617    pub fn on_type_format<T: ToPointUtf16>(
 5618        &mut self,
 5619        buffer: Entity<Buffer>,
 5620        position: T,
 5621        trigger: String,
 5622        push_to_history: bool,
 5623        cx: &mut Context<Self>,
 5624    ) -> Task<Result<Option<Transaction>>> {
 5625        let position = position.to_point_utf16(buffer.read(cx));
 5626        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5627    }
 5628
 5629    fn on_type_format_impl(
 5630        &mut self,
 5631        buffer: Entity<Buffer>,
 5632        position: PointUtf16,
 5633        trigger: String,
 5634        push_to_history: bool,
 5635        cx: &mut Context<Self>,
 5636    ) -> Task<Result<Option<Transaction>>> {
 5637        let options = buffer.update(cx, |buffer, cx| {
 5638            lsp_command::lsp_formatting_options(
 5639                language_settings(
 5640                    buffer.language_at(position).map(|l| l.name()),
 5641                    buffer.file(),
 5642                    cx,
 5643                )
 5644                .as_ref(),
 5645            )
 5646        });
 5647
 5648        cx.spawn(async move |this, cx| {
 5649            if let Some(waiter) =
 5650                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5651            {
 5652                waiter.await?;
 5653            }
 5654            cx.update(|cx| {
 5655                this.update(cx, |this, cx| {
 5656                    this.request_lsp(
 5657                        buffer.clone(),
 5658                        LanguageServerToQuery::FirstCapable,
 5659                        OnTypeFormatting {
 5660                            position,
 5661                            trigger,
 5662                            options,
 5663                            push_to_history,
 5664                        },
 5665                        cx,
 5666                    )
 5667                })
 5668            })?
 5669            .await
 5670        })
 5671    }
 5672
 5673    pub fn definitions(
 5674        &mut self,
 5675        buffer: &Entity<Buffer>,
 5676        position: PointUtf16,
 5677        cx: &mut Context<Self>,
 5678    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5679        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5680            let request = GetDefinitions { position };
 5681            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5682                return Task::ready(Ok(None));
 5683            }
 5684
 5685            let request_timeout = ProjectSettings::get_global(cx)
 5686                .global_lsp_settings
 5687                .get_request_timeout();
 5688
 5689            let request_task = upstream_client.request_lsp(
 5690                project_id,
 5691                None,
 5692                request_timeout,
 5693                cx.background_executor().clone(),
 5694                request.to_proto(project_id, buffer.read(cx)),
 5695            );
 5696            let buffer = buffer.clone();
 5697            cx.spawn(async move |weak_lsp_store, cx| {
 5698                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5699                    return Ok(None);
 5700                };
 5701                let Some(responses) = request_task.await? else {
 5702                    return Ok(None);
 5703                };
 5704                let actions = join_all(responses.payload.into_iter().map(|response| {
 5705                    GetDefinitions { position }.response_from_proto(
 5706                        response.response,
 5707                        lsp_store.clone(),
 5708                        buffer.clone(),
 5709                        cx.clone(),
 5710                    )
 5711                }))
 5712                .await;
 5713
 5714                Ok(Some(
 5715                    actions
 5716                        .into_iter()
 5717                        .collect::<Result<Vec<Vec<_>>>>()?
 5718                        .into_iter()
 5719                        .flatten()
 5720                        .dedup()
 5721                        .collect(),
 5722                ))
 5723            })
 5724        } else {
 5725            let definitions_task = self.request_multiple_lsp_locally(
 5726                buffer,
 5727                Some(position),
 5728                GetDefinitions { position },
 5729                cx,
 5730            );
 5731            cx.background_spawn(async move {
 5732                Ok(Some(
 5733                    definitions_task
 5734                        .await
 5735                        .into_iter()
 5736                        .flat_map(|(_, definitions)| definitions)
 5737                        .dedup()
 5738                        .collect(),
 5739                ))
 5740            })
 5741        }
 5742    }
 5743
 5744    pub fn declarations(
 5745        &mut self,
 5746        buffer: &Entity<Buffer>,
 5747        position: PointUtf16,
 5748        cx: &mut Context<Self>,
 5749    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5750        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5751            let request = GetDeclarations { position };
 5752            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5753                return Task::ready(Ok(None));
 5754            }
 5755            let request_timeout = ProjectSettings::get_global(cx)
 5756                .global_lsp_settings
 5757                .get_request_timeout();
 5758            let request_task = upstream_client.request_lsp(
 5759                project_id,
 5760                None,
 5761                request_timeout,
 5762                cx.background_executor().clone(),
 5763                request.to_proto(project_id, buffer.read(cx)),
 5764            );
 5765            let buffer = buffer.clone();
 5766            cx.spawn(async move |weak_lsp_store, cx| {
 5767                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5768                    return Ok(None);
 5769                };
 5770                let Some(responses) = request_task.await? else {
 5771                    return Ok(None);
 5772                };
 5773                let actions = join_all(responses.payload.into_iter().map(|response| {
 5774                    GetDeclarations { position }.response_from_proto(
 5775                        response.response,
 5776                        lsp_store.clone(),
 5777                        buffer.clone(),
 5778                        cx.clone(),
 5779                    )
 5780                }))
 5781                .await;
 5782
 5783                Ok(Some(
 5784                    actions
 5785                        .into_iter()
 5786                        .collect::<Result<Vec<Vec<_>>>>()?
 5787                        .into_iter()
 5788                        .flatten()
 5789                        .dedup()
 5790                        .collect(),
 5791                ))
 5792            })
 5793        } else {
 5794            let declarations_task = self.request_multiple_lsp_locally(
 5795                buffer,
 5796                Some(position),
 5797                GetDeclarations { position },
 5798                cx,
 5799            );
 5800            cx.background_spawn(async move {
 5801                Ok(Some(
 5802                    declarations_task
 5803                        .await
 5804                        .into_iter()
 5805                        .flat_map(|(_, declarations)| declarations)
 5806                        .dedup()
 5807                        .collect(),
 5808                ))
 5809            })
 5810        }
 5811    }
 5812
 5813    pub fn type_definitions(
 5814        &mut self,
 5815        buffer: &Entity<Buffer>,
 5816        position: PointUtf16,
 5817        cx: &mut Context<Self>,
 5818    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5819        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5820            let request = GetTypeDefinitions { position };
 5821            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5822                return Task::ready(Ok(None));
 5823            }
 5824            let request_timeout = ProjectSettings::get_global(cx)
 5825                .global_lsp_settings
 5826                .get_request_timeout();
 5827            let request_task = upstream_client.request_lsp(
 5828                project_id,
 5829                None,
 5830                request_timeout,
 5831                cx.background_executor().clone(),
 5832                request.to_proto(project_id, buffer.read(cx)),
 5833            );
 5834            let buffer = buffer.clone();
 5835            cx.spawn(async move |weak_lsp_store, cx| {
 5836                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5837                    return Ok(None);
 5838                };
 5839                let Some(responses) = request_task.await? else {
 5840                    return Ok(None);
 5841                };
 5842                let actions = join_all(responses.payload.into_iter().map(|response| {
 5843                    GetTypeDefinitions { position }.response_from_proto(
 5844                        response.response,
 5845                        lsp_store.clone(),
 5846                        buffer.clone(),
 5847                        cx.clone(),
 5848                    )
 5849                }))
 5850                .await;
 5851
 5852                Ok(Some(
 5853                    actions
 5854                        .into_iter()
 5855                        .collect::<Result<Vec<Vec<_>>>>()?
 5856                        .into_iter()
 5857                        .flatten()
 5858                        .dedup()
 5859                        .collect(),
 5860                ))
 5861            })
 5862        } else {
 5863            let type_definitions_task = self.request_multiple_lsp_locally(
 5864                buffer,
 5865                Some(position),
 5866                GetTypeDefinitions { position },
 5867                cx,
 5868            );
 5869            cx.background_spawn(async move {
 5870                Ok(Some(
 5871                    type_definitions_task
 5872                        .await
 5873                        .into_iter()
 5874                        .flat_map(|(_, type_definitions)| type_definitions)
 5875                        .dedup()
 5876                        .collect(),
 5877                ))
 5878            })
 5879        }
 5880    }
 5881
 5882    pub fn implementations(
 5883        &mut self,
 5884        buffer: &Entity<Buffer>,
 5885        position: PointUtf16,
 5886        cx: &mut Context<Self>,
 5887    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5888        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5889            let request = GetImplementations { position };
 5890            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5891                return Task::ready(Ok(None));
 5892            }
 5893
 5894            let request_timeout = ProjectSettings::get_global(cx)
 5895                .global_lsp_settings
 5896                .get_request_timeout();
 5897            let request_task = upstream_client.request_lsp(
 5898                project_id,
 5899                None,
 5900                request_timeout,
 5901                cx.background_executor().clone(),
 5902                request.to_proto(project_id, buffer.read(cx)),
 5903            );
 5904            let buffer = buffer.clone();
 5905            cx.spawn(async move |weak_lsp_store, cx| {
 5906                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5907                    return Ok(None);
 5908                };
 5909                let Some(responses) = request_task.await? else {
 5910                    return Ok(None);
 5911                };
 5912                let actions = join_all(responses.payload.into_iter().map(|response| {
 5913                    GetImplementations { position }.response_from_proto(
 5914                        response.response,
 5915                        lsp_store.clone(),
 5916                        buffer.clone(),
 5917                        cx.clone(),
 5918                    )
 5919                }))
 5920                .await;
 5921
 5922                Ok(Some(
 5923                    actions
 5924                        .into_iter()
 5925                        .collect::<Result<Vec<Vec<_>>>>()?
 5926                        .into_iter()
 5927                        .flatten()
 5928                        .dedup()
 5929                        .collect(),
 5930                ))
 5931            })
 5932        } else {
 5933            let implementations_task = self.request_multiple_lsp_locally(
 5934                buffer,
 5935                Some(position),
 5936                GetImplementations { position },
 5937                cx,
 5938            );
 5939            cx.background_spawn(async move {
 5940                Ok(Some(
 5941                    implementations_task
 5942                        .await
 5943                        .into_iter()
 5944                        .flat_map(|(_, implementations)| implementations)
 5945                        .dedup()
 5946                        .collect(),
 5947                ))
 5948            })
 5949        }
 5950    }
 5951
 5952    pub fn references(
 5953        &mut self,
 5954        buffer: &Entity<Buffer>,
 5955        position: PointUtf16,
 5956        cx: &mut Context<Self>,
 5957    ) -> Task<Result<Option<Vec<Location>>>> {
 5958        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5959            let request = GetReferences { position };
 5960            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5961                return Task::ready(Ok(None));
 5962            }
 5963
 5964            let request_timeout = ProjectSettings::get_global(cx)
 5965                .global_lsp_settings
 5966                .get_request_timeout();
 5967            let request_task = upstream_client.request_lsp(
 5968                project_id,
 5969                None,
 5970                request_timeout,
 5971                cx.background_executor().clone(),
 5972                request.to_proto(project_id, buffer.read(cx)),
 5973            );
 5974            let buffer = buffer.clone();
 5975            cx.spawn(async move |weak_lsp_store, cx| {
 5976                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5977                    return Ok(None);
 5978                };
 5979                let Some(responses) = request_task.await? else {
 5980                    return Ok(None);
 5981                };
 5982
 5983                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5984                    GetReferences { position }.response_from_proto(
 5985                        lsp_response.response,
 5986                        lsp_store.clone(),
 5987                        buffer.clone(),
 5988                        cx.clone(),
 5989                    )
 5990                }))
 5991                .await
 5992                .into_iter()
 5993                .collect::<Result<Vec<Vec<_>>>>()?
 5994                .into_iter()
 5995                .flatten()
 5996                .dedup()
 5997                .collect();
 5998                Ok(Some(locations))
 5999            })
 6000        } else {
 6001            let references_task = self.request_multiple_lsp_locally(
 6002                buffer,
 6003                Some(position),
 6004                GetReferences { position },
 6005                cx,
 6006            );
 6007            cx.background_spawn(async move {
 6008                Ok(Some(
 6009                    references_task
 6010                        .await
 6011                        .into_iter()
 6012                        .flat_map(|(_, references)| references)
 6013                        .dedup()
 6014                        .collect(),
 6015                ))
 6016            })
 6017        }
 6018    }
 6019
 6020    pub fn code_actions(
 6021        &mut self,
 6022        buffer: &Entity<Buffer>,
 6023        range: Range<Anchor>,
 6024        kinds: Option<Vec<CodeActionKind>>,
 6025        cx: &mut Context<Self>,
 6026    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6027        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6028            let request = GetCodeActions {
 6029                range: range.clone(),
 6030                kinds: kinds.clone(),
 6031            };
 6032            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6033                return Task::ready(Ok(None));
 6034            }
 6035            let request_timeout = ProjectSettings::get_global(cx)
 6036                .global_lsp_settings
 6037                .get_request_timeout();
 6038            let request_task = upstream_client.request_lsp(
 6039                project_id,
 6040                None,
 6041                request_timeout,
 6042                cx.background_executor().clone(),
 6043                request.to_proto(project_id, buffer.read(cx)),
 6044            );
 6045            let buffer = buffer.clone();
 6046            cx.spawn(async move |weak_lsp_store, cx| {
 6047                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6048                    return Ok(None);
 6049                };
 6050                let Some(responses) = request_task.await? else {
 6051                    return Ok(None);
 6052                };
 6053                let actions = join_all(responses.payload.into_iter().map(|response| {
 6054                    GetCodeActions {
 6055                        range: range.clone(),
 6056                        kinds: kinds.clone(),
 6057                    }
 6058                    .response_from_proto(
 6059                        response.response,
 6060                        lsp_store.clone(),
 6061                        buffer.clone(),
 6062                        cx.clone(),
 6063                    )
 6064                }))
 6065                .await;
 6066
 6067                Ok(Some(
 6068                    actions
 6069                        .into_iter()
 6070                        .collect::<Result<Vec<Vec<_>>>>()?
 6071                        .into_iter()
 6072                        .flatten()
 6073                        .collect(),
 6074                ))
 6075            })
 6076        } else {
 6077            let all_actions_task = self.request_multiple_lsp_locally(
 6078                buffer,
 6079                Some(range.start),
 6080                GetCodeActions { range, kinds },
 6081                cx,
 6082            );
 6083            cx.background_spawn(async move {
 6084                Ok(Some(
 6085                    all_actions_task
 6086                        .await
 6087                        .into_iter()
 6088                        .flat_map(|(_, actions)| actions)
 6089                        .collect(),
 6090                ))
 6091            })
 6092        }
 6093    }
 6094
 6095    #[inline(never)]
 6096    pub fn completions(
 6097        &self,
 6098        buffer: &Entity<Buffer>,
 6099        position: PointUtf16,
 6100        context: CompletionContext,
 6101        cx: &mut Context<Self>,
 6102    ) -> Task<Result<Vec<CompletionResponse>>> {
 6103        let language_registry = self.languages.clone();
 6104
 6105        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6106            let snapshot = buffer.read(cx).snapshot();
 6107            let offset = position.to_offset(&snapshot);
 6108            let scope = snapshot.language_scope_at(offset);
 6109            let capable_lsps = self.all_capable_for_proto_request(
 6110                buffer,
 6111                |server_name, capabilities| {
 6112                    capabilities.completion_provider.is_some()
 6113                        && scope
 6114                            .as_ref()
 6115                            .map(|scope| scope.language_allowed(server_name))
 6116                            .unwrap_or(true)
 6117                },
 6118                cx,
 6119            );
 6120            if capable_lsps.is_empty() {
 6121                return Task::ready(Ok(Vec::new()));
 6122            }
 6123
 6124            let language = buffer.read(cx).language().cloned();
 6125
 6126            // In the future, we should provide project guests with the names of LSP adapters,
 6127            // so that they can use the correct LSP adapter when computing labels. For now,
 6128            // guests just use the first LSP adapter associated with the buffer's language.
 6129            let lsp_adapter = language.as_ref().and_then(|language| {
 6130                language_registry
 6131                    .lsp_adapters(&language.name())
 6132                    .first()
 6133                    .cloned()
 6134            });
 6135
 6136            let buffer = buffer.clone();
 6137
 6138            cx.spawn(async move |this, cx| {
 6139                let requests = join_all(
 6140                    capable_lsps
 6141                        .into_iter()
 6142                        .map(|id| {
 6143                            let request = GetCompletions {
 6144                                position,
 6145                                context: context.clone(),
 6146                                server_id: Some(id),
 6147                            };
 6148                            let buffer = buffer.clone();
 6149                            let language = language.clone();
 6150                            let lsp_adapter = lsp_adapter.clone();
 6151                            let upstream_client = upstream_client.clone();
 6152                            let response = this
 6153                                .update(cx, |this, cx| {
 6154                                    this.send_lsp_proto_request(
 6155                                        buffer,
 6156                                        upstream_client,
 6157                                        project_id,
 6158                                        request,
 6159                                        cx,
 6160                                    )
 6161                                })
 6162                                .log_err();
 6163                            async move {
 6164                                let response = response?.await.log_err()?;
 6165
 6166                                let completions = populate_labels_for_completions(
 6167                                    response.completions,
 6168                                    language,
 6169                                    lsp_adapter,
 6170                                )
 6171                                .await;
 6172
 6173                                Some(CompletionResponse {
 6174                                    completions,
 6175                                    display_options: CompletionDisplayOptions::default(),
 6176                                    is_incomplete: response.is_incomplete,
 6177                                })
 6178                            }
 6179                        })
 6180                        .collect::<Vec<_>>(),
 6181                );
 6182                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6183            })
 6184        } else if let Some(local) = self.as_local() {
 6185            let snapshot = buffer.read(cx).snapshot();
 6186            let offset = position.to_offset(&snapshot);
 6187            let scope = snapshot.language_scope_at(offset);
 6188            let language = snapshot.language().cloned();
 6189            let completion_settings = language_settings(
 6190                language.as_ref().map(|language| language.name()),
 6191                buffer.read(cx).file(),
 6192                cx,
 6193            )
 6194            .completions
 6195            .clone();
 6196            if !completion_settings.lsp {
 6197                return Task::ready(Ok(Vec::new()));
 6198            }
 6199
 6200            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6201                local
 6202                    .language_servers_for_buffer(buffer, cx)
 6203                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6204                    .filter(|(adapter, _)| {
 6205                        scope
 6206                            .as_ref()
 6207                            .map(|scope| scope.language_allowed(&adapter.name))
 6208                            .unwrap_or(true)
 6209                    })
 6210                    .map(|(_, server)| server.server_id())
 6211                    .collect()
 6212            });
 6213
 6214            let buffer = buffer.clone();
 6215            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6216            let lsp_timeout = if lsp_timeout > 0 {
 6217                Some(Duration::from_millis(lsp_timeout))
 6218            } else {
 6219                None
 6220            };
 6221            cx.spawn(async move |this,  cx| {
 6222                let mut tasks = Vec::with_capacity(server_ids.len());
 6223                this.update(cx, |lsp_store, cx| {
 6224                    for server_id in server_ids {
 6225                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6226                        let lsp_timeout = lsp_timeout
 6227                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6228                        let mut timeout = cx.background_spawn(async move {
 6229                            match lsp_timeout {
 6230                                Some(lsp_timeout) => {
 6231                                    lsp_timeout.await;
 6232                                    true
 6233                                },
 6234                                None => false,
 6235                            }
 6236                        }).fuse();
 6237                        let mut lsp_request = lsp_store.request_lsp(
 6238                            buffer.clone(),
 6239                            LanguageServerToQuery::Other(server_id),
 6240                            GetCompletions {
 6241                                position,
 6242                                context: context.clone(),
 6243                                server_id: Some(server_id),
 6244                            },
 6245                            cx,
 6246                        ).fuse();
 6247                        let new_task = cx.background_spawn(async move {
 6248                            select_biased! {
 6249                                response = lsp_request => anyhow::Ok(Some(response?)),
 6250                                timeout_happened = timeout => {
 6251                                    if timeout_happened {
 6252                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6253                                        Ok(None)
 6254                                    } else {
 6255                                        let completions = lsp_request.await?;
 6256                                        Ok(Some(completions))
 6257                                    }
 6258                                },
 6259                            }
 6260                        });
 6261                        tasks.push((lsp_adapter, new_task));
 6262                    }
 6263                })?;
 6264
 6265                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6266                    let completion_response = task.await.ok()??;
 6267                    let completions = populate_labels_for_completions(
 6268                            completion_response.completions,
 6269                            language.clone(),
 6270                            lsp_adapter,
 6271                        )
 6272                        .await;
 6273                    Some(CompletionResponse {
 6274                        completions,
 6275                        display_options: CompletionDisplayOptions::default(),
 6276                        is_incomplete: completion_response.is_incomplete,
 6277                    })
 6278                });
 6279
 6280                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6281
 6282                Ok(responses.into_iter().flatten().collect())
 6283            })
 6284        } else {
 6285            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6286        }
 6287    }
 6288
 6289    pub fn resolve_completions(
 6290        &self,
 6291        buffer: Entity<Buffer>,
 6292        completion_indices: Vec<usize>,
 6293        completions: Rc<RefCell<Box<[Completion]>>>,
 6294        cx: &mut Context<Self>,
 6295    ) -> Task<Result<bool>> {
 6296        let client = self.upstream_client();
 6297        let buffer_id = buffer.read(cx).remote_id();
 6298        let buffer_snapshot = buffer.read(cx).snapshot();
 6299
 6300        if !self.check_if_capable_for_proto_request(
 6301            &buffer,
 6302            GetCompletions::can_resolve_completions,
 6303            cx,
 6304        ) {
 6305            return Task::ready(Ok(false));
 6306        }
 6307        cx.spawn(async move |lsp_store, cx| {
 6308            let request_timeout = cx.update(|app| {
 6309                ProjectSettings::get_global(app)
 6310                    .global_lsp_settings
 6311                    .get_request_timeout()
 6312            });
 6313
 6314            let mut did_resolve = false;
 6315            if let Some((client, project_id)) = client {
 6316                for completion_index in completion_indices {
 6317                    let server_id = {
 6318                        let completion = &completions.borrow()[completion_index];
 6319                        completion.source.server_id()
 6320                    };
 6321                    if let Some(server_id) = server_id {
 6322                        if Self::resolve_completion_remote(
 6323                            project_id,
 6324                            server_id,
 6325                            buffer_id,
 6326                            completions.clone(),
 6327                            completion_index,
 6328                            client.clone(),
 6329                        )
 6330                        .await
 6331                        .log_err()
 6332                        .is_some()
 6333                        {
 6334                            did_resolve = true;
 6335                        }
 6336                    } else {
 6337                        resolve_word_completion(
 6338                            &buffer_snapshot,
 6339                            &mut completions.borrow_mut()[completion_index],
 6340                        );
 6341                    }
 6342                }
 6343            } else {
 6344                for completion_index in completion_indices {
 6345                    let server_id = {
 6346                        let completion = &completions.borrow()[completion_index];
 6347                        completion.source.server_id()
 6348                    };
 6349                    if let Some(server_id) = server_id {
 6350                        let server_and_adapter = lsp_store
 6351                            .read_with(cx, |lsp_store, _| {
 6352                                let server = lsp_store.language_server_for_id(server_id)?;
 6353                                let adapter =
 6354                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6355                                Some((server, adapter))
 6356                            })
 6357                            .ok()
 6358                            .flatten();
 6359                        let Some((server, adapter)) = server_and_adapter else {
 6360                            continue;
 6361                        };
 6362
 6363                        let resolved = Self::resolve_completion_local(
 6364                            server,
 6365                            completions.clone(),
 6366                            completion_index,
 6367                            request_timeout,
 6368                        )
 6369                        .await
 6370                        .log_err()
 6371                        .is_some();
 6372                        if resolved {
 6373                            Self::regenerate_completion_labels(
 6374                                adapter,
 6375                                &buffer_snapshot,
 6376                                completions.clone(),
 6377                                completion_index,
 6378                            )
 6379                            .await
 6380                            .log_err();
 6381                            did_resolve = true;
 6382                        }
 6383                    } else {
 6384                        resolve_word_completion(
 6385                            &buffer_snapshot,
 6386                            &mut completions.borrow_mut()[completion_index],
 6387                        );
 6388                    }
 6389                }
 6390            }
 6391
 6392            Ok(did_resolve)
 6393        })
 6394    }
 6395
 6396    async fn resolve_completion_local(
 6397        server: Arc<lsp::LanguageServer>,
 6398        completions: Rc<RefCell<Box<[Completion]>>>,
 6399        completion_index: usize,
 6400        request_timeout: Duration,
 6401    ) -> Result<()> {
 6402        let server_id = server.server_id();
 6403        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6404            return Ok(());
 6405        }
 6406
 6407        let request = {
 6408            let completion = &completions.borrow()[completion_index];
 6409            match &completion.source {
 6410                CompletionSource::Lsp {
 6411                    lsp_completion,
 6412                    resolved,
 6413                    server_id: completion_server_id,
 6414                    ..
 6415                } => {
 6416                    if *resolved {
 6417                        return Ok(());
 6418                    }
 6419                    anyhow::ensure!(
 6420                        server_id == *completion_server_id,
 6421                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6422                    );
 6423                    server.request::<lsp::request::ResolveCompletionItem>(
 6424                        *lsp_completion.clone(),
 6425                        request_timeout,
 6426                    )
 6427                }
 6428                CompletionSource::BufferWord { .. }
 6429                | CompletionSource::Dap { .. }
 6430                | CompletionSource::Custom => {
 6431                    return Ok(());
 6432                }
 6433            }
 6434        };
 6435        let resolved_completion = request
 6436            .await
 6437            .into_response()
 6438            .context("resolve completion")?;
 6439
 6440        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6441        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6442
 6443        let mut completions = completions.borrow_mut();
 6444        let completion = &mut completions[completion_index];
 6445        if let CompletionSource::Lsp {
 6446            lsp_completion,
 6447            resolved,
 6448            server_id: completion_server_id,
 6449            ..
 6450        } = &mut completion.source
 6451        {
 6452            if *resolved {
 6453                return Ok(());
 6454            }
 6455            anyhow::ensure!(
 6456                server_id == *completion_server_id,
 6457                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6458            );
 6459            **lsp_completion = resolved_completion;
 6460            *resolved = true;
 6461        }
 6462        Ok(())
 6463    }
 6464
 6465    async fn regenerate_completion_labels(
 6466        adapter: Arc<CachedLspAdapter>,
 6467        snapshot: &BufferSnapshot,
 6468        completions: Rc<RefCell<Box<[Completion]>>>,
 6469        completion_index: usize,
 6470    ) -> Result<()> {
 6471        let completion_item = completions.borrow()[completion_index]
 6472            .source
 6473            .lsp_completion(true)
 6474            .map(Cow::into_owned);
 6475        if let Some(lsp_documentation) = completion_item
 6476            .as_ref()
 6477            .and_then(|completion_item| completion_item.documentation.clone())
 6478        {
 6479            let mut completions = completions.borrow_mut();
 6480            let completion = &mut completions[completion_index];
 6481            completion.documentation = Some(lsp_documentation.into());
 6482        } else {
 6483            let mut completions = completions.borrow_mut();
 6484            let completion = &mut completions[completion_index];
 6485            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6486        }
 6487
 6488        let mut new_label = match completion_item {
 6489            Some(completion_item) => {
 6490                // Some language servers always return `detail` lazily via resolve, regardless of
 6491                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6492                // See: https://github.com/yioneko/vtsls/issues/213
 6493                let language = snapshot.language();
 6494                match language {
 6495                    Some(language) => {
 6496                        adapter
 6497                            .labels_for_completions(
 6498                                std::slice::from_ref(&completion_item),
 6499                                language,
 6500                            )
 6501                            .await?
 6502                    }
 6503                    None => Vec::new(),
 6504                }
 6505                .pop()
 6506                .flatten()
 6507                .unwrap_or_else(|| {
 6508                    CodeLabel::fallback_for_completion(
 6509                        &completion_item,
 6510                        language.map(|language| language.as_ref()),
 6511                    )
 6512                })
 6513            }
 6514            None => CodeLabel::plain(
 6515                completions.borrow()[completion_index].new_text.clone(),
 6516                None,
 6517            ),
 6518        };
 6519        ensure_uniform_list_compatible_label(&mut new_label);
 6520
 6521        let mut completions = completions.borrow_mut();
 6522        let completion = &mut completions[completion_index];
 6523        if completion.label.filter_text() == new_label.filter_text() {
 6524            completion.label = new_label;
 6525        } else {
 6526            log::error!(
 6527                "Resolved completion changed display label from {} to {}. \
 6528                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6529                completion.label.text(),
 6530                new_label.text(),
 6531                completion.label.filter_text(),
 6532                new_label.filter_text()
 6533            );
 6534        }
 6535
 6536        Ok(())
 6537    }
 6538
 6539    async fn resolve_completion_remote(
 6540        project_id: u64,
 6541        server_id: LanguageServerId,
 6542        buffer_id: BufferId,
 6543        completions: Rc<RefCell<Box<[Completion]>>>,
 6544        completion_index: usize,
 6545        client: AnyProtoClient,
 6546    ) -> Result<()> {
 6547        let lsp_completion = {
 6548            let completion = &completions.borrow()[completion_index];
 6549            match &completion.source {
 6550                CompletionSource::Lsp {
 6551                    lsp_completion,
 6552                    resolved,
 6553                    server_id: completion_server_id,
 6554                    ..
 6555                } => {
 6556                    anyhow::ensure!(
 6557                        server_id == *completion_server_id,
 6558                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6559                    );
 6560                    if *resolved {
 6561                        return Ok(());
 6562                    }
 6563                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6564                }
 6565                CompletionSource::Custom
 6566                | CompletionSource::Dap { .. }
 6567                | CompletionSource::BufferWord { .. } => {
 6568                    return Ok(());
 6569                }
 6570            }
 6571        };
 6572        let request = proto::ResolveCompletionDocumentation {
 6573            project_id,
 6574            language_server_id: server_id.0 as u64,
 6575            lsp_completion,
 6576            buffer_id: buffer_id.into(),
 6577        };
 6578
 6579        let response = client
 6580            .request(request)
 6581            .await
 6582            .context("completion documentation resolve proto request")?;
 6583        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6584
 6585        let documentation = if response.documentation.is_empty() {
 6586            CompletionDocumentation::Undocumented
 6587        } else if response.documentation_is_markdown {
 6588            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6589        } else if response.documentation.lines().count() <= 1 {
 6590            CompletionDocumentation::SingleLine(response.documentation.into())
 6591        } else {
 6592            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6593        };
 6594
 6595        let mut completions = completions.borrow_mut();
 6596        let completion = &mut completions[completion_index];
 6597        completion.documentation = Some(documentation);
 6598        if let CompletionSource::Lsp {
 6599            insert_range,
 6600            lsp_completion,
 6601            resolved,
 6602            server_id: completion_server_id,
 6603            lsp_defaults: _,
 6604        } = &mut completion.source
 6605        {
 6606            let completion_insert_range = response
 6607                .old_insert_start
 6608                .and_then(deserialize_anchor)
 6609                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6610            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6611
 6612            if *resolved {
 6613                return Ok(());
 6614            }
 6615            anyhow::ensure!(
 6616                server_id == *completion_server_id,
 6617                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6618            );
 6619            **lsp_completion = resolved_lsp_completion;
 6620            *resolved = true;
 6621        }
 6622
 6623        let replace_range = response
 6624            .old_replace_start
 6625            .and_then(deserialize_anchor)
 6626            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6627        if let Some((old_replace_start, old_replace_end)) = replace_range
 6628            && !response.new_text.is_empty()
 6629        {
 6630            completion.new_text = response.new_text;
 6631            completion.replace_range = old_replace_start..old_replace_end;
 6632        }
 6633
 6634        Ok(())
 6635    }
 6636
 6637    pub fn apply_additional_edits_for_completion(
 6638        &self,
 6639        buffer_handle: Entity<Buffer>,
 6640        completions: Rc<RefCell<Box<[Completion]>>>,
 6641        completion_index: usize,
 6642        push_to_history: bool,
 6643        cx: &mut Context<Self>,
 6644    ) -> Task<Result<Option<Transaction>>> {
 6645        if let Some((client, project_id)) = self.upstream_client() {
 6646            let buffer = buffer_handle.read(cx);
 6647            let buffer_id = buffer.remote_id();
 6648            cx.spawn(async move |_, cx| {
 6649                let request = {
 6650                    let completion = completions.borrow()[completion_index].clone();
 6651                    proto::ApplyCompletionAdditionalEdits {
 6652                        project_id,
 6653                        buffer_id: buffer_id.into(),
 6654                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6655                            replace_range: completion.replace_range,
 6656                            new_text: completion.new_text,
 6657                            source: completion.source,
 6658                        })),
 6659                    }
 6660                };
 6661
 6662                let Some(transaction) = client.request(request).await?.transaction else {
 6663                    return Ok(None);
 6664                };
 6665
 6666                let transaction = language::proto::deserialize_transaction(transaction)?;
 6667                buffer_handle
 6668                    .update(cx, |buffer, _| {
 6669                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6670                    })
 6671                    .await?;
 6672                if push_to_history {
 6673                    buffer_handle.update(cx, |buffer, _| {
 6674                        buffer.push_transaction(transaction.clone(), Instant::now());
 6675                        buffer.finalize_last_transaction();
 6676                    });
 6677                }
 6678                Ok(Some(transaction))
 6679            })
 6680        } else {
 6681            let request_timeout = ProjectSettings::get_global(cx)
 6682                .global_lsp_settings
 6683                .get_request_timeout();
 6684
 6685            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6686                let completion = &completions.borrow()[completion_index];
 6687                let server_id = completion.source.server_id()?;
 6688                Some(
 6689                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6690                        .1
 6691                        .clone(),
 6692                )
 6693            }) else {
 6694                return Task::ready(Ok(None));
 6695            };
 6696
 6697            cx.spawn(async move |this, cx| {
 6698                Self::resolve_completion_local(
 6699                    server.clone(),
 6700                    completions.clone(),
 6701                    completion_index,
 6702                    request_timeout,
 6703                )
 6704                .await
 6705                .context("resolving completion")?;
 6706                let completion = completions.borrow()[completion_index].clone();
 6707                let additional_text_edits = completion
 6708                    .source
 6709                    .lsp_completion(true)
 6710                    .as_ref()
 6711                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6712                if let Some(edits) = additional_text_edits {
 6713                    let edits = this
 6714                        .update(cx, |this, cx| {
 6715                            this.as_local_mut().unwrap().edits_from_lsp(
 6716                                &buffer_handle,
 6717                                edits,
 6718                                server.server_id(),
 6719                                None,
 6720                                cx,
 6721                            )
 6722                        })?
 6723                        .await?;
 6724
 6725                    buffer_handle.update(cx, |buffer, cx| {
 6726                        buffer.finalize_last_transaction();
 6727                        buffer.start_transaction();
 6728
 6729                        for (range, text) in edits {
 6730                            let primary = &completion.replace_range;
 6731
 6732                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6733                            // and the primary completion is just an insertion (empty range), then this is likely
 6734                            // an auto-import scenario and should not be considered overlapping
 6735                            // https://github.com/zed-industries/zed/issues/26136
 6736                            let is_file_start_auto_import = {
 6737                                let snapshot = buffer.snapshot();
 6738                                let primary_start_point = primary.start.to_point(&snapshot);
 6739                                let range_start_point = range.start.to_point(&snapshot);
 6740
 6741                                let result = primary_start_point.row == 0
 6742                                    && primary_start_point.column == 0
 6743                                    && range_start_point.row == 0
 6744                                    && range_start_point.column == 0;
 6745
 6746                                result
 6747                            };
 6748
 6749                            let has_overlap = if is_file_start_auto_import {
 6750                                false
 6751                            } else {
 6752                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6753                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6754                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6755                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6756                                let result = start_within || end_within;
 6757                                result
 6758                            };
 6759
 6760                            //Skip additional edits which overlap with the primary completion edit
 6761                            //https://github.com/zed-industries/zed/pull/1871
 6762                            if !has_overlap {
 6763                                buffer.edit([(range, text)], None, cx);
 6764                            }
 6765                        }
 6766
 6767                        let transaction = if buffer.end_transaction(cx).is_some() {
 6768                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6769                            if !push_to_history {
 6770                                buffer.forget_transaction(transaction.id);
 6771                            }
 6772                            Some(transaction)
 6773                        } else {
 6774                            None
 6775                        };
 6776                        Ok(transaction)
 6777                    })
 6778                } else {
 6779                    Ok(None)
 6780                }
 6781            })
 6782        }
 6783    }
 6784
 6785    pub fn pull_diagnostics(
 6786        &mut self,
 6787        buffer: Entity<Buffer>,
 6788        cx: &mut Context<Self>,
 6789    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6790        let buffer_id = buffer.read(cx).remote_id();
 6791
 6792        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6793            let mut suitable_capabilities = None;
 6794            // Are we capable for proto request?
 6795            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6796                &buffer,
 6797                |capabilities| {
 6798                    if let Some(caps) = &capabilities.diagnostic_provider {
 6799                        suitable_capabilities = Some(caps.clone());
 6800                        true
 6801                    } else {
 6802                        false
 6803                    }
 6804                },
 6805                cx,
 6806            );
 6807            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6808            let Some(dynamic_caps) = suitable_capabilities else {
 6809                return Task::ready(Ok(None));
 6810            };
 6811            assert!(any_server_has_diagnostics_provider);
 6812
 6813            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6814            let request = GetDocumentDiagnostics {
 6815                previous_result_id: None,
 6816                identifier,
 6817                registration_id: None,
 6818            };
 6819            let request_timeout = ProjectSettings::get_global(cx)
 6820                .global_lsp_settings
 6821                .get_request_timeout();
 6822            let request_task = client.request_lsp(
 6823                upstream_project_id,
 6824                None,
 6825                request_timeout,
 6826                cx.background_executor().clone(),
 6827                request.to_proto(upstream_project_id, buffer.read(cx)),
 6828            );
 6829            cx.background_spawn(async move {
 6830                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6831                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6832                // Do not attempt to further process the dummy responses here.
 6833                let _response = request_task.await?;
 6834                Ok(None)
 6835            })
 6836        } else {
 6837            let servers = buffer.update(cx, |buffer, cx| {
 6838                self.running_language_servers_for_local_buffer(buffer, cx)
 6839                    .map(|(_, server)| server.clone())
 6840                    .collect::<Vec<_>>()
 6841            });
 6842
 6843            let pull_diagnostics = servers
 6844                .into_iter()
 6845                .flat_map(|server| {
 6846                    let result = maybe!({
 6847                        let local = self.as_local()?;
 6848                        let server_id = server.server_id();
 6849                        let providers_with_identifiers = local
 6850                            .language_server_dynamic_registrations
 6851                            .get(&server_id)
 6852                            .into_iter()
 6853                            .flat_map(|registrations| registrations.diagnostics.clone())
 6854                            .collect::<Vec<_>>();
 6855                        Some(
 6856                            providers_with_identifiers
 6857                                .into_iter()
 6858                                .map(|(registration_id, dynamic_caps)| {
 6859                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6860                                    let registration_id = registration_id.map(SharedString::from);
 6861                                    let result_id = self.result_id_for_buffer_pull(
 6862                                        server_id,
 6863                                        buffer_id,
 6864                                        &registration_id,
 6865                                        cx,
 6866                                    );
 6867                                    self.request_lsp(
 6868                                        buffer.clone(),
 6869                                        LanguageServerToQuery::Other(server_id),
 6870                                        GetDocumentDiagnostics {
 6871                                            previous_result_id: result_id,
 6872                                            registration_id,
 6873                                            identifier,
 6874                                        },
 6875                                        cx,
 6876                                    )
 6877                                })
 6878                                .collect::<Vec<_>>(),
 6879                        )
 6880                    });
 6881
 6882                    result.unwrap_or_default()
 6883                })
 6884                .collect::<Vec<_>>();
 6885
 6886            cx.background_spawn(async move {
 6887                let mut responses = Vec::new();
 6888                for diagnostics in join_all(pull_diagnostics).await {
 6889                    responses.extend(diagnostics?);
 6890                }
 6891                Ok(Some(responses))
 6892            })
 6893        }
 6894    }
 6895
 6896    pub fn applicable_inlay_chunks(
 6897        &mut self,
 6898        buffer: &Entity<Buffer>,
 6899        ranges: &[Range<text::Anchor>],
 6900        cx: &mut Context<Self>,
 6901    ) -> Vec<Range<BufferRow>> {
 6902        let buffer_snapshot = buffer.read(cx).snapshot();
 6903        let ranges = ranges
 6904            .iter()
 6905            .map(|range| range.to_point(&buffer_snapshot))
 6906            .collect::<Vec<_>>();
 6907
 6908        self.latest_lsp_data(buffer, cx)
 6909            .inlay_hints
 6910            .applicable_chunks(ranges.as_slice())
 6911            .map(|chunk| chunk.row_range())
 6912            .collect()
 6913    }
 6914
 6915    pub fn invalidate_inlay_hints<'a>(
 6916        &'a mut self,
 6917        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6918    ) {
 6919        for buffer_id in for_buffers {
 6920            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6921                lsp_data.inlay_hints.clear();
 6922            }
 6923        }
 6924    }
 6925
 6926    pub fn inlay_hints(
 6927        &mut self,
 6928        invalidate: InvalidationStrategy,
 6929        buffer: Entity<Buffer>,
 6930        ranges: Vec<Range<text::Anchor>>,
 6931        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6932        cx: &mut Context<Self>,
 6933    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6934        let next_hint_id = self.next_hint_id.clone();
 6935        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6936        let query_version = lsp_data.buffer_version.clone();
 6937        let mut lsp_refresh_requested = false;
 6938        let for_server = if let InvalidationStrategy::RefreshRequested {
 6939            server_id,
 6940            request_id,
 6941        } = invalidate
 6942        {
 6943            let invalidated = lsp_data
 6944                .inlay_hints
 6945                .invalidate_for_server_refresh(server_id, request_id);
 6946            lsp_refresh_requested = invalidated;
 6947            Some(server_id)
 6948        } else {
 6949            None
 6950        };
 6951        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6952        let known_chunks = known_chunks
 6953            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6954            .map(|(_, known_chunks)| known_chunks)
 6955            .unwrap_or_default();
 6956
 6957        let buffer_snapshot = buffer.read(cx).snapshot();
 6958        let ranges = ranges
 6959            .iter()
 6960            .map(|range| range.to_point(&buffer_snapshot))
 6961            .collect::<Vec<_>>();
 6962
 6963        let mut hint_fetch_tasks = Vec::new();
 6964        let mut cached_inlay_hints = None;
 6965        let mut ranges_to_query = None;
 6966        let applicable_chunks = existing_inlay_hints
 6967            .applicable_chunks(ranges.as_slice())
 6968            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 6969            .collect::<Vec<_>>();
 6970        if applicable_chunks.is_empty() {
 6971            return HashMap::default();
 6972        }
 6973
 6974        for row_chunk in applicable_chunks {
 6975            match (
 6976                existing_inlay_hints
 6977                    .cached_hints(&row_chunk)
 6978                    .filter(|_| !lsp_refresh_requested)
 6979                    .cloned(),
 6980                existing_inlay_hints
 6981                    .fetched_hints(&row_chunk)
 6982                    .as_ref()
 6983                    .filter(|_| !lsp_refresh_requested)
 6984                    .cloned(),
 6985            ) {
 6986                (None, None) => {
 6987                    let chunk_range = row_chunk.anchor_range();
 6988                    ranges_to_query
 6989                        .get_or_insert_with(Vec::new)
 6990                        .push((row_chunk, chunk_range));
 6991                }
 6992                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 6993                (Some(cached_hints), None) => {
 6994                    for (server_id, cached_hints) in cached_hints {
 6995                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6996                            cached_inlay_hints
 6997                                .get_or_insert_with(HashMap::default)
 6998                                .entry(row_chunk.row_range())
 6999                                .or_insert_with(HashMap::default)
 7000                                .entry(server_id)
 7001                                .or_insert_with(Vec::new)
 7002                                .extend(cached_hints);
 7003                        }
 7004                    }
 7005                }
 7006                (Some(cached_hints), Some(fetched_hints)) => {
 7007                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7008                    for (server_id, cached_hints) in cached_hints {
 7009                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7010                            cached_inlay_hints
 7011                                .get_or_insert_with(HashMap::default)
 7012                                .entry(row_chunk.row_range())
 7013                                .or_insert_with(HashMap::default)
 7014                                .entry(server_id)
 7015                                .or_insert_with(Vec::new)
 7016                                .extend(cached_hints);
 7017                        }
 7018                    }
 7019                }
 7020            }
 7021        }
 7022
 7023        if hint_fetch_tasks.is_empty()
 7024            && ranges_to_query
 7025                .as_ref()
 7026                .is_none_or(|ranges| ranges.is_empty())
 7027            && let Some(cached_inlay_hints) = cached_inlay_hints
 7028        {
 7029            cached_inlay_hints
 7030                .into_iter()
 7031                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7032                .collect()
 7033        } else {
 7034            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7035                // When a server refresh was requested, other servers' cached hints
 7036                // are unaffected by the refresh and must be included in the result.
 7037                // Otherwise apply_fetched_hints (with should_invalidate()=true)
 7038                // removes all visible hints but only adds back the requesting
 7039                // server's new hints, permanently losing other servers' hints.
 7040                let other_servers_cached: CacheInlayHints = if lsp_refresh_requested {
 7041                    lsp_data
 7042                        .inlay_hints
 7043                        .cached_hints(&chunk)
 7044                        .cloned()
 7045                        .unwrap_or_default()
 7046                } else {
 7047                    HashMap::default()
 7048                };
 7049
 7050                let next_hint_id = next_hint_id.clone();
 7051                let buffer = buffer.clone();
 7052                let query_version = query_version.clone();
 7053                let new_inlay_hints = cx
 7054                    .spawn(async move |lsp_store, cx| {
 7055                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7056                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7057                        })?;
 7058                        new_fetch_task
 7059                            .await
 7060                            .and_then(|new_hints_by_server| {
 7061                                lsp_store.update(cx, |lsp_store, cx| {
 7062                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7063                                    let update_cache = lsp_data.buffer_version == query_version;
 7064                                    if new_hints_by_server.is_empty() {
 7065                                        if update_cache {
 7066                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7067                                        }
 7068                                        other_servers_cached
 7069                                    } else {
 7070                                        let mut result = other_servers_cached;
 7071                                        for (server_id, new_hints) in new_hints_by_server {
 7072                                            let new_hints = new_hints
 7073                                                .into_iter()
 7074                                                .map(|new_hint| {
 7075                                                    (
 7076                                                        InlayId::Hint(next_hint_id.fetch_add(
 7077                                                            1,
 7078                                                            atomic::Ordering::AcqRel,
 7079                                                        )),
 7080                                                        new_hint,
 7081                                                    )
 7082                                                })
 7083                                                .collect::<Vec<_>>();
 7084                                            if update_cache {
 7085                                                lsp_data.inlay_hints.insert_new_hints(
 7086                                                    chunk,
 7087                                                    server_id,
 7088                                                    new_hints.clone(),
 7089                                                );
 7090                                            }
 7091                                            result.insert(server_id, new_hints);
 7092                                        }
 7093                                        result
 7094                                    }
 7095                                })
 7096                            })
 7097                            .map_err(Arc::new)
 7098                    })
 7099                    .shared();
 7100
 7101                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7102                *fetch_task = Some(new_inlay_hints.clone());
 7103                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7104            }
 7105
 7106            cached_inlay_hints
 7107                .unwrap_or_default()
 7108                .into_iter()
 7109                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7110                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7111                    (
 7112                        chunk.row_range(),
 7113                        cx.spawn(async move |_, _| {
 7114                            hints_fetch.await.map_err(|e| {
 7115                                if e.error_code() != ErrorCode::Internal {
 7116                                    anyhow!(e.error_code())
 7117                                } else {
 7118                                    anyhow!("{e:#}")
 7119                                }
 7120                            })
 7121                        }),
 7122                    )
 7123                }))
 7124                .collect()
 7125        }
 7126    }
 7127
 7128    fn fetch_inlay_hints(
 7129        &mut self,
 7130        for_server: Option<LanguageServerId>,
 7131        buffer: &Entity<Buffer>,
 7132        range: Range<Anchor>,
 7133        cx: &mut Context<Self>,
 7134    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7135        let request = InlayHints {
 7136            range: range.clone(),
 7137        };
 7138        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7139            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7140                return Task::ready(Ok(HashMap::default()));
 7141            }
 7142            let request_timeout = ProjectSettings::get_global(cx)
 7143                .global_lsp_settings
 7144                .get_request_timeout();
 7145            let request_task = upstream_client.request_lsp(
 7146                project_id,
 7147                for_server.map(|id| id.to_proto()),
 7148                request_timeout,
 7149                cx.background_executor().clone(),
 7150                request.to_proto(project_id, buffer.read(cx)),
 7151            );
 7152            let buffer = buffer.clone();
 7153            cx.spawn(async move |weak_lsp_store, cx| {
 7154                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7155                    return Ok(HashMap::default());
 7156                };
 7157                let Some(responses) = request_task.await? else {
 7158                    return Ok(HashMap::default());
 7159                };
 7160
 7161                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7162                    let lsp_store = lsp_store.clone();
 7163                    let buffer = buffer.clone();
 7164                    let cx = cx.clone();
 7165                    let request = request.clone();
 7166                    async move {
 7167                        (
 7168                            LanguageServerId::from_proto(response.server_id),
 7169                            request
 7170                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7171                                .await,
 7172                        )
 7173                    }
 7174                }))
 7175                .await;
 7176
 7177                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7178                let mut has_errors = false;
 7179                let inlay_hints = inlay_hints
 7180                    .into_iter()
 7181                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7182                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7183                        Err(e) => {
 7184                            has_errors = true;
 7185                            log::error!("{e:#}");
 7186                            None
 7187                        }
 7188                    })
 7189                    .map(|(server_id, mut new_hints)| {
 7190                        new_hints.retain(|hint| {
 7191                            hint.position.is_valid(&buffer_snapshot)
 7192                                && range.start.is_valid(&buffer_snapshot)
 7193                                && range.end.is_valid(&buffer_snapshot)
 7194                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7195                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7196                        });
 7197                        (server_id, new_hints)
 7198                    })
 7199                    .collect::<HashMap<_, _>>();
 7200                anyhow::ensure!(
 7201                    !has_errors || !inlay_hints.is_empty(),
 7202                    "Failed to fetch inlay hints"
 7203                );
 7204                Ok(inlay_hints)
 7205            })
 7206        } else {
 7207            let inlay_hints_task = match for_server {
 7208                Some(server_id) => {
 7209                    let server_task = self.request_lsp(
 7210                        buffer.clone(),
 7211                        LanguageServerToQuery::Other(server_id),
 7212                        request,
 7213                        cx,
 7214                    );
 7215                    cx.background_spawn(async move {
 7216                        let mut responses = Vec::new();
 7217                        match server_task.await {
 7218                            Ok(response) => responses.push((server_id, response)),
 7219                            // rust-analyzer likes to error with this when its still loading up
 7220                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7221                            Err(e) => log::error!(
 7222                                "Error handling response for inlay hints request: {e:#}"
 7223                            ),
 7224                        }
 7225                        responses
 7226                    })
 7227                }
 7228                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7229            };
 7230            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7231            cx.background_spawn(async move {
 7232                Ok(inlay_hints_task
 7233                    .await
 7234                    .into_iter()
 7235                    .map(|(server_id, mut new_hints)| {
 7236                        new_hints.retain(|hint| {
 7237                            hint.position.is_valid(&buffer_snapshot)
 7238                                && range.start.is_valid(&buffer_snapshot)
 7239                                && range.end.is_valid(&buffer_snapshot)
 7240                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7241                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7242                        });
 7243                        (server_id, new_hints)
 7244                    })
 7245                    .collect())
 7246            })
 7247        }
 7248    }
 7249
 7250    fn diagnostic_registration_exists(
 7251        &self,
 7252        server_id: LanguageServerId,
 7253        registration_id: &Option<SharedString>,
 7254    ) -> bool {
 7255        let Some(local) = self.as_local() else {
 7256            return false;
 7257        };
 7258        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7259        else {
 7260            return false;
 7261        };
 7262        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7263        registrations.diagnostics.contains_key(&registration_key)
 7264    }
 7265
 7266    pub fn pull_diagnostics_for_buffer(
 7267        &mut self,
 7268        buffer: Entity<Buffer>,
 7269        cx: &mut Context<Self>,
 7270    ) -> Task<anyhow::Result<()>> {
 7271        let diagnostics = self.pull_diagnostics(buffer, cx);
 7272        cx.spawn(async move |lsp_store, cx| {
 7273            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7274                return Ok(());
 7275            };
 7276            lsp_store.update(cx, |lsp_store, cx| {
 7277                if lsp_store.as_local().is_none() {
 7278                    return;
 7279                }
 7280
 7281                let mut unchanged_buffers = HashMap::default();
 7282                let server_diagnostics_updates = diagnostics
 7283                    .into_iter()
 7284                    .filter_map(|diagnostics_set| match diagnostics_set {
 7285                        LspPullDiagnostics::Response {
 7286                            server_id,
 7287                            uri,
 7288                            diagnostics,
 7289                            registration_id,
 7290                        } => Some((server_id, uri, diagnostics, registration_id)),
 7291                        LspPullDiagnostics::Default => None,
 7292                    })
 7293                    .filter(|(server_id, _, _, registration_id)| {
 7294                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7295                    })
 7296                    .fold(
 7297                        HashMap::default(),
 7298                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7299                            let (result_id, diagnostics) = match diagnostics {
 7300                                PulledDiagnostics::Unchanged { result_id } => {
 7301                                    unchanged_buffers
 7302                                        .entry(new_registration_id.clone())
 7303                                        .or_insert_with(HashSet::default)
 7304                                        .insert(uri.clone());
 7305                                    (Some(result_id), Vec::new())
 7306                                }
 7307                                PulledDiagnostics::Changed {
 7308                                    result_id,
 7309                                    diagnostics,
 7310                                } => (result_id, diagnostics),
 7311                            };
 7312                            let disk_based_sources = Cow::Owned(
 7313                                lsp_store
 7314                                    .language_server_adapter_for_id(server_id)
 7315                                    .as_ref()
 7316                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7317                                    .unwrap_or(&[])
 7318                                    .to_vec(),
 7319                            );
 7320                            acc.entry(server_id)
 7321                                .or_insert_with(HashMap::default)
 7322                                .entry(new_registration_id.clone())
 7323                                .or_insert_with(Vec::new)
 7324                                .push(DocumentDiagnosticsUpdate {
 7325                                    server_id,
 7326                                    diagnostics: lsp::PublishDiagnosticsParams {
 7327                                        uri,
 7328                                        diagnostics,
 7329                                        version: None,
 7330                                    },
 7331                                    result_id: result_id.map(SharedString::new),
 7332                                    disk_based_sources,
 7333                                    registration_id: new_registration_id,
 7334                                });
 7335                            acc
 7336                        },
 7337                    );
 7338
 7339                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7340                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7341                        lsp_store
 7342                            .merge_lsp_diagnostics(
 7343                                DiagnosticSourceKind::Pulled,
 7344                                diagnostic_updates,
 7345                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7346                                    DiagnosticSourceKind::Pulled => {
 7347                                        old_diagnostic.registration_id != registration_id
 7348                                            || unchanged_buffers
 7349                                                .get(&old_diagnostic.registration_id)
 7350                                                .is_some_and(|unchanged_buffers| {
 7351                                                    unchanged_buffers.contains(&document_uri)
 7352                                                })
 7353                                    }
 7354                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7355                                        true
 7356                                    }
 7357                                },
 7358                                cx,
 7359                            )
 7360                            .log_err();
 7361                    }
 7362                }
 7363            })
 7364        })
 7365    }
 7366
 7367    pub fn signature_help<T: ToPointUtf16>(
 7368        &mut self,
 7369        buffer: &Entity<Buffer>,
 7370        position: T,
 7371        cx: &mut Context<Self>,
 7372    ) -> Task<Option<Vec<SignatureHelp>>> {
 7373        let position = position.to_point_utf16(buffer.read(cx));
 7374
 7375        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7376            let request = GetSignatureHelp { position };
 7377            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7378                return Task::ready(None);
 7379            }
 7380            let request_timeout = ProjectSettings::get_global(cx)
 7381                .global_lsp_settings
 7382                .get_request_timeout();
 7383            let request_task = client.request_lsp(
 7384                upstream_project_id,
 7385                None,
 7386                request_timeout,
 7387                cx.background_executor().clone(),
 7388                request.to_proto(upstream_project_id, buffer.read(cx)),
 7389            );
 7390            let buffer = buffer.clone();
 7391            cx.spawn(async move |weak_lsp_store, cx| {
 7392                let lsp_store = weak_lsp_store.upgrade()?;
 7393                let signatures = join_all(
 7394                    request_task
 7395                        .await
 7396                        .log_err()
 7397                        .flatten()
 7398                        .map(|response| response.payload)
 7399                        .unwrap_or_default()
 7400                        .into_iter()
 7401                        .map(|response| {
 7402                            let response = GetSignatureHelp { position }.response_from_proto(
 7403                                response.response,
 7404                                lsp_store.clone(),
 7405                                buffer.clone(),
 7406                                cx.clone(),
 7407                            );
 7408                            async move { response.await.log_err().flatten() }
 7409                        }),
 7410                )
 7411                .await
 7412                .into_iter()
 7413                .flatten()
 7414                .collect();
 7415                Some(signatures)
 7416            })
 7417        } else {
 7418            let all_actions_task = self.request_multiple_lsp_locally(
 7419                buffer,
 7420                Some(position),
 7421                GetSignatureHelp { position },
 7422                cx,
 7423            );
 7424            cx.background_spawn(async move {
 7425                Some(
 7426                    all_actions_task
 7427                        .await
 7428                        .into_iter()
 7429                        .flat_map(|(_, actions)| actions)
 7430                        .collect::<Vec<_>>(),
 7431                )
 7432            })
 7433        }
 7434    }
 7435
 7436    pub fn hover(
 7437        &mut self,
 7438        buffer: &Entity<Buffer>,
 7439        position: PointUtf16,
 7440        cx: &mut Context<Self>,
 7441    ) -> Task<Option<Vec<Hover>>> {
 7442        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7443            let request = GetHover { position };
 7444            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7445                return Task::ready(None);
 7446            }
 7447            let request_timeout = ProjectSettings::get_global(cx)
 7448                .global_lsp_settings
 7449                .get_request_timeout();
 7450            let request_task = client.request_lsp(
 7451                upstream_project_id,
 7452                None,
 7453                request_timeout,
 7454                cx.background_executor().clone(),
 7455                request.to_proto(upstream_project_id, buffer.read(cx)),
 7456            );
 7457            let buffer = buffer.clone();
 7458            cx.spawn(async move |weak_lsp_store, cx| {
 7459                let lsp_store = weak_lsp_store.upgrade()?;
 7460                let hovers = join_all(
 7461                    request_task
 7462                        .await
 7463                        .log_err()
 7464                        .flatten()
 7465                        .map(|response| response.payload)
 7466                        .unwrap_or_default()
 7467                        .into_iter()
 7468                        .map(|response| {
 7469                            let response = GetHover { position }.response_from_proto(
 7470                                response.response,
 7471                                lsp_store.clone(),
 7472                                buffer.clone(),
 7473                                cx.clone(),
 7474                            );
 7475                            async move {
 7476                                response
 7477                                    .await
 7478                                    .log_err()
 7479                                    .flatten()
 7480                                    .and_then(remove_empty_hover_blocks)
 7481                            }
 7482                        }),
 7483                )
 7484                .await
 7485                .into_iter()
 7486                .flatten()
 7487                .collect();
 7488                Some(hovers)
 7489            })
 7490        } else {
 7491            let all_actions_task = self.request_multiple_lsp_locally(
 7492                buffer,
 7493                Some(position),
 7494                GetHover { position },
 7495                cx,
 7496            );
 7497            cx.background_spawn(async move {
 7498                Some(
 7499                    all_actions_task
 7500                        .await
 7501                        .into_iter()
 7502                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7503                        .collect::<Vec<Hover>>(),
 7504                )
 7505            })
 7506        }
 7507    }
 7508
 7509    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7510        let language_registry = self.languages.clone();
 7511
 7512        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7513            let request = upstream_client.request(proto::GetProjectSymbols {
 7514                project_id: *project_id,
 7515                query: query.to_string(),
 7516            });
 7517            cx.foreground_executor().spawn(async move {
 7518                let response = request.await?;
 7519                let mut symbols = Vec::new();
 7520                let core_symbols = response
 7521                    .symbols
 7522                    .into_iter()
 7523                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7524                    .collect::<Vec<_>>();
 7525                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7526                    .await;
 7527                Ok(symbols)
 7528            })
 7529        } else if let Some(local) = self.as_local() {
 7530            struct WorkspaceSymbolsResult {
 7531                server_id: LanguageServerId,
 7532                lsp_adapter: Arc<CachedLspAdapter>,
 7533                worktree: WeakEntity<Worktree>,
 7534                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7535            }
 7536
 7537            let mut requests = Vec::new();
 7538            let mut requested_servers = BTreeSet::new();
 7539            let request_timeout = ProjectSettings::get_global(cx)
 7540                .global_lsp_settings
 7541                .get_request_timeout();
 7542
 7543            for (seed, state) in local.language_server_ids.iter() {
 7544                let Some(worktree_handle) = self
 7545                    .worktree_store
 7546                    .read(cx)
 7547                    .worktree_for_id(seed.worktree_id, cx)
 7548                else {
 7549                    continue;
 7550                };
 7551
 7552                let worktree = worktree_handle.read(cx);
 7553                if !worktree.is_visible() {
 7554                    continue;
 7555                }
 7556
 7557                if !requested_servers.insert(state.id) {
 7558                    continue;
 7559                }
 7560
 7561                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7562                    Some(LanguageServerState::Running {
 7563                        adapter, server, ..
 7564                    }) => (adapter.clone(), server),
 7565
 7566                    _ => continue,
 7567                };
 7568
 7569                let supports_workspace_symbol_request =
 7570                    match server.capabilities().workspace_symbol_provider {
 7571                        Some(OneOf::Left(supported)) => supported,
 7572                        Some(OneOf::Right(_)) => true,
 7573                        None => false,
 7574                    };
 7575
 7576                if !supports_workspace_symbol_request {
 7577                    continue;
 7578                }
 7579
 7580                let worktree_handle = worktree_handle.clone();
 7581                let server_id = server.server_id();
 7582                requests.push(
 7583                    server
 7584                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7585                            lsp::WorkspaceSymbolParams {
 7586                                query: query.to_string(),
 7587                                ..Default::default()
 7588                            },
 7589                            request_timeout,
 7590                        )
 7591                        .map(move |response| {
 7592                            let lsp_symbols = response
 7593                                .into_response()
 7594                                .context("workspace symbols request")
 7595                                .log_err()
 7596                                .flatten()
 7597                                .map(|symbol_response| match symbol_response {
 7598                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7599                                        flat_responses
 7600                                            .into_iter()
 7601                                            .map(|lsp_symbol| {
 7602                                                (
 7603                                                    lsp_symbol.name,
 7604                                                    lsp_symbol.kind,
 7605                                                    lsp_symbol.location,
 7606                                                    lsp_symbol.container_name,
 7607                                                )
 7608                                            })
 7609                                            .collect::<Vec<_>>()
 7610                                    }
 7611                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7612                                        nested_responses
 7613                                            .into_iter()
 7614                                            .filter_map(|lsp_symbol| {
 7615                                                let location = match lsp_symbol.location {
 7616                                                    OneOf::Left(location) => location,
 7617                                                    OneOf::Right(_) => {
 7618                                                        log::error!(
 7619                                                            "Unexpected: client capabilities \
 7620                                                            forbid symbol resolutions in \
 7621                                                            workspace.symbol.resolveSupport"
 7622                                                        );
 7623                                                        return None;
 7624                                                    }
 7625                                                };
 7626                                                Some((
 7627                                                    lsp_symbol.name,
 7628                                                    lsp_symbol.kind,
 7629                                                    location,
 7630                                                    lsp_symbol.container_name,
 7631                                                ))
 7632                                            })
 7633                                            .collect::<Vec<_>>()
 7634                                    }
 7635                                })
 7636                                .unwrap_or_default();
 7637
 7638                            WorkspaceSymbolsResult {
 7639                                server_id,
 7640                                lsp_adapter,
 7641                                worktree: worktree_handle.downgrade(),
 7642                                lsp_symbols,
 7643                            }
 7644                        }),
 7645                );
 7646            }
 7647
 7648            cx.spawn(async move |this, cx| {
 7649                let responses = futures::future::join_all(requests).await;
 7650                let this = match this.upgrade() {
 7651                    Some(this) => this,
 7652                    None => return Ok(Vec::new()),
 7653                };
 7654
 7655                let mut symbols = Vec::new();
 7656                for result in responses {
 7657                    let core_symbols = this.update(cx, |this, cx| {
 7658                        result
 7659                            .lsp_symbols
 7660                            .into_iter()
 7661                            .filter_map(
 7662                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7663                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7664                                    let source_worktree = result.worktree.upgrade()?;
 7665                                    let source_worktree_id = source_worktree.read(cx).id();
 7666
 7667                                    let path = if let Some((tree, rel_path)) =
 7668                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7669                                    {
 7670                                        let worktree_id = tree.read(cx).id();
 7671                                        SymbolLocation::InProject(ProjectPath {
 7672                                            worktree_id,
 7673                                            path: rel_path,
 7674                                        })
 7675                                    } else {
 7676                                        SymbolLocation::OutsideProject {
 7677                                            signature: this.symbol_signature(&abs_path),
 7678                                            abs_path: abs_path.into(),
 7679                                        }
 7680                                    };
 7681
 7682                                    Some(CoreSymbol {
 7683                                        source_language_server_id: result.server_id,
 7684                                        language_server_name: result.lsp_adapter.name.clone(),
 7685                                        source_worktree_id,
 7686                                        path,
 7687                                        kind: symbol_kind,
 7688                                        name: collapse_newlines(&symbol_name, ""),
 7689                                        range: range_from_lsp(symbol_location.range),
 7690                                        container_name: container_name
 7691                                            .map(|c| collapse_newlines(&c, "")),
 7692                                    })
 7693                                },
 7694                            )
 7695                            .collect::<Vec<_>>()
 7696                    });
 7697
 7698                    populate_labels_for_symbols(
 7699                        core_symbols,
 7700                        &language_registry,
 7701                        Some(result.lsp_adapter),
 7702                        &mut symbols,
 7703                    )
 7704                    .await;
 7705                }
 7706
 7707                Ok(symbols)
 7708            })
 7709        } else {
 7710            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7711        }
 7712    }
 7713
 7714    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7715        let mut summary = DiagnosticSummary::default();
 7716        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7717            summary.error_count += path_summary.error_count;
 7718            summary.warning_count += path_summary.warning_count;
 7719        }
 7720        summary
 7721    }
 7722
 7723    /// Returns the diagnostic summary for a specific project path.
 7724    pub fn diagnostic_summary_for_path(
 7725        &self,
 7726        project_path: &ProjectPath,
 7727        _: &App,
 7728    ) -> DiagnosticSummary {
 7729        if let Some(summaries) = self
 7730            .diagnostic_summaries
 7731            .get(&project_path.worktree_id)
 7732            .and_then(|map| map.get(&project_path.path))
 7733        {
 7734            let (error_count, warning_count) = summaries.iter().fold(
 7735                (0, 0),
 7736                |(error_count, warning_count), (_language_server_id, summary)| {
 7737                    (
 7738                        error_count + summary.error_count,
 7739                        warning_count + summary.warning_count,
 7740                    )
 7741                },
 7742            );
 7743
 7744            DiagnosticSummary {
 7745                error_count,
 7746                warning_count,
 7747            }
 7748        } else {
 7749            DiagnosticSummary::default()
 7750        }
 7751    }
 7752
 7753    pub fn diagnostic_summaries<'a>(
 7754        &'a self,
 7755        include_ignored: bool,
 7756        cx: &'a App,
 7757    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7758        self.worktree_store
 7759            .read(cx)
 7760            .visible_worktrees(cx)
 7761            .filter_map(|worktree| {
 7762                let worktree = worktree.read(cx);
 7763                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7764            })
 7765            .flat_map(move |(worktree, summaries)| {
 7766                let worktree_id = worktree.id();
 7767                summaries
 7768                    .iter()
 7769                    .filter(move |(path, _)| {
 7770                        include_ignored
 7771                            || worktree
 7772                                .entry_for_path(path.as_ref())
 7773                                .is_some_and(|entry| !entry.is_ignored)
 7774                    })
 7775                    .flat_map(move |(path, summaries)| {
 7776                        summaries.iter().map(move |(server_id, summary)| {
 7777                            (
 7778                                ProjectPath {
 7779                                    worktree_id,
 7780                                    path: path.clone(),
 7781                                },
 7782                                *server_id,
 7783                                *summary,
 7784                            )
 7785                        })
 7786                    })
 7787            })
 7788    }
 7789
 7790    pub fn on_buffer_edited(
 7791        &mut self,
 7792        buffer: Entity<Buffer>,
 7793        cx: &mut Context<Self>,
 7794    ) -> Option<()> {
 7795        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7796            Some(
 7797                self.as_local()?
 7798                    .language_servers_for_buffer(buffer, cx)
 7799                    .map(|i| i.1.clone())
 7800                    .collect(),
 7801            )
 7802        })?;
 7803
 7804        let buffer = buffer.read(cx);
 7805        let file = File::from_dyn(buffer.file())?;
 7806        let abs_path = file.as_local()?.abs_path(cx);
 7807        let uri = lsp::Uri::from_file_path(&abs_path)
 7808            .ok()
 7809            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7810            .log_err()?;
 7811        let next_snapshot = buffer.text_snapshot();
 7812        for language_server in language_servers {
 7813            let language_server = language_server.clone();
 7814
 7815            let buffer_snapshots = self
 7816                .as_local_mut()?
 7817                .buffer_snapshots
 7818                .get_mut(&buffer.remote_id())
 7819                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7820            let previous_snapshot = buffer_snapshots.last()?;
 7821
 7822            let build_incremental_change = || {
 7823                buffer
 7824                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7825                        previous_snapshot.snapshot.version(),
 7826                    )
 7827                    .map(|edit| {
 7828                        let edit_start = edit.new.start.0;
 7829                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7830                        let new_text = next_snapshot
 7831                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7832                            .collect();
 7833                        lsp::TextDocumentContentChangeEvent {
 7834                            range: Some(lsp::Range::new(
 7835                                point_to_lsp(edit_start),
 7836                                point_to_lsp(edit_end),
 7837                            )),
 7838                            range_length: None,
 7839                            text: new_text,
 7840                        }
 7841                    })
 7842                    .collect()
 7843            };
 7844
 7845            let document_sync_kind = language_server
 7846                .capabilities()
 7847                .text_document_sync
 7848                .as_ref()
 7849                .and_then(|sync| match sync {
 7850                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7851                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7852                });
 7853
 7854            let content_changes: Vec<_> = match document_sync_kind {
 7855                Some(lsp::TextDocumentSyncKind::FULL) => {
 7856                    vec![lsp::TextDocumentContentChangeEvent {
 7857                        range: None,
 7858                        range_length: None,
 7859                        text: next_snapshot.text(),
 7860                    }]
 7861                }
 7862                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7863                _ => {
 7864                    #[cfg(any(test, feature = "test-support"))]
 7865                    {
 7866                        build_incremental_change()
 7867                    }
 7868
 7869                    #[cfg(not(any(test, feature = "test-support")))]
 7870                    {
 7871                        continue;
 7872                    }
 7873                }
 7874            };
 7875
 7876            let next_version = previous_snapshot.version + 1;
 7877            buffer_snapshots.push(LspBufferSnapshot {
 7878                version: next_version,
 7879                snapshot: next_snapshot.clone(),
 7880            });
 7881
 7882            language_server
 7883                .notify::<lsp::notification::DidChangeTextDocument>(
 7884                    lsp::DidChangeTextDocumentParams {
 7885                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7886                            uri.clone(),
 7887                            next_version,
 7888                        ),
 7889                        content_changes,
 7890                    },
 7891                )
 7892                .ok();
 7893            self.pull_workspace_diagnostics(language_server.server_id());
 7894        }
 7895
 7896        None
 7897    }
 7898
 7899    pub fn on_buffer_saved(
 7900        &mut self,
 7901        buffer: Entity<Buffer>,
 7902        cx: &mut Context<Self>,
 7903    ) -> Option<()> {
 7904        let file = File::from_dyn(buffer.read(cx).file())?;
 7905        let worktree_id = file.worktree_id(cx);
 7906        let abs_path = file.as_local()?.abs_path(cx);
 7907        let text_document = lsp::TextDocumentIdentifier {
 7908            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7909        };
 7910        let local = self.as_local()?;
 7911
 7912        for server in local.language_servers_for_worktree(worktree_id) {
 7913            if let Some(include_text) = include_text(server.as_ref()) {
 7914                let text = if include_text {
 7915                    Some(buffer.read(cx).text())
 7916                } else {
 7917                    None
 7918                };
 7919                server
 7920                    .notify::<lsp::notification::DidSaveTextDocument>(
 7921                        lsp::DidSaveTextDocumentParams {
 7922                            text_document: text_document.clone(),
 7923                            text,
 7924                        },
 7925                    )
 7926                    .ok();
 7927            }
 7928        }
 7929
 7930        let language_servers = buffer.update(cx, |buffer, cx| {
 7931            local.language_server_ids_for_buffer(buffer, cx)
 7932        });
 7933        for language_server_id in language_servers {
 7934            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7935        }
 7936
 7937        None
 7938    }
 7939
 7940    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7941        maybe!(async move {
 7942            let mut refreshed_servers = HashSet::default();
 7943            let servers = lsp_store
 7944                .update(cx, |lsp_store, cx| {
 7945                    let local = lsp_store.as_local()?;
 7946
 7947                    let servers = local
 7948                        .language_server_ids
 7949                        .iter()
 7950                        .filter_map(|(seed, state)| {
 7951                            let worktree = lsp_store
 7952                                .worktree_store
 7953                                .read(cx)
 7954                                .worktree_for_id(seed.worktree_id, cx);
 7955                            let delegate: Arc<dyn LspAdapterDelegate> =
 7956                                worktree.map(|worktree| {
 7957                                    LocalLspAdapterDelegate::new(
 7958                                        local.languages.clone(),
 7959                                        &local.environment,
 7960                                        cx.weak_entity(),
 7961                                        &worktree,
 7962                                        local.http_client.clone(),
 7963                                        local.fs.clone(),
 7964                                        cx,
 7965                                    )
 7966                                })?;
 7967                            let server_id = state.id;
 7968
 7969                            let states = local.language_servers.get(&server_id)?;
 7970
 7971                            match states {
 7972                                LanguageServerState::Starting { .. } => None,
 7973                                LanguageServerState::Running {
 7974                                    adapter, server, ..
 7975                                } => {
 7976                                    let adapter = adapter.clone();
 7977                                    let server = server.clone();
 7978                                    refreshed_servers.insert(server.name());
 7979                                    let toolchain = seed.toolchain.clone();
 7980                                    Some(cx.spawn(async move |_, cx| {
 7981                                        let settings =
 7982                                            LocalLspStore::workspace_configuration_for_adapter(
 7983                                                adapter.adapter.clone(),
 7984                                                &delegate,
 7985                                                toolchain,
 7986                                                None,
 7987                                                cx,
 7988                                            )
 7989                                            .await
 7990                                            .ok()?;
 7991                                        server
 7992                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7993                                                lsp::DidChangeConfigurationParams { settings },
 7994                                            )
 7995                                            .ok()?;
 7996                                        Some(())
 7997                                    }))
 7998                                }
 7999                            }
 8000                        })
 8001                        .collect::<Vec<_>>();
 8002
 8003                    Some(servers)
 8004                })
 8005                .ok()
 8006                .flatten()?;
 8007
 8008            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8009            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8010            // to stop and unregister its language server wrapper.
 8011            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8012            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8013            let _: Vec<Option<()>> = join_all(servers).await;
 8014
 8015            Some(())
 8016        })
 8017        .await;
 8018    }
 8019
 8020    fn maintain_workspace_config(
 8021        external_refresh_requests: watch::Receiver<()>,
 8022        cx: &mut Context<Self>,
 8023    ) -> Task<Result<()>> {
 8024        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8025        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8026
 8027        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8028            *settings_changed_tx.borrow_mut() = ();
 8029        });
 8030
 8031        let mut joint_future =
 8032            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8033        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8034        // - 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).
 8035        // - 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.
 8036        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8037        // - 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,
 8038        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8039        cx.spawn(async move |this, cx| {
 8040            while let Some(()) = joint_future.next().await {
 8041                this.update(cx, |this, cx| {
 8042                    this.refresh_server_tree(cx);
 8043                })
 8044                .ok();
 8045
 8046                Self::refresh_workspace_configurations(&this, cx).await;
 8047            }
 8048
 8049            drop(settings_observation);
 8050            anyhow::Ok(())
 8051        })
 8052    }
 8053
 8054    pub fn running_language_servers_for_local_buffer<'a>(
 8055        &'a self,
 8056        buffer: &Buffer,
 8057        cx: &mut App,
 8058    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8059        let local = self.as_local();
 8060        let language_server_ids = local
 8061            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8062            .unwrap_or_default();
 8063
 8064        language_server_ids
 8065            .into_iter()
 8066            .filter_map(
 8067                move |server_id| match local?.language_servers.get(&server_id)? {
 8068                    LanguageServerState::Running {
 8069                        adapter, server, ..
 8070                    } => Some((adapter, server)),
 8071                    _ => None,
 8072                },
 8073            )
 8074    }
 8075
 8076    pub fn language_servers_for_local_buffer(
 8077        &self,
 8078        buffer: &Buffer,
 8079        cx: &mut App,
 8080    ) -> Vec<LanguageServerId> {
 8081        let local = self.as_local();
 8082        local
 8083            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8084            .unwrap_or_default()
 8085    }
 8086
 8087    pub fn language_server_for_local_buffer<'a>(
 8088        &'a self,
 8089        buffer: &'a Buffer,
 8090        server_id: LanguageServerId,
 8091        cx: &'a mut App,
 8092    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8093        self.as_local()?
 8094            .language_servers_for_buffer(buffer, cx)
 8095            .find(|(_, s)| s.server_id() == server_id)
 8096    }
 8097
 8098    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8099        self.diagnostic_summaries.remove(&id_to_remove);
 8100        if let Some(local) = self.as_local_mut() {
 8101            let to_remove = local.remove_worktree(id_to_remove, cx);
 8102            for server in to_remove {
 8103                self.language_server_statuses.remove(&server);
 8104            }
 8105        }
 8106    }
 8107
 8108    pub fn shared(
 8109        &mut self,
 8110        project_id: u64,
 8111        downstream_client: AnyProtoClient,
 8112        _: &mut Context<Self>,
 8113    ) {
 8114        self.downstream_client = Some((downstream_client.clone(), project_id));
 8115
 8116        for (server_id, status) in &self.language_server_statuses {
 8117            if let Some(server) = self.language_server_for_id(*server_id) {
 8118                downstream_client
 8119                    .send(proto::StartLanguageServer {
 8120                        project_id,
 8121                        server: Some(proto::LanguageServer {
 8122                            id: server_id.to_proto(),
 8123                            name: status.name.to_string(),
 8124                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8125                        }),
 8126                        capabilities: serde_json::to_string(&server.capabilities())
 8127                            .expect("serializing server LSP capabilities"),
 8128                    })
 8129                    .log_err();
 8130            }
 8131        }
 8132    }
 8133
 8134    pub fn disconnected_from_host(&mut self) {
 8135        self.downstream_client.take();
 8136    }
 8137
 8138    pub fn disconnected_from_ssh_remote(&mut self) {
 8139        if let LspStoreMode::Remote(RemoteLspStore {
 8140            upstream_client, ..
 8141        }) = &mut self.mode
 8142        {
 8143            upstream_client.take();
 8144        }
 8145    }
 8146
 8147    pub(crate) fn set_language_server_statuses_from_proto(
 8148        &mut self,
 8149        project: WeakEntity<Project>,
 8150        language_servers: Vec<proto::LanguageServer>,
 8151        server_capabilities: Vec<String>,
 8152        cx: &mut Context<Self>,
 8153    ) {
 8154        let lsp_logs = cx
 8155            .try_global::<GlobalLogStore>()
 8156            .map(|lsp_store| lsp_store.0.clone());
 8157
 8158        self.language_server_statuses = language_servers
 8159            .into_iter()
 8160            .zip(server_capabilities)
 8161            .map(|(server, server_capabilities)| {
 8162                let server_id = LanguageServerId(server.id as usize);
 8163                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8164                    self.lsp_server_capabilities
 8165                        .insert(server_id, server_capabilities);
 8166                }
 8167
 8168                let name = LanguageServerName::from_proto(server.name);
 8169                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8170
 8171                if let Some(lsp_logs) = &lsp_logs {
 8172                    lsp_logs.update(cx, |lsp_logs, cx| {
 8173                        lsp_logs.add_language_server(
 8174                            // Only remote clients get their language servers set from proto
 8175                            LanguageServerKind::Remote {
 8176                                project: project.clone(),
 8177                            },
 8178                            server_id,
 8179                            Some(name.clone()),
 8180                            worktree,
 8181                            None,
 8182                            cx,
 8183                        );
 8184                    });
 8185                }
 8186
 8187                (
 8188                    server_id,
 8189                    LanguageServerStatus {
 8190                        name,
 8191                        server_version: None,
 8192                        pending_work: Default::default(),
 8193                        has_pending_diagnostic_updates: false,
 8194                        progress_tokens: Default::default(),
 8195                        worktree,
 8196                        binary: None,
 8197                        configuration: None,
 8198                        workspace_folders: BTreeSet::new(),
 8199                        process_id: None,
 8200                    },
 8201                )
 8202            })
 8203            .collect();
 8204    }
 8205
 8206    #[cfg(feature = "test-support")]
 8207    pub fn update_diagnostic_entries(
 8208        &mut self,
 8209        server_id: LanguageServerId,
 8210        abs_path: PathBuf,
 8211        result_id: Option<SharedString>,
 8212        version: Option<i32>,
 8213        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8214        cx: &mut Context<Self>,
 8215    ) -> anyhow::Result<()> {
 8216        self.merge_diagnostic_entries(
 8217            vec![DocumentDiagnosticsUpdate {
 8218                diagnostics: DocumentDiagnostics {
 8219                    diagnostics,
 8220                    document_abs_path: abs_path,
 8221                    version,
 8222                },
 8223                result_id,
 8224                server_id,
 8225                disk_based_sources: Cow::Borrowed(&[]),
 8226                registration_id: None,
 8227            }],
 8228            |_, _, _| false,
 8229            cx,
 8230        )?;
 8231        Ok(())
 8232    }
 8233
 8234    pub fn merge_diagnostic_entries<'a>(
 8235        &mut self,
 8236        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8237        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8238        cx: &mut Context<Self>,
 8239    ) -> anyhow::Result<()> {
 8240        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8241        let mut updated_diagnostics_paths = HashMap::default();
 8242        for mut update in diagnostic_updates {
 8243            let abs_path = &update.diagnostics.document_abs_path;
 8244            let server_id = update.server_id;
 8245            let Some((worktree, relative_path)) =
 8246                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8247            else {
 8248                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8249                return Ok(());
 8250            };
 8251
 8252            let worktree_id = worktree.read(cx).id();
 8253            let project_path = ProjectPath {
 8254                worktree_id,
 8255                path: relative_path,
 8256            };
 8257
 8258            let document_uri = lsp::Uri::from_file_path(abs_path)
 8259                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8260            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8261                let snapshot = buffer_handle.read(cx).snapshot();
 8262                let buffer = buffer_handle.read(cx);
 8263                let reused_diagnostics = buffer
 8264                    .buffer_diagnostics(Some(server_id))
 8265                    .iter()
 8266                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8267                    .map(|v| {
 8268                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8269                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8270                        DiagnosticEntry {
 8271                            range: start..end,
 8272                            diagnostic: v.diagnostic.clone(),
 8273                        }
 8274                    })
 8275                    .collect::<Vec<_>>();
 8276
 8277                self.as_local_mut()
 8278                    .context("cannot merge diagnostics on a remote LspStore")?
 8279                    .update_buffer_diagnostics(
 8280                        &buffer_handle,
 8281                        server_id,
 8282                        Some(update.registration_id),
 8283                        update.result_id,
 8284                        update.diagnostics.version,
 8285                        update.diagnostics.diagnostics.clone(),
 8286                        reused_diagnostics.clone(),
 8287                        cx,
 8288                    )?;
 8289
 8290                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8291            } else if let Some(local) = self.as_local() {
 8292                let reused_diagnostics = local
 8293                    .diagnostics
 8294                    .get(&worktree_id)
 8295                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8296                    .and_then(|diagnostics_by_server_id| {
 8297                        diagnostics_by_server_id
 8298                            .binary_search_by_key(&server_id, |e| e.0)
 8299                            .ok()
 8300                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8301                    })
 8302                    .into_iter()
 8303                    .flatten()
 8304                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8305
 8306                update
 8307                    .diagnostics
 8308                    .diagnostics
 8309                    .extend(reused_diagnostics.cloned());
 8310            }
 8311
 8312            let updated = worktree.update(cx, |worktree, cx| {
 8313                self.update_worktree_diagnostics(
 8314                    worktree.id(),
 8315                    server_id,
 8316                    project_path.path.clone(),
 8317                    update.diagnostics.diagnostics,
 8318                    cx,
 8319                )
 8320            })?;
 8321            match updated {
 8322                ControlFlow::Continue(new_summary) => {
 8323                    if let Some((project_id, new_summary)) = new_summary {
 8324                        match &mut diagnostics_summary {
 8325                            Some(diagnostics_summary) => {
 8326                                diagnostics_summary
 8327                                    .more_summaries
 8328                                    .push(proto::DiagnosticSummary {
 8329                                        path: project_path.path.as_ref().to_proto(),
 8330                                        language_server_id: server_id.0 as u64,
 8331                                        error_count: new_summary.error_count,
 8332                                        warning_count: new_summary.warning_count,
 8333                                    })
 8334                            }
 8335                            None => {
 8336                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8337                                    project_id,
 8338                                    worktree_id: worktree_id.to_proto(),
 8339                                    summary: Some(proto::DiagnosticSummary {
 8340                                        path: project_path.path.as_ref().to_proto(),
 8341                                        language_server_id: server_id.0 as u64,
 8342                                        error_count: new_summary.error_count,
 8343                                        warning_count: new_summary.warning_count,
 8344                                    }),
 8345                                    more_summaries: Vec::new(),
 8346                                })
 8347                            }
 8348                        }
 8349                    }
 8350                    updated_diagnostics_paths
 8351                        .entry(server_id)
 8352                        .or_insert_with(Vec::new)
 8353                        .push(project_path);
 8354                }
 8355                ControlFlow::Break(()) => {}
 8356            }
 8357        }
 8358
 8359        if let Some((diagnostics_summary, (downstream_client, _))) =
 8360            diagnostics_summary.zip(self.downstream_client.as_ref())
 8361        {
 8362            downstream_client.send(diagnostics_summary).log_err();
 8363        }
 8364        for (server_id, paths) in updated_diagnostics_paths {
 8365            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8366        }
 8367        Ok(())
 8368    }
 8369
 8370    fn update_worktree_diagnostics(
 8371        &mut self,
 8372        worktree_id: WorktreeId,
 8373        server_id: LanguageServerId,
 8374        path_in_worktree: Arc<RelPath>,
 8375        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8376        _: &mut Context<Worktree>,
 8377    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8378        let local = match &mut self.mode {
 8379            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8380            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8381        };
 8382
 8383        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8384        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8385        let summaries_by_server_id = summaries_for_tree
 8386            .entry(path_in_worktree.clone())
 8387            .or_default();
 8388
 8389        let old_summary = summaries_by_server_id
 8390            .remove(&server_id)
 8391            .unwrap_or_default();
 8392
 8393        let new_summary = DiagnosticSummary::new(&diagnostics);
 8394        if diagnostics.is_empty() {
 8395            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8396            {
 8397                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8398                    diagnostics_by_server_id.remove(ix);
 8399                }
 8400                if diagnostics_by_server_id.is_empty() {
 8401                    diagnostics_for_tree.remove(&path_in_worktree);
 8402                }
 8403            }
 8404        } else {
 8405            summaries_by_server_id.insert(server_id, new_summary);
 8406            let diagnostics_by_server_id = diagnostics_for_tree
 8407                .entry(path_in_worktree.clone())
 8408                .or_default();
 8409            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8410                Ok(ix) => {
 8411                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8412                }
 8413                Err(ix) => {
 8414                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8415                }
 8416            }
 8417        }
 8418
 8419        if !old_summary.is_empty() || !new_summary.is_empty() {
 8420            if let Some((_, project_id)) = &self.downstream_client {
 8421                Ok(ControlFlow::Continue(Some((
 8422                    *project_id,
 8423                    proto::DiagnosticSummary {
 8424                        path: path_in_worktree.to_proto(),
 8425                        language_server_id: server_id.0 as u64,
 8426                        error_count: new_summary.error_count as u32,
 8427                        warning_count: new_summary.warning_count as u32,
 8428                    },
 8429                ))))
 8430            } else {
 8431                Ok(ControlFlow::Continue(None))
 8432            }
 8433        } else {
 8434            Ok(ControlFlow::Break(()))
 8435        }
 8436    }
 8437
 8438    pub fn open_buffer_for_symbol(
 8439        &mut self,
 8440        symbol: &Symbol,
 8441        cx: &mut Context<Self>,
 8442    ) -> Task<Result<Entity<Buffer>>> {
 8443        if let Some((client, project_id)) = self.upstream_client() {
 8444            let request = client.request(proto::OpenBufferForSymbol {
 8445                project_id,
 8446                symbol: Some(Self::serialize_symbol(symbol)),
 8447            });
 8448            cx.spawn(async move |this, cx| {
 8449                let response = request.await?;
 8450                let buffer_id = BufferId::new(response.buffer_id)?;
 8451                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8452                    .await
 8453            })
 8454        } else if let Some(local) = self.as_local() {
 8455            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8456                seed.worktree_id == symbol.source_worktree_id
 8457                    && state.id == symbol.source_language_server_id
 8458                    && symbol.language_server_name == seed.name
 8459            });
 8460            if !is_valid {
 8461                return Task::ready(Err(anyhow!(
 8462                    "language server for worktree and language not found"
 8463                )));
 8464            };
 8465
 8466            let symbol_abs_path = match &symbol.path {
 8467                SymbolLocation::InProject(project_path) => self
 8468                    .worktree_store
 8469                    .read(cx)
 8470                    .absolutize(&project_path, cx)
 8471                    .context("no such worktree"),
 8472                SymbolLocation::OutsideProject {
 8473                    abs_path,
 8474                    signature: _,
 8475                } => Ok(abs_path.to_path_buf()),
 8476            };
 8477            let symbol_abs_path = match symbol_abs_path {
 8478                Ok(abs_path) => abs_path,
 8479                Err(err) => return Task::ready(Err(err)),
 8480            };
 8481            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8482                uri
 8483            } else {
 8484                return Task::ready(Err(anyhow!("invalid symbol path")));
 8485            };
 8486
 8487            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8488        } else {
 8489            Task::ready(Err(anyhow!("no upstream client or local store")))
 8490        }
 8491    }
 8492
 8493    pub(crate) fn open_local_buffer_via_lsp(
 8494        &mut self,
 8495        abs_path: lsp::Uri,
 8496        language_server_id: LanguageServerId,
 8497        cx: &mut Context<Self>,
 8498    ) -> Task<Result<Entity<Buffer>>> {
 8499        let path_style = self.worktree_store.read(cx).path_style();
 8500        cx.spawn(async move |lsp_store, cx| {
 8501            // Escape percent-encoded string.
 8502            let current_scheme = abs_path.scheme().to_owned();
 8503            // Uri is immutable, so we can't modify the scheme
 8504
 8505            let abs_path = abs_path
 8506                .to_file_path_ext(path_style)
 8507                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8508            let p = abs_path.clone();
 8509            let yarn_worktree = lsp_store
 8510                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8511                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8512                        cx.spawn(async move |this, cx| {
 8513                            let t = this
 8514                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8515                                .ok()?;
 8516                            t.await
 8517                        })
 8518                    }),
 8519                    None => Task::ready(None),
 8520                })?
 8521                .await;
 8522            let (worktree_root_target, known_relative_path) =
 8523                if let Some((zip_root, relative_path)) = yarn_worktree {
 8524                    (zip_root, Some(relative_path))
 8525                } else {
 8526                    (Arc::<Path>::from(abs_path.as_path()), None)
 8527                };
 8528            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8529                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8530                    worktree_store.find_worktree(&worktree_root_target, cx)
 8531                })
 8532            })?;
 8533            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8534                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8535                (result.0, relative_path, None)
 8536            } else {
 8537                let worktree = lsp_store
 8538                    .update(cx, |lsp_store, cx| {
 8539                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8540                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8541                        })
 8542                    })?
 8543                    .await?;
 8544                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8545                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8546                    lsp_store
 8547                        .update(cx, |lsp_store, cx| {
 8548                            if let Some(local) = lsp_store.as_local_mut() {
 8549                                local.register_language_server_for_invisible_worktree(
 8550                                    &worktree,
 8551                                    language_server_id,
 8552                                    cx,
 8553                                )
 8554                            }
 8555                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8556                                Some(status) => status.worktree,
 8557                                None => None,
 8558                            }
 8559                        })
 8560                        .ok()
 8561                        .flatten()
 8562                        .zip(Some(worktree_root.clone()))
 8563                } else {
 8564                    None
 8565                };
 8566                let relative_path = if let Some(known_path) = known_relative_path {
 8567                    known_path
 8568                } else {
 8569                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8570                        .into_arc()
 8571                };
 8572                (worktree, relative_path, source_ws)
 8573            };
 8574            let project_path = ProjectPath {
 8575                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8576                path: relative_path,
 8577            };
 8578            let buffer = lsp_store
 8579                .update(cx, |lsp_store, cx| {
 8580                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8581                        buffer_store.open_buffer(project_path, cx)
 8582                    })
 8583                })?
 8584                .await?;
 8585            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8586            if let Some((source_ws, worktree_root)) = source_ws {
 8587                buffer.update(cx, |buffer, cx| {
 8588                    let settings = WorktreeSettings::get(
 8589                        Some(
 8590                            (&ProjectPath {
 8591                                worktree_id: source_ws,
 8592                                path: Arc::from(RelPath::empty()),
 8593                            })
 8594                                .into(),
 8595                        ),
 8596                        cx,
 8597                    );
 8598                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8599                    if is_read_only {
 8600                        buffer.set_capability(Capability::ReadOnly, cx);
 8601                    }
 8602                });
 8603            }
 8604            Ok(buffer)
 8605        })
 8606    }
 8607
 8608    fn local_lsp_servers_for_buffer(
 8609        &self,
 8610        buffer: &Entity<Buffer>,
 8611        cx: &mut Context<Self>,
 8612    ) -> Vec<LanguageServerId> {
 8613        let Some(local) = self.as_local() else {
 8614            return Vec::new();
 8615        };
 8616
 8617        let snapshot = buffer.read(cx).snapshot();
 8618
 8619        buffer.update(cx, |buffer, cx| {
 8620            local
 8621                .language_servers_for_buffer(buffer, cx)
 8622                .map(|(_, server)| server.server_id())
 8623                .filter(|server_id| {
 8624                    self.as_local().is_none_or(|local| {
 8625                        local
 8626                            .buffers_opened_in_servers
 8627                            .get(&snapshot.remote_id())
 8628                            .is_some_and(|servers| servers.contains(server_id))
 8629                    })
 8630                })
 8631                .collect()
 8632        })
 8633    }
 8634
 8635    fn request_multiple_lsp_locally<P, R>(
 8636        &mut self,
 8637        buffer: &Entity<Buffer>,
 8638        position: Option<P>,
 8639        request: R,
 8640        cx: &mut Context<Self>,
 8641    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8642    where
 8643        P: ToOffset,
 8644        R: LspCommand + Clone,
 8645        <R::LspRequest as lsp::request::Request>::Result: Send,
 8646        <R::LspRequest as lsp::request::Request>::Params: Send,
 8647    {
 8648        let Some(local) = self.as_local() else {
 8649            return Task::ready(Vec::new());
 8650        };
 8651
 8652        let snapshot = buffer.read(cx).snapshot();
 8653        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8654
 8655        let server_ids = buffer.update(cx, |buffer, cx| {
 8656            local
 8657                .language_servers_for_buffer(buffer, cx)
 8658                .filter(|(adapter, _)| {
 8659                    scope
 8660                        .as_ref()
 8661                        .map(|scope| scope.language_allowed(&adapter.name))
 8662                        .unwrap_or(true)
 8663                })
 8664                .map(|(_, server)| server.server_id())
 8665                .filter(|server_id| {
 8666                    self.as_local().is_none_or(|local| {
 8667                        local
 8668                            .buffers_opened_in_servers
 8669                            .get(&snapshot.remote_id())
 8670                            .is_some_and(|servers| servers.contains(server_id))
 8671                    })
 8672                })
 8673                .collect::<Vec<_>>()
 8674        });
 8675
 8676        let mut response_results = server_ids
 8677            .into_iter()
 8678            .map(|server_id| {
 8679                let task = self.request_lsp(
 8680                    buffer.clone(),
 8681                    LanguageServerToQuery::Other(server_id),
 8682                    request.clone(),
 8683                    cx,
 8684                );
 8685                async move { (server_id, task.await) }
 8686            })
 8687            .collect::<FuturesUnordered<_>>();
 8688
 8689        cx.background_spawn(async move {
 8690            let mut responses = Vec::with_capacity(response_results.len());
 8691            while let Some((server_id, response_result)) = response_results.next().await {
 8692                match response_result {
 8693                    Ok(response) => responses.push((server_id, response)),
 8694                    // rust-analyzer likes to error with this when its still loading up
 8695                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8696                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8697                }
 8698            }
 8699            responses
 8700        })
 8701    }
 8702
 8703    async fn handle_lsp_get_completions(
 8704        this: Entity<Self>,
 8705        envelope: TypedEnvelope<proto::GetCompletions>,
 8706        mut cx: AsyncApp,
 8707    ) -> Result<proto::GetCompletionsResponse> {
 8708        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8709
 8710        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8711        let buffer_handle = this.update(&mut cx, |this, cx| {
 8712            this.buffer_store.read(cx).get_existing(buffer_id)
 8713        })?;
 8714        let request = GetCompletions::from_proto(
 8715            envelope.payload,
 8716            this.clone(),
 8717            buffer_handle.clone(),
 8718            cx.clone(),
 8719        )
 8720        .await?;
 8721
 8722        let server_to_query = match request.server_id {
 8723            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8724            None => LanguageServerToQuery::FirstCapable,
 8725        };
 8726
 8727        let response = this
 8728            .update(&mut cx, |this, cx| {
 8729                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8730            })
 8731            .await?;
 8732        this.update(&mut cx, |this, cx| {
 8733            Ok(GetCompletions::response_to_proto(
 8734                response,
 8735                this,
 8736                sender_id,
 8737                &buffer_handle.read(cx).version(),
 8738                cx,
 8739            ))
 8740        })
 8741    }
 8742
 8743    async fn handle_lsp_command<T: LspCommand>(
 8744        this: Entity<Self>,
 8745        envelope: TypedEnvelope<T::ProtoRequest>,
 8746        mut cx: AsyncApp,
 8747    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8748    where
 8749        <T::LspRequest as lsp::request::Request>::Params: Send,
 8750        <T::LspRequest as lsp::request::Request>::Result: Send,
 8751    {
 8752        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8753        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8754        let buffer_handle = this.update(&mut cx, |this, cx| {
 8755            this.buffer_store.read(cx).get_existing(buffer_id)
 8756        })?;
 8757        let request = T::from_proto(
 8758            envelope.payload,
 8759            this.clone(),
 8760            buffer_handle.clone(),
 8761            cx.clone(),
 8762        )
 8763        .await?;
 8764        let response = this
 8765            .update(&mut cx, |this, cx| {
 8766                this.request_lsp(
 8767                    buffer_handle.clone(),
 8768                    LanguageServerToQuery::FirstCapable,
 8769                    request,
 8770                    cx,
 8771                )
 8772            })
 8773            .await?;
 8774        this.update(&mut cx, |this, cx| {
 8775            Ok(T::response_to_proto(
 8776                response,
 8777                this,
 8778                sender_id,
 8779                &buffer_handle.read(cx).version(),
 8780                cx,
 8781            ))
 8782        })
 8783    }
 8784
 8785    async fn handle_lsp_query(
 8786        lsp_store: Entity<Self>,
 8787        envelope: TypedEnvelope<proto::LspQuery>,
 8788        mut cx: AsyncApp,
 8789    ) -> Result<proto::Ack> {
 8790        use proto::lsp_query::Request;
 8791        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8792        let lsp_query = envelope.payload;
 8793        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8794        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8795        match lsp_query.request.context("invalid LSP query request")? {
 8796            Request::GetReferences(get_references) => {
 8797                let position = get_references.position.clone().and_then(deserialize_anchor);
 8798                Self::query_lsp_locally::<GetReferences>(
 8799                    lsp_store,
 8800                    server_id,
 8801                    sender_id,
 8802                    lsp_request_id,
 8803                    get_references,
 8804                    position,
 8805                    &mut cx,
 8806                )
 8807                .await?;
 8808            }
 8809            Request::GetDocumentColor(get_document_color) => {
 8810                Self::query_lsp_locally::<GetDocumentColor>(
 8811                    lsp_store,
 8812                    server_id,
 8813                    sender_id,
 8814                    lsp_request_id,
 8815                    get_document_color,
 8816                    None,
 8817                    &mut cx,
 8818                )
 8819                .await?;
 8820            }
 8821            Request::GetFoldingRanges(get_folding_ranges) => {
 8822                Self::query_lsp_locally::<GetFoldingRanges>(
 8823                    lsp_store,
 8824                    server_id,
 8825                    sender_id,
 8826                    lsp_request_id,
 8827                    get_folding_ranges,
 8828                    None,
 8829                    &mut cx,
 8830                )
 8831                .await?;
 8832            }
 8833            Request::GetDocumentSymbols(get_document_symbols) => {
 8834                Self::query_lsp_locally::<GetDocumentSymbols>(
 8835                    lsp_store,
 8836                    server_id,
 8837                    sender_id,
 8838                    lsp_request_id,
 8839                    get_document_symbols,
 8840                    None,
 8841                    &mut cx,
 8842                )
 8843                .await?;
 8844            }
 8845            Request::GetHover(get_hover) => {
 8846                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8847                Self::query_lsp_locally::<GetHover>(
 8848                    lsp_store,
 8849                    server_id,
 8850                    sender_id,
 8851                    lsp_request_id,
 8852                    get_hover,
 8853                    position,
 8854                    &mut cx,
 8855                )
 8856                .await?;
 8857            }
 8858            Request::GetCodeActions(get_code_actions) => {
 8859                Self::query_lsp_locally::<GetCodeActions>(
 8860                    lsp_store,
 8861                    server_id,
 8862                    sender_id,
 8863                    lsp_request_id,
 8864                    get_code_actions,
 8865                    None,
 8866                    &mut cx,
 8867                )
 8868                .await?;
 8869            }
 8870            Request::GetSignatureHelp(get_signature_help) => {
 8871                let position = get_signature_help
 8872                    .position
 8873                    .clone()
 8874                    .and_then(deserialize_anchor);
 8875                Self::query_lsp_locally::<GetSignatureHelp>(
 8876                    lsp_store,
 8877                    server_id,
 8878                    sender_id,
 8879                    lsp_request_id,
 8880                    get_signature_help,
 8881                    position,
 8882                    &mut cx,
 8883                )
 8884                .await?;
 8885            }
 8886            Request::GetCodeLens(get_code_lens) => {
 8887                Self::query_lsp_locally::<GetCodeLens>(
 8888                    lsp_store,
 8889                    server_id,
 8890                    sender_id,
 8891                    lsp_request_id,
 8892                    get_code_lens,
 8893                    None,
 8894                    &mut cx,
 8895                )
 8896                .await?;
 8897            }
 8898            Request::GetDefinition(get_definition) => {
 8899                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8900                Self::query_lsp_locally::<GetDefinitions>(
 8901                    lsp_store,
 8902                    server_id,
 8903                    sender_id,
 8904                    lsp_request_id,
 8905                    get_definition,
 8906                    position,
 8907                    &mut cx,
 8908                )
 8909                .await?;
 8910            }
 8911            Request::GetDeclaration(get_declaration) => {
 8912                let position = get_declaration
 8913                    .position
 8914                    .clone()
 8915                    .and_then(deserialize_anchor);
 8916                Self::query_lsp_locally::<GetDeclarations>(
 8917                    lsp_store,
 8918                    server_id,
 8919                    sender_id,
 8920                    lsp_request_id,
 8921                    get_declaration,
 8922                    position,
 8923                    &mut cx,
 8924                )
 8925                .await?;
 8926            }
 8927            Request::GetTypeDefinition(get_type_definition) => {
 8928                let position = get_type_definition
 8929                    .position
 8930                    .clone()
 8931                    .and_then(deserialize_anchor);
 8932                Self::query_lsp_locally::<GetTypeDefinitions>(
 8933                    lsp_store,
 8934                    server_id,
 8935                    sender_id,
 8936                    lsp_request_id,
 8937                    get_type_definition,
 8938                    position,
 8939                    &mut cx,
 8940                )
 8941                .await?;
 8942            }
 8943            Request::GetImplementation(get_implementation) => {
 8944                let position = get_implementation
 8945                    .position
 8946                    .clone()
 8947                    .and_then(deserialize_anchor);
 8948                Self::query_lsp_locally::<GetImplementations>(
 8949                    lsp_store,
 8950                    server_id,
 8951                    sender_id,
 8952                    lsp_request_id,
 8953                    get_implementation,
 8954                    position,
 8955                    &mut cx,
 8956                )
 8957                .await?;
 8958            }
 8959            Request::InlayHints(inlay_hints) => {
 8960                let query_start = inlay_hints
 8961                    .start
 8962                    .clone()
 8963                    .and_then(deserialize_anchor)
 8964                    .context("invalid inlay hints range start")?;
 8965                let query_end = inlay_hints
 8966                    .end
 8967                    .clone()
 8968                    .and_then(deserialize_anchor)
 8969                    .context("invalid inlay hints range end")?;
 8970                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 8971                    &lsp_store,
 8972                    server_id,
 8973                    lsp_request_id,
 8974                    &inlay_hints,
 8975                    query_start..query_end,
 8976                    &mut cx,
 8977                )
 8978                .await
 8979                .context("preparing inlay hints request")?;
 8980                Self::query_lsp_locally::<InlayHints>(
 8981                    lsp_store,
 8982                    server_id,
 8983                    sender_id,
 8984                    lsp_request_id,
 8985                    inlay_hints,
 8986                    None,
 8987                    &mut cx,
 8988                )
 8989                .await
 8990                .context("querying for inlay hints")?
 8991            }
 8992            //////////////////////////////
 8993            // Below are LSP queries that need to fetch more data,
 8994            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 8995            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8996                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 8997                    &lsp_store,
 8998                    &get_document_diagnostics,
 8999                    &mut cx,
 9000                )
 9001                .await?;
 9002                lsp_store.update(&mut cx, |lsp_store, cx| {
 9003                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9004                    let key = LspKey {
 9005                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9006                        server_queried: server_id,
 9007                    };
 9008                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9009                    ) {
 9010                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9011                            lsp_requests.clear();
 9012                        };
 9013                    }
 9014
 9015                    lsp_data.lsp_requests.entry(key).or_default().insert(
 9016                        lsp_request_id,
 9017                        cx.spawn(async move |lsp_store, cx| {
 9018                            let diagnostics_pull = lsp_store
 9019                                .update(cx, |lsp_store, cx| {
 9020                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9021                                })
 9022                                .ok();
 9023                            if let Some(diagnostics_pull) = diagnostics_pull {
 9024                                match diagnostics_pull.await {
 9025                                    Ok(()) => {}
 9026                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9027                                };
 9028                            }
 9029                        }),
 9030                    );
 9031                });
 9032            }
 9033            Request::SemanticTokens(semantic_tokens) => {
 9034                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 9035                    &lsp_store,
 9036                    &semantic_tokens,
 9037                    &mut cx,
 9038                )
 9039                .await?;
 9040                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9041                lsp_store.update(&mut cx, |lsp_store, cx| {
 9042                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9043                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9044                        let key = LspKey {
 9045                            request_type: TypeId::of::<SemanticTokensFull>(),
 9046                            server_queried: server_id,
 9047                        };
 9048                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9049                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9050                                lsp_requests.clear();
 9051                            };
 9052                        }
 9053
 9054                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9055                            lsp_request_id,
 9056                            cx.spawn(async move |lsp_store, cx| {
 9057                                let tokens_fetch = lsp_store
 9058                                    .update(cx, |lsp_store, cx| {
 9059                                        lsp_store
 9060                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9061                                    })
 9062                                    .ok();
 9063                                if let Some(tokens_fetch) = tokens_fetch {
 9064                                    let new_tokens = tokens_fetch.await;
 9065                                    if let Some(new_tokens) = new_tokens {
 9066                                        lsp_store
 9067                                            .update(cx, |lsp_store, cx| {
 9068                                                let response = new_tokens
 9069                                                    .into_iter()
 9070                                                    .map(|(server_id, response)| {
 9071                                                        (
 9072                                                            server_id.to_proto(),
 9073                                                            SemanticTokensFull::response_to_proto(
 9074                                                                response,
 9075                                                                lsp_store,
 9076                                                                sender_id,
 9077                                                                &buffer_version,
 9078                                                                cx,
 9079                                                            ),
 9080                                                        )
 9081                                                    })
 9082                                                    .collect::<HashMap<_, _>>();
 9083                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9084                                                    project_id,
 9085                                                    lsp_request_id,
 9086                                                    response,
 9087                                                ) {
 9088                                                    Ok(()) => {}
 9089                                                    Err(e) => {
 9090                                                        log::error!(
 9091                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9092                                                        )
 9093                                                    }
 9094                                                }
 9095                                            })
 9096                                            .ok();
 9097                                    }
 9098                                }
 9099                            }),
 9100                        );
 9101                    }
 9102                });
 9103            }
 9104        }
 9105        Ok(proto::Ack {})
 9106    }
 9107
 9108    async fn handle_lsp_query_response(
 9109        lsp_store: Entity<Self>,
 9110        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9111        cx: AsyncApp,
 9112    ) -> Result<()> {
 9113        lsp_store.read_with(&cx, |lsp_store, _| {
 9114            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9115                upstream_client.handle_lsp_response(envelope.clone());
 9116            }
 9117        });
 9118        Ok(())
 9119    }
 9120
 9121    async fn handle_apply_code_action(
 9122        this: Entity<Self>,
 9123        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9124        mut cx: AsyncApp,
 9125    ) -> Result<proto::ApplyCodeActionResponse> {
 9126        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9127        let action =
 9128            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9129        let apply_code_action = this.update(&mut cx, |this, cx| {
 9130            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9131            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9132            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9133        })?;
 9134
 9135        let project_transaction = apply_code_action.await?;
 9136        let project_transaction = this.update(&mut cx, |this, cx| {
 9137            this.buffer_store.update(cx, |buffer_store, cx| {
 9138                buffer_store.serialize_project_transaction_for_peer(
 9139                    project_transaction,
 9140                    sender_id,
 9141                    cx,
 9142                )
 9143            })
 9144        });
 9145        Ok(proto::ApplyCodeActionResponse {
 9146            transaction: Some(project_transaction),
 9147        })
 9148    }
 9149
 9150    async fn handle_register_buffer_with_language_servers(
 9151        this: Entity<Self>,
 9152        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9153        mut cx: AsyncApp,
 9154    ) -> Result<proto::Ack> {
 9155        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9156        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9157        this.update(&mut cx, |this, cx| {
 9158            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9159                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9160                    project_id: upstream_project_id,
 9161                    buffer_id: buffer_id.to_proto(),
 9162                    only_servers: envelope.payload.only_servers,
 9163                });
 9164            }
 9165
 9166            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9167                anyhow::bail!("buffer is not open");
 9168            };
 9169
 9170            let handle = this.register_buffer_with_language_servers(
 9171                &buffer,
 9172                envelope
 9173                    .payload
 9174                    .only_servers
 9175                    .into_iter()
 9176                    .filter_map(|selector| {
 9177                        Some(match selector.selector? {
 9178                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9179                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9180                            }
 9181                            proto::language_server_selector::Selector::Name(name) => {
 9182                                LanguageServerSelector::Name(LanguageServerName(
 9183                                    SharedString::from(name),
 9184                                ))
 9185                            }
 9186                        })
 9187                    })
 9188                    .collect(),
 9189                false,
 9190                cx,
 9191            );
 9192            // Pull diagnostics for the buffer even if it was already registered.
 9193            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9194            // but it's unclear if we need it.
 9195            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9196                .detach();
 9197            this.buffer_store().update(cx, |buffer_store, _| {
 9198                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9199            });
 9200
 9201            Ok(())
 9202        })?;
 9203        Ok(proto::Ack {})
 9204    }
 9205
 9206    async fn handle_rename_project_entry(
 9207        this: Entity<Self>,
 9208        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9209        mut cx: AsyncApp,
 9210    ) -> Result<proto::ProjectEntryResponse> {
 9211        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9212        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9213        let new_path =
 9214            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9215
 9216        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9217            .update(&mut cx, |this, cx| {
 9218                let (worktree, entry) = this
 9219                    .worktree_store
 9220                    .read(cx)
 9221                    .worktree_and_entry_for_id(entry_id, cx)?;
 9222                let new_worktree = this
 9223                    .worktree_store
 9224                    .read(cx)
 9225                    .worktree_for_id(new_worktree_id, cx)?;
 9226                Some((
 9227                    this.worktree_store.clone(),
 9228                    worktree,
 9229                    new_worktree,
 9230                    entry.clone(),
 9231                ))
 9232            })
 9233            .context("worktree not found")?;
 9234        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9235            (worktree.absolutize(&old_entry.path), worktree.id())
 9236        });
 9237        let new_abs_path =
 9238            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9239
 9240        let _transaction = Self::will_rename_entry(
 9241            this.downgrade(),
 9242            old_worktree_id,
 9243            &old_abs_path,
 9244            &new_abs_path,
 9245            old_entry.is_dir(),
 9246            cx.clone(),
 9247        )
 9248        .await;
 9249        let response = WorktreeStore::handle_rename_project_entry(
 9250            worktree_store,
 9251            envelope.payload,
 9252            cx.clone(),
 9253        )
 9254        .await;
 9255        this.read_with(&cx, |this, _| {
 9256            this.did_rename_entry(
 9257                old_worktree_id,
 9258                &old_abs_path,
 9259                &new_abs_path,
 9260                old_entry.is_dir(),
 9261            );
 9262        });
 9263        response
 9264    }
 9265
 9266    async fn handle_update_diagnostic_summary(
 9267        this: Entity<Self>,
 9268        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9269        mut cx: AsyncApp,
 9270    ) -> Result<()> {
 9271        this.update(&mut cx, |lsp_store, cx| {
 9272            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9273            let mut updated_diagnostics_paths = HashMap::default();
 9274            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9275            for message_summary in envelope
 9276                .payload
 9277                .summary
 9278                .into_iter()
 9279                .chain(envelope.payload.more_summaries)
 9280            {
 9281                let project_path = ProjectPath {
 9282                    worktree_id,
 9283                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9284                };
 9285                let path = project_path.path.clone();
 9286                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9287                let summary = DiagnosticSummary {
 9288                    error_count: message_summary.error_count as usize,
 9289                    warning_count: message_summary.warning_count as usize,
 9290                };
 9291
 9292                if summary.is_empty() {
 9293                    if let Some(worktree_summaries) =
 9294                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9295                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9296                    {
 9297                        summaries.remove(&server_id);
 9298                        if summaries.is_empty() {
 9299                            worktree_summaries.remove(&path);
 9300                        }
 9301                    }
 9302                } else {
 9303                    lsp_store
 9304                        .diagnostic_summaries
 9305                        .entry(worktree_id)
 9306                        .or_default()
 9307                        .entry(path)
 9308                        .or_default()
 9309                        .insert(server_id, summary);
 9310                }
 9311
 9312                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9313                    match &mut diagnostics_summary {
 9314                        Some(diagnostics_summary) => {
 9315                            diagnostics_summary
 9316                                .more_summaries
 9317                                .push(proto::DiagnosticSummary {
 9318                                    path: project_path.path.as_ref().to_proto(),
 9319                                    language_server_id: server_id.0 as u64,
 9320                                    error_count: summary.error_count as u32,
 9321                                    warning_count: summary.warning_count as u32,
 9322                                })
 9323                        }
 9324                        None => {
 9325                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9326                                project_id: *project_id,
 9327                                worktree_id: worktree_id.to_proto(),
 9328                                summary: Some(proto::DiagnosticSummary {
 9329                                    path: project_path.path.as_ref().to_proto(),
 9330                                    language_server_id: server_id.0 as u64,
 9331                                    error_count: summary.error_count as u32,
 9332                                    warning_count: summary.warning_count as u32,
 9333                                }),
 9334                                more_summaries: Vec::new(),
 9335                            })
 9336                        }
 9337                    }
 9338                }
 9339                updated_diagnostics_paths
 9340                    .entry(server_id)
 9341                    .or_insert_with(Vec::new)
 9342                    .push(project_path);
 9343            }
 9344
 9345            if let Some((diagnostics_summary, (downstream_client, _))) =
 9346                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9347            {
 9348                downstream_client.send(diagnostics_summary).log_err();
 9349            }
 9350            for (server_id, paths) in updated_diagnostics_paths {
 9351                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9352            }
 9353            Ok(())
 9354        })
 9355    }
 9356
 9357    async fn handle_start_language_server(
 9358        lsp_store: Entity<Self>,
 9359        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9360        mut cx: AsyncApp,
 9361    ) -> Result<()> {
 9362        let server = envelope.payload.server.context("invalid server")?;
 9363        let server_capabilities =
 9364            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9365                .with_context(|| {
 9366                    format!(
 9367                        "incorrect server capabilities {}",
 9368                        envelope.payload.capabilities
 9369                    )
 9370                })?;
 9371        lsp_store.update(&mut cx, |lsp_store, cx| {
 9372            let server_id = LanguageServerId(server.id as usize);
 9373            let server_name = LanguageServerName::from_proto(server.name.clone());
 9374            lsp_store
 9375                .lsp_server_capabilities
 9376                .insert(server_id, server_capabilities);
 9377            lsp_store.language_server_statuses.insert(
 9378                server_id,
 9379                LanguageServerStatus {
 9380                    name: server_name.clone(),
 9381                    server_version: None,
 9382                    pending_work: Default::default(),
 9383                    has_pending_diagnostic_updates: false,
 9384                    progress_tokens: Default::default(),
 9385                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9386                    binary: None,
 9387                    configuration: None,
 9388                    workspace_folders: BTreeSet::new(),
 9389                    process_id: None,
 9390                },
 9391            );
 9392            cx.emit(LspStoreEvent::LanguageServerAdded(
 9393                server_id,
 9394                server_name,
 9395                server.worktree_id.map(WorktreeId::from_proto),
 9396            ));
 9397            cx.notify();
 9398        });
 9399        Ok(())
 9400    }
 9401
 9402    async fn handle_update_language_server(
 9403        lsp_store: Entity<Self>,
 9404        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9405        mut cx: AsyncApp,
 9406    ) -> Result<()> {
 9407        lsp_store.update(&mut cx, |lsp_store, cx| {
 9408            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9409
 9410            match envelope.payload.variant.context("invalid variant")? {
 9411                proto::update_language_server::Variant::WorkStart(payload) => {
 9412                    lsp_store.on_lsp_work_start(
 9413                        language_server_id,
 9414                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9415                            .context("invalid progress token value")?,
 9416                        LanguageServerProgress {
 9417                            title: payload.title,
 9418                            is_disk_based_diagnostics_progress: false,
 9419                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9420                            message: payload.message,
 9421                            percentage: payload.percentage.map(|p| p as usize),
 9422                            last_update_at: cx.background_executor().now(),
 9423                        },
 9424                        cx,
 9425                    );
 9426                }
 9427                proto::update_language_server::Variant::WorkProgress(payload) => {
 9428                    lsp_store.on_lsp_work_progress(
 9429                        language_server_id,
 9430                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9431                            .context("invalid progress token value")?,
 9432                        LanguageServerProgress {
 9433                            title: None,
 9434                            is_disk_based_diagnostics_progress: false,
 9435                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9436                            message: payload.message,
 9437                            percentage: payload.percentage.map(|p| p as usize),
 9438                            last_update_at: cx.background_executor().now(),
 9439                        },
 9440                        cx,
 9441                    );
 9442                }
 9443
 9444                proto::update_language_server::Variant::WorkEnd(payload) => {
 9445                    lsp_store.on_lsp_work_end(
 9446                        language_server_id,
 9447                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9448                            .context("invalid progress token value")?,
 9449                        cx,
 9450                    );
 9451                }
 9452
 9453                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9454                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9455                }
 9456
 9457                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9458                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9459                }
 9460
 9461                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9462                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9463                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9464                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9465                        language_server_id,
 9466                        name: envelope
 9467                            .payload
 9468                            .server_name
 9469                            .map(SharedString::new)
 9470                            .map(LanguageServerName),
 9471                        message: non_lsp,
 9472                    });
 9473                }
 9474            }
 9475
 9476            Ok(())
 9477        })
 9478    }
 9479
 9480    async fn handle_language_server_log(
 9481        this: Entity<Self>,
 9482        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9483        mut cx: AsyncApp,
 9484    ) -> Result<()> {
 9485        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9486        let log_type = envelope
 9487            .payload
 9488            .log_type
 9489            .map(LanguageServerLogType::from_proto)
 9490            .context("invalid language server log type")?;
 9491
 9492        let message = envelope.payload.message;
 9493
 9494        this.update(&mut cx, |_, cx| {
 9495            cx.emit(LspStoreEvent::LanguageServerLog(
 9496                language_server_id,
 9497                log_type,
 9498                message,
 9499            ));
 9500        });
 9501        Ok(())
 9502    }
 9503
 9504    async fn handle_lsp_ext_cancel_flycheck(
 9505        lsp_store: Entity<Self>,
 9506        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9507        cx: AsyncApp,
 9508    ) -> Result<proto::Ack> {
 9509        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9510        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9511            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9512                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9513            } else {
 9514                None
 9515            }
 9516        });
 9517        if let Some(task) = task {
 9518            task.context("handling lsp ext cancel flycheck")?;
 9519        }
 9520
 9521        Ok(proto::Ack {})
 9522    }
 9523
 9524    async fn handle_lsp_ext_run_flycheck(
 9525        lsp_store: Entity<Self>,
 9526        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9527        mut cx: AsyncApp,
 9528    ) -> Result<proto::Ack> {
 9529        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9530        lsp_store.update(&mut cx, |lsp_store, cx| {
 9531            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9532                let text_document = if envelope.payload.current_file_only {
 9533                    let buffer_id = envelope
 9534                        .payload
 9535                        .buffer_id
 9536                        .map(|id| BufferId::new(id))
 9537                        .transpose()?;
 9538                    buffer_id
 9539                        .and_then(|buffer_id| {
 9540                            lsp_store
 9541                                .buffer_store()
 9542                                .read(cx)
 9543                                .get(buffer_id)
 9544                                .and_then(|buffer| {
 9545                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9546                                })
 9547                                .map(|path| make_text_document_identifier(&path))
 9548                        })
 9549                        .transpose()?
 9550                } else {
 9551                    None
 9552                };
 9553                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9554                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9555                )?;
 9556            }
 9557            anyhow::Ok(())
 9558        })?;
 9559
 9560        Ok(proto::Ack {})
 9561    }
 9562
 9563    async fn handle_lsp_ext_clear_flycheck(
 9564        lsp_store: Entity<Self>,
 9565        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9566        cx: AsyncApp,
 9567    ) -> Result<proto::Ack> {
 9568        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9569        lsp_store.read_with(&cx, |lsp_store, _| {
 9570            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9571                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9572            } else {
 9573                None
 9574            }
 9575        });
 9576
 9577        Ok(proto::Ack {})
 9578    }
 9579
 9580    pub fn disk_based_diagnostics_started(
 9581        &mut self,
 9582        language_server_id: LanguageServerId,
 9583        cx: &mut Context<Self>,
 9584    ) {
 9585        if let Some(language_server_status) =
 9586            self.language_server_statuses.get_mut(&language_server_id)
 9587        {
 9588            language_server_status.has_pending_diagnostic_updates = true;
 9589        }
 9590
 9591        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9592        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9593            language_server_id,
 9594            name: self
 9595                .language_server_adapter_for_id(language_server_id)
 9596                .map(|adapter| adapter.name()),
 9597            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9598                Default::default(),
 9599            ),
 9600        })
 9601    }
 9602
 9603    pub fn disk_based_diagnostics_finished(
 9604        &mut self,
 9605        language_server_id: LanguageServerId,
 9606        cx: &mut Context<Self>,
 9607    ) {
 9608        if let Some(language_server_status) =
 9609            self.language_server_statuses.get_mut(&language_server_id)
 9610        {
 9611            language_server_status.has_pending_diagnostic_updates = false;
 9612        }
 9613
 9614        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9615        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9616            language_server_id,
 9617            name: self
 9618                .language_server_adapter_for_id(language_server_id)
 9619                .map(|adapter| adapter.name()),
 9620            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9621                Default::default(),
 9622            ),
 9623        })
 9624    }
 9625
 9626    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9627    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9628    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9629    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9630    // the language server might take some time to publish diagnostics.
 9631    fn simulate_disk_based_diagnostics_events_if_needed(
 9632        &mut self,
 9633        language_server_id: LanguageServerId,
 9634        cx: &mut Context<Self>,
 9635    ) {
 9636        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9637
 9638        let Some(LanguageServerState::Running {
 9639            simulate_disk_based_diagnostics_completion,
 9640            adapter,
 9641            ..
 9642        }) = self
 9643            .as_local_mut()
 9644            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9645        else {
 9646            return;
 9647        };
 9648
 9649        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9650            return;
 9651        }
 9652
 9653        let prev_task =
 9654            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9655                cx.background_executor()
 9656                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9657                    .await;
 9658
 9659                this.update(cx, |this, cx| {
 9660                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9661
 9662                    if let Some(LanguageServerState::Running {
 9663                        simulate_disk_based_diagnostics_completion,
 9664                        ..
 9665                    }) = this.as_local_mut().and_then(|local_store| {
 9666                        local_store.language_servers.get_mut(&language_server_id)
 9667                    }) {
 9668                        *simulate_disk_based_diagnostics_completion = None;
 9669                    }
 9670                })
 9671                .ok();
 9672            }));
 9673
 9674        if prev_task.is_none() {
 9675            self.disk_based_diagnostics_started(language_server_id, cx);
 9676        }
 9677    }
 9678
 9679    pub fn language_server_statuses(
 9680        &self,
 9681    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9682        self.language_server_statuses
 9683            .iter()
 9684            .map(|(key, value)| (*key, value))
 9685    }
 9686
 9687    pub(super) fn did_rename_entry(
 9688        &self,
 9689        worktree_id: WorktreeId,
 9690        old_path: &Path,
 9691        new_path: &Path,
 9692        is_dir: bool,
 9693    ) {
 9694        maybe!({
 9695            let local_store = self.as_local()?;
 9696
 9697            let old_uri = lsp::Uri::from_file_path(old_path)
 9698                .ok()
 9699                .map(|uri| uri.to_string())?;
 9700            let new_uri = lsp::Uri::from_file_path(new_path)
 9701                .ok()
 9702                .map(|uri| uri.to_string())?;
 9703
 9704            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9705                let Some(filter) = local_store
 9706                    .language_server_paths_watched_for_rename
 9707                    .get(&language_server.server_id())
 9708                else {
 9709                    continue;
 9710                };
 9711
 9712                if filter.should_send_did_rename(&old_uri, is_dir) {
 9713                    language_server
 9714                        .notify::<DidRenameFiles>(RenameFilesParams {
 9715                            files: vec![FileRename {
 9716                                old_uri: old_uri.clone(),
 9717                                new_uri: new_uri.clone(),
 9718                            }],
 9719                        })
 9720                        .ok();
 9721                }
 9722            }
 9723            Some(())
 9724        });
 9725    }
 9726
 9727    pub(super) fn will_rename_entry(
 9728        this: WeakEntity<Self>,
 9729        worktree_id: WorktreeId,
 9730        old_path: &Path,
 9731        new_path: &Path,
 9732        is_dir: bool,
 9733        cx: AsyncApp,
 9734    ) -> Task<ProjectTransaction> {
 9735        let old_uri = lsp::Uri::from_file_path(old_path)
 9736            .ok()
 9737            .map(|uri| uri.to_string());
 9738        let new_uri = lsp::Uri::from_file_path(new_path)
 9739            .ok()
 9740            .map(|uri| uri.to_string());
 9741        cx.spawn(async move |cx| {
 9742            let mut tasks = vec![];
 9743            this.update(cx, |this, cx| {
 9744                let local_store = this.as_local()?;
 9745                let old_uri = old_uri?;
 9746                let new_uri = new_uri?;
 9747                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9748                    let Some(filter) = local_store
 9749                        .language_server_paths_watched_for_rename
 9750                        .get(&language_server.server_id())
 9751                    else {
 9752                        continue;
 9753                    };
 9754
 9755                    if !filter.should_send_will_rename(&old_uri, is_dir) {
 9756                        continue;
 9757                    }
 9758                    let request_timeout = ProjectSettings::get_global(cx)
 9759                        .global_lsp_settings
 9760                        .get_request_timeout();
 9761
 9762                    let apply_edit = cx.spawn({
 9763                        let old_uri = old_uri.clone();
 9764                        let new_uri = new_uri.clone();
 9765                        let language_server = language_server.clone();
 9766                        async move |this, cx| {
 9767                            let edit = language_server
 9768                                .request::<WillRenameFiles>(
 9769                                    RenameFilesParams {
 9770                                        files: vec![FileRename { old_uri, new_uri }],
 9771                                    },
 9772                                    request_timeout,
 9773                                )
 9774                                .await
 9775                                .into_response()
 9776                                .context("will rename files")
 9777                                .log_err()
 9778                                .flatten()?;
 9779
 9780                            LocalLspStore::deserialize_workspace_edit(
 9781                                this.upgrade()?,
 9782                                edit,
 9783                                false,
 9784                                language_server.clone(),
 9785                                cx,
 9786                            )
 9787                            .await
 9788                            .ok()
 9789                        }
 9790                    });
 9791                    tasks.push(apply_edit);
 9792                }
 9793                Some(())
 9794            })
 9795            .ok()
 9796            .flatten();
 9797            let mut merged_transaction = ProjectTransaction::default();
 9798            for task in tasks {
 9799                // Await on tasks sequentially so that the order of application of edits is deterministic
 9800                // (at least with regards to the order of registration of language servers)
 9801                if let Some(transaction) = task.await {
 9802                    for (buffer, buffer_transaction) in transaction.0 {
 9803                        merged_transaction.0.insert(buffer, buffer_transaction);
 9804                    }
 9805                }
 9806            }
 9807            merged_transaction
 9808        })
 9809    }
 9810
 9811    fn lsp_notify_abs_paths_changed(
 9812        &mut self,
 9813        server_id: LanguageServerId,
 9814        changes: Vec<PathEvent>,
 9815    ) {
 9816        maybe!({
 9817            let server = self.language_server_for_id(server_id)?;
 9818            let changes = changes
 9819                .into_iter()
 9820                .filter_map(|event| {
 9821                    let typ = match event.kind? {
 9822                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9823                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9824                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9825                    };
 9826                    Some(lsp::FileEvent {
 9827                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9828                        typ,
 9829                    })
 9830                })
 9831                .collect::<Vec<_>>();
 9832            if !changes.is_empty() {
 9833                server
 9834                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9835                        lsp::DidChangeWatchedFilesParams { changes },
 9836                    )
 9837                    .ok();
 9838            }
 9839            Some(())
 9840        });
 9841    }
 9842
 9843    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9844        self.as_local()?.language_server_for_id(id)
 9845    }
 9846
 9847    fn on_lsp_progress(
 9848        &mut self,
 9849        progress_params: lsp::ProgressParams,
 9850        language_server_id: LanguageServerId,
 9851        disk_based_diagnostics_progress_token: Option<String>,
 9852        cx: &mut Context<Self>,
 9853    ) {
 9854        match progress_params.value {
 9855            lsp::ProgressParamsValue::WorkDone(progress) => {
 9856                self.handle_work_done_progress(
 9857                    progress,
 9858                    language_server_id,
 9859                    disk_based_diagnostics_progress_token,
 9860                    ProgressToken::from_lsp(progress_params.token),
 9861                    cx,
 9862                );
 9863            }
 9864            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9865                let registration_id = match progress_params.token {
 9866                    lsp::NumberOrString::Number(_) => None,
 9867                    lsp::NumberOrString::String(token) => token
 9868                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9869                        .map(|(_, id)| id.to_owned()),
 9870                };
 9871                if let Some(LanguageServerState::Running {
 9872                    workspace_diagnostics_refresh_tasks,
 9873                    ..
 9874                }) = self
 9875                    .as_local_mut()
 9876                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9877                    && let Some(workspace_diagnostics) =
 9878                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9879                {
 9880                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9881                    self.apply_workspace_diagnostic_report(
 9882                        language_server_id,
 9883                        report,
 9884                        registration_id.map(SharedString::from),
 9885                        cx,
 9886                    )
 9887                }
 9888            }
 9889        }
 9890    }
 9891
 9892    fn handle_work_done_progress(
 9893        &mut self,
 9894        progress: lsp::WorkDoneProgress,
 9895        language_server_id: LanguageServerId,
 9896        disk_based_diagnostics_progress_token: Option<String>,
 9897        token: ProgressToken,
 9898        cx: &mut Context<Self>,
 9899    ) {
 9900        let language_server_status =
 9901            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9902                status
 9903            } else {
 9904                return;
 9905            };
 9906
 9907        if !language_server_status.progress_tokens.contains(&token) {
 9908            return;
 9909        }
 9910
 9911        let is_disk_based_diagnostics_progress =
 9912            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9913                (&disk_based_diagnostics_progress_token, &token)
 9914            {
 9915                token.starts_with(disk_based_token)
 9916            } else {
 9917                false
 9918            };
 9919
 9920        match progress {
 9921            lsp::WorkDoneProgress::Begin(report) => {
 9922                if is_disk_based_diagnostics_progress {
 9923                    self.disk_based_diagnostics_started(language_server_id, cx);
 9924                }
 9925                self.on_lsp_work_start(
 9926                    language_server_id,
 9927                    token.clone(),
 9928                    LanguageServerProgress {
 9929                        title: Some(report.title),
 9930                        is_disk_based_diagnostics_progress,
 9931                        is_cancellable: report.cancellable.unwrap_or(false),
 9932                        message: report.message.clone(),
 9933                        percentage: report.percentage.map(|p| p as usize),
 9934                        last_update_at: cx.background_executor().now(),
 9935                    },
 9936                    cx,
 9937                );
 9938            }
 9939            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9940                language_server_id,
 9941                token,
 9942                LanguageServerProgress {
 9943                    title: None,
 9944                    is_disk_based_diagnostics_progress,
 9945                    is_cancellable: report.cancellable.unwrap_or(false),
 9946                    message: report.message,
 9947                    percentage: report.percentage.map(|p| p as usize),
 9948                    last_update_at: cx.background_executor().now(),
 9949                },
 9950                cx,
 9951            ),
 9952            lsp::WorkDoneProgress::End(_) => {
 9953                language_server_status.progress_tokens.remove(&token);
 9954                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9955                if is_disk_based_diagnostics_progress {
 9956                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9957                }
 9958            }
 9959        }
 9960    }
 9961
 9962    fn on_lsp_work_start(
 9963        &mut self,
 9964        language_server_id: LanguageServerId,
 9965        token: ProgressToken,
 9966        progress: LanguageServerProgress,
 9967        cx: &mut Context<Self>,
 9968    ) {
 9969        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9970            status.pending_work.insert(token.clone(), progress.clone());
 9971            cx.notify();
 9972        }
 9973        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9974            language_server_id,
 9975            name: self
 9976                .language_server_adapter_for_id(language_server_id)
 9977                .map(|adapter| adapter.name()),
 9978            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9979                token: Some(token.to_proto()),
 9980                title: progress.title,
 9981                message: progress.message,
 9982                percentage: progress.percentage.map(|p| p as u32),
 9983                is_cancellable: Some(progress.is_cancellable),
 9984            }),
 9985        })
 9986    }
 9987
 9988    fn on_lsp_work_progress(
 9989        &mut self,
 9990        language_server_id: LanguageServerId,
 9991        token: ProgressToken,
 9992        progress: LanguageServerProgress,
 9993        cx: &mut Context<Self>,
 9994    ) {
 9995        let mut did_update = false;
 9996        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9997            match status.pending_work.entry(token.clone()) {
 9998                btree_map::Entry::Vacant(entry) => {
 9999                    entry.insert(progress.clone());
10000                    did_update = true;
10001                }
10002                btree_map::Entry::Occupied(mut entry) => {
10003                    let entry = entry.get_mut();
10004                    if (progress.last_update_at - entry.last_update_at)
10005                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10006                    {
10007                        entry.last_update_at = progress.last_update_at;
10008                        if progress.message.is_some() {
10009                            entry.message = progress.message.clone();
10010                        }
10011                        if progress.percentage.is_some() {
10012                            entry.percentage = progress.percentage;
10013                        }
10014                        if progress.is_cancellable != entry.is_cancellable {
10015                            entry.is_cancellable = progress.is_cancellable;
10016                        }
10017                        did_update = true;
10018                    }
10019                }
10020            }
10021        }
10022
10023        if did_update {
10024            cx.emit(LspStoreEvent::LanguageServerUpdate {
10025                language_server_id,
10026                name: self
10027                    .language_server_adapter_for_id(language_server_id)
10028                    .map(|adapter| adapter.name()),
10029                message: proto::update_language_server::Variant::WorkProgress(
10030                    proto::LspWorkProgress {
10031                        token: Some(token.to_proto()),
10032                        message: progress.message,
10033                        percentage: progress.percentage.map(|p| p as u32),
10034                        is_cancellable: Some(progress.is_cancellable),
10035                    },
10036                ),
10037            })
10038        }
10039    }
10040
10041    fn on_lsp_work_end(
10042        &mut self,
10043        language_server_id: LanguageServerId,
10044        token: ProgressToken,
10045        cx: &mut Context<Self>,
10046    ) {
10047        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10048            if let Some(work) = status.pending_work.remove(&token)
10049                && !work.is_disk_based_diagnostics_progress
10050            {
10051                cx.emit(LspStoreEvent::RefreshInlayHints {
10052                    server_id: language_server_id,
10053                    request_id: None,
10054                });
10055            }
10056            cx.notify();
10057        }
10058
10059        cx.emit(LspStoreEvent::LanguageServerUpdate {
10060            language_server_id,
10061            name: self
10062                .language_server_adapter_for_id(language_server_id)
10063                .map(|adapter| adapter.name()),
10064            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10065                token: Some(token.to_proto()),
10066            }),
10067        })
10068    }
10069
10070    pub async fn handle_resolve_completion_documentation(
10071        this: Entity<Self>,
10072        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10073        mut cx: AsyncApp,
10074    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10075        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10076
10077        let completion = this
10078            .read_with(&cx, |this, cx| {
10079                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10080                let server = this
10081                    .language_server_for_id(id)
10082                    .with_context(|| format!("No language server {id}"))?;
10083
10084                let request_timeout = ProjectSettings::get_global(cx)
10085                    .global_lsp_settings
10086                    .get_request_timeout();
10087
10088                anyhow::Ok(cx.background_spawn(async move {
10089                    let can_resolve = server
10090                        .capabilities()
10091                        .completion_provider
10092                        .as_ref()
10093                        .and_then(|options| options.resolve_provider)
10094                        .unwrap_or(false);
10095                    if can_resolve {
10096                        server
10097                            .request::<lsp::request::ResolveCompletionItem>(
10098                                lsp_completion,
10099                                request_timeout,
10100                            )
10101                            .await
10102                            .into_response()
10103                            .context("resolve completion item")
10104                    } else {
10105                        anyhow::Ok(lsp_completion)
10106                    }
10107                }))
10108            })?
10109            .await?;
10110
10111        let mut documentation_is_markdown = false;
10112        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10113        let documentation = match completion.documentation {
10114            Some(lsp::Documentation::String(text)) => text,
10115
10116            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10117                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10118                value
10119            }
10120
10121            _ => String::new(),
10122        };
10123
10124        // If we have a new buffer_id, that means we're talking to a new client
10125        // and want to check for new text_edits in the completion too.
10126        let mut old_replace_start = None;
10127        let mut old_replace_end = None;
10128        let mut old_insert_start = None;
10129        let mut old_insert_end = None;
10130        let mut new_text = String::default();
10131        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10132            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10133                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10134                anyhow::Ok(buffer.read(cx).snapshot())
10135            })?;
10136
10137            if let Some(text_edit) = completion.text_edit.as_ref() {
10138                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10139
10140                if let Some(mut edit) = edit {
10141                    LineEnding::normalize(&mut edit.new_text);
10142
10143                    new_text = edit.new_text;
10144                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10145                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10146                    if let Some(insert_range) = edit.insert_range {
10147                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10148                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10149                    }
10150                }
10151            }
10152        }
10153
10154        Ok(proto::ResolveCompletionDocumentationResponse {
10155            documentation,
10156            documentation_is_markdown,
10157            old_replace_start,
10158            old_replace_end,
10159            new_text,
10160            lsp_completion,
10161            old_insert_start,
10162            old_insert_end,
10163        })
10164    }
10165
10166    async fn handle_on_type_formatting(
10167        this: Entity<Self>,
10168        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10169        mut cx: AsyncApp,
10170    ) -> Result<proto::OnTypeFormattingResponse> {
10171        let on_type_formatting = this.update(&mut cx, |this, cx| {
10172            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10173            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10174            let position = envelope
10175                .payload
10176                .position
10177                .and_then(deserialize_anchor)
10178                .context("invalid position")?;
10179            anyhow::Ok(this.apply_on_type_formatting(
10180                buffer,
10181                position,
10182                envelope.payload.trigger.clone(),
10183                cx,
10184            ))
10185        })?;
10186
10187        let transaction = on_type_formatting
10188            .await?
10189            .as_ref()
10190            .map(language::proto::serialize_transaction);
10191        Ok(proto::OnTypeFormattingResponse { transaction })
10192    }
10193
10194    async fn handle_pull_workspace_diagnostics(
10195        lsp_store: Entity<Self>,
10196        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10197        mut cx: AsyncApp,
10198    ) -> Result<proto::Ack> {
10199        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10200        lsp_store.update(&mut cx, |lsp_store, _| {
10201            lsp_store.pull_workspace_diagnostics(server_id);
10202        });
10203        Ok(proto::Ack {})
10204    }
10205
10206    async fn handle_open_buffer_for_symbol(
10207        this: Entity<Self>,
10208        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10209        mut cx: AsyncApp,
10210    ) -> Result<proto::OpenBufferForSymbolResponse> {
10211        let peer_id = envelope.original_sender_id().unwrap_or_default();
10212        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10213        let symbol = Self::deserialize_symbol(symbol)?;
10214        this.read_with(&cx, |this, _| {
10215            if let SymbolLocation::OutsideProject {
10216                abs_path,
10217                signature,
10218            } = &symbol.path
10219            {
10220                let new_signature = this.symbol_signature(&abs_path);
10221                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10222            }
10223            Ok(())
10224        })?;
10225        let buffer = this
10226            .update(&mut cx, |this, cx| {
10227                this.open_buffer_for_symbol(
10228                    &Symbol {
10229                        language_server_name: symbol.language_server_name,
10230                        source_worktree_id: symbol.source_worktree_id,
10231                        source_language_server_id: symbol.source_language_server_id,
10232                        path: symbol.path,
10233                        name: symbol.name,
10234                        kind: symbol.kind,
10235                        range: symbol.range,
10236                        label: CodeLabel::default(),
10237                        container_name: symbol.container_name,
10238                    },
10239                    cx,
10240                )
10241            })
10242            .await?;
10243
10244        this.update(&mut cx, |this, cx| {
10245            let is_private = buffer
10246                .read(cx)
10247                .file()
10248                .map(|f| f.is_private())
10249                .unwrap_or_default();
10250            if is_private {
10251                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10252            } else {
10253                this.buffer_store
10254                    .update(cx, |buffer_store, cx| {
10255                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10256                    })
10257                    .detach_and_log_err(cx);
10258                let buffer_id = buffer.read(cx).remote_id().to_proto();
10259                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10260            }
10261        })
10262    }
10263
10264    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10265        let mut hasher = Sha256::new();
10266        hasher.update(abs_path.to_string_lossy().as_bytes());
10267        hasher.update(self.nonce.to_be_bytes());
10268        hasher.finalize().as_slice().try_into().unwrap()
10269    }
10270
10271    pub async fn handle_get_project_symbols(
10272        this: Entity<Self>,
10273        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10274        mut cx: AsyncApp,
10275    ) -> Result<proto::GetProjectSymbolsResponse> {
10276        let symbols = this
10277            .update(&mut cx, |this, cx| {
10278                this.symbols(&envelope.payload.query, cx)
10279            })
10280            .await?;
10281
10282        Ok(proto::GetProjectSymbolsResponse {
10283            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10284        })
10285    }
10286
10287    pub async fn handle_restart_language_servers(
10288        this: Entity<Self>,
10289        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10290        mut cx: AsyncApp,
10291    ) -> Result<proto::Ack> {
10292        this.update(&mut cx, |lsp_store, cx| {
10293            let buffers =
10294                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10295            lsp_store.restart_language_servers_for_buffers(
10296                buffers,
10297                envelope
10298                    .payload
10299                    .only_servers
10300                    .into_iter()
10301                    .filter_map(|selector| {
10302                        Some(match selector.selector? {
10303                            proto::language_server_selector::Selector::ServerId(server_id) => {
10304                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10305                            }
10306                            proto::language_server_selector::Selector::Name(name) => {
10307                                LanguageServerSelector::Name(LanguageServerName(
10308                                    SharedString::from(name),
10309                                ))
10310                            }
10311                        })
10312                    })
10313                    .collect(),
10314                cx,
10315            );
10316        });
10317
10318        Ok(proto::Ack {})
10319    }
10320
10321    pub async fn handle_stop_language_servers(
10322        lsp_store: Entity<Self>,
10323        envelope: TypedEnvelope<proto::StopLanguageServers>,
10324        mut cx: AsyncApp,
10325    ) -> Result<proto::Ack> {
10326        lsp_store.update(&mut cx, |lsp_store, cx| {
10327            if envelope.payload.all
10328                && envelope.payload.also_servers.is_empty()
10329                && envelope.payload.buffer_ids.is_empty()
10330            {
10331                lsp_store.stop_all_language_servers(cx);
10332            } else {
10333                let buffers =
10334                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10335                lsp_store
10336                    .stop_language_servers_for_buffers(
10337                        buffers,
10338                        envelope
10339                            .payload
10340                            .also_servers
10341                            .into_iter()
10342                            .filter_map(|selector| {
10343                                Some(match selector.selector? {
10344                                    proto::language_server_selector::Selector::ServerId(
10345                                        server_id,
10346                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10347                                        server_id,
10348                                    )),
10349                                    proto::language_server_selector::Selector::Name(name) => {
10350                                        LanguageServerSelector::Name(LanguageServerName(
10351                                            SharedString::from(name),
10352                                        ))
10353                                    }
10354                                })
10355                            })
10356                            .collect(),
10357                        cx,
10358                    )
10359                    .detach_and_log_err(cx);
10360            }
10361        });
10362
10363        Ok(proto::Ack {})
10364    }
10365
10366    pub async fn handle_cancel_language_server_work(
10367        lsp_store: Entity<Self>,
10368        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10369        mut cx: AsyncApp,
10370    ) -> Result<proto::Ack> {
10371        lsp_store.update(&mut cx, |lsp_store, cx| {
10372            if let Some(work) = envelope.payload.work {
10373                match work {
10374                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10375                        let buffers =
10376                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10377                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10378                    }
10379                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10380                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10381                        let token = work
10382                            .token
10383                            .map(|token| {
10384                                ProgressToken::from_proto(token)
10385                                    .context("invalid work progress token")
10386                            })
10387                            .transpose()?;
10388                        lsp_store.cancel_language_server_work(server_id, token, cx);
10389                    }
10390                }
10391            }
10392            anyhow::Ok(())
10393        })?;
10394
10395        Ok(proto::Ack {})
10396    }
10397
10398    fn buffer_ids_to_buffers(
10399        &mut self,
10400        buffer_ids: impl Iterator<Item = u64>,
10401        cx: &mut Context<Self>,
10402    ) -> Vec<Entity<Buffer>> {
10403        buffer_ids
10404            .into_iter()
10405            .flat_map(|buffer_id| {
10406                self.buffer_store
10407                    .read(cx)
10408                    .get(BufferId::new(buffer_id).log_err()?)
10409            })
10410            .collect::<Vec<_>>()
10411    }
10412
10413    async fn handle_apply_additional_edits_for_completion(
10414        this: Entity<Self>,
10415        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10416        mut cx: AsyncApp,
10417    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10418        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10419            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10420            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10421            let completion = Self::deserialize_completion(
10422                envelope.payload.completion.context("invalid completion")?,
10423            )?;
10424            anyhow::Ok((buffer, completion))
10425        })?;
10426
10427        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10428            this.apply_additional_edits_for_completion(
10429                buffer,
10430                Rc::new(RefCell::new(Box::new([Completion {
10431                    replace_range: completion.replace_range,
10432                    new_text: completion.new_text,
10433                    source: completion.source,
10434                    documentation: None,
10435                    label: CodeLabel::default(),
10436                    match_start: None,
10437                    snippet_deduplication_key: None,
10438                    insert_text_mode: None,
10439                    icon_path: None,
10440                    confirm: None,
10441                }]))),
10442                0,
10443                false,
10444                cx,
10445            )
10446        });
10447
10448        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10449            transaction: apply_additional_edits
10450                .await?
10451                .as_ref()
10452                .map(language::proto::serialize_transaction),
10453        })
10454    }
10455
10456    pub fn last_formatting_failure(&self) -> Option<&str> {
10457        self.last_formatting_failure.as_deref()
10458    }
10459
10460    pub fn reset_last_formatting_failure(&mut self) {
10461        self.last_formatting_failure = None;
10462    }
10463
10464    pub fn environment_for_buffer(
10465        &self,
10466        buffer: &Entity<Buffer>,
10467        cx: &mut Context<Self>,
10468    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10469        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10470            environment.update(cx, |env, cx| {
10471                env.buffer_environment(buffer, &self.worktree_store, cx)
10472            })
10473        } else {
10474            Task::ready(None).shared()
10475        }
10476    }
10477
10478    pub fn format(
10479        &mut self,
10480        buffers: HashSet<Entity<Buffer>>,
10481        target: LspFormatTarget,
10482        push_to_history: bool,
10483        trigger: FormatTrigger,
10484        cx: &mut Context<Self>,
10485    ) -> Task<anyhow::Result<ProjectTransaction>> {
10486        let logger = zlog::scoped!("format");
10487        if self.as_local().is_some() {
10488            zlog::trace!(logger => "Formatting locally");
10489            let logger = zlog::scoped!(logger => "local");
10490            let buffers = buffers
10491                .into_iter()
10492                .map(|buffer_handle| {
10493                    let buffer = buffer_handle.read(cx);
10494                    let buffer_abs_path = File::from_dyn(buffer.file())
10495                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10496
10497                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10498                })
10499                .collect::<Vec<_>>();
10500
10501            cx.spawn(async move |lsp_store, cx| {
10502                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10503
10504                for (handle, abs_path, id) in buffers {
10505                    let env = lsp_store
10506                        .update(cx, |lsp_store, cx| {
10507                            lsp_store.environment_for_buffer(&handle, cx)
10508                        })?
10509                        .await;
10510
10511                    let ranges = match &target {
10512                        LspFormatTarget::Buffers => None,
10513                        LspFormatTarget::Ranges(ranges) => {
10514                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10515                        }
10516                    };
10517
10518                    formattable_buffers.push(FormattableBuffer {
10519                        handle,
10520                        abs_path,
10521                        env,
10522                        ranges,
10523                    });
10524                }
10525                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10526
10527                let format_timer = zlog::time!(logger => "Formatting buffers");
10528                let result = LocalLspStore::format_locally(
10529                    lsp_store.clone(),
10530                    formattable_buffers,
10531                    push_to_history,
10532                    trigger,
10533                    logger,
10534                    cx,
10535                )
10536                .await;
10537                format_timer.end();
10538
10539                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10540
10541                lsp_store.update(cx, |lsp_store, _| {
10542                    lsp_store.update_last_formatting_failure(&result);
10543                })?;
10544
10545                result
10546            })
10547        } else if let Some((client, project_id)) = self.upstream_client() {
10548            zlog::trace!(logger => "Formatting remotely");
10549            let logger = zlog::scoped!(logger => "remote");
10550
10551            let buffer_ranges = match &target {
10552                LspFormatTarget::Buffers => Vec::new(),
10553                LspFormatTarget::Ranges(ranges) => ranges
10554                    .iter()
10555                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10556                        buffer_id: buffer_id.to_proto(),
10557                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10558                    })
10559                    .collect(),
10560            };
10561
10562            let buffer_store = self.buffer_store();
10563            cx.spawn(async move |lsp_store, cx| {
10564                zlog::trace!(logger => "Sending remote format request");
10565                let request_timer = zlog::time!(logger => "remote format request");
10566                let result = client
10567                    .request(proto::FormatBuffers {
10568                        project_id,
10569                        trigger: trigger as i32,
10570                        buffer_ids: buffers
10571                            .iter()
10572                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10573                            .collect(),
10574                        buffer_ranges,
10575                    })
10576                    .await
10577                    .and_then(|result| result.transaction.context("missing transaction"));
10578                request_timer.end();
10579
10580                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10581
10582                lsp_store.update(cx, |lsp_store, _| {
10583                    lsp_store.update_last_formatting_failure(&result);
10584                })?;
10585
10586                let transaction_response = result?;
10587                let _timer = zlog::time!(logger => "deserializing project transaction");
10588                buffer_store
10589                    .update(cx, |buffer_store, cx| {
10590                        buffer_store.deserialize_project_transaction(
10591                            transaction_response,
10592                            push_to_history,
10593                            cx,
10594                        )
10595                    })
10596                    .await
10597            })
10598        } else {
10599            zlog::trace!(logger => "Not formatting");
10600            Task::ready(Ok(ProjectTransaction::default()))
10601        }
10602    }
10603
10604    async fn handle_format_buffers(
10605        this: Entity<Self>,
10606        envelope: TypedEnvelope<proto::FormatBuffers>,
10607        mut cx: AsyncApp,
10608    ) -> Result<proto::FormatBuffersResponse> {
10609        let sender_id = envelope.original_sender_id().unwrap_or_default();
10610        let format = this.update(&mut cx, |this, cx| {
10611            let mut buffers = HashSet::default();
10612            for buffer_id in &envelope.payload.buffer_ids {
10613                let buffer_id = BufferId::new(*buffer_id)?;
10614                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10615            }
10616
10617            let target = if envelope.payload.buffer_ranges.is_empty() {
10618                LspFormatTarget::Buffers
10619            } else {
10620                let mut ranges_map = BTreeMap::new();
10621                for buffer_range in &envelope.payload.buffer_ranges {
10622                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10623                    let ranges: Result<Vec<_>> = buffer_range
10624                        .ranges
10625                        .iter()
10626                        .map(|range| {
10627                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10628                        })
10629                        .collect();
10630                    ranges_map.insert(buffer_id, ranges?);
10631                }
10632                LspFormatTarget::Ranges(ranges_map)
10633            };
10634
10635            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10636            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10637        })?;
10638
10639        let project_transaction = format.await?;
10640        let project_transaction = this.update(&mut cx, |this, cx| {
10641            this.buffer_store.update(cx, |buffer_store, cx| {
10642                buffer_store.serialize_project_transaction_for_peer(
10643                    project_transaction,
10644                    sender_id,
10645                    cx,
10646                )
10647            })
10648        });
10649        Ok(proto::FormatBuffersResponse {
10650            transaction: Some(project_transaction),
10651        })
10652    }
10653
10654    async fn handle_apply_code_action_kind(
10655        this: Entity<Self>,
10656        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10657        mut cx: AsyncApp,
10658    ) -> Result<proto::ApplyCodeActionKindResponse> {
10659        let sender_id = envelope.original_sender_id().unwrap_or_default();
10660        let format = this.update(&mut cx, |this, cx| {
10661            let mut buffers = HashSet::default();
10662            for buffer_id in &envelope.payload.buffer_ids {
10663                let buffer_id = BufferId::new(*buffer_id)?;
10664                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10665            }
10666            let kind = match envelope.payload.kind.as_str() {
10667                "" => CodeActionKind::EMPTY,
10668                "quickfix" => CodeActionKind::QUICKFIX,
10669                "refactor" => CodeActionKind::REFACTOR,
10670                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10671                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10672                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10673                "source" => CodeActionKind::SOURCE,
10674                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10675                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10676                _ => anyhow::bail!(
10677                    "Invalid code action kind {}",
10678                    envelope.payload.kind.as_str()
10679                ),
10680            };
10681            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10682        })?;
10683
10684        let project_transaction = format.await?;
10685        let project_transaction = this.update(&mut cx, |this, cx| {
10686            this.buffer_store.update(cx, |buffer_store, cx| {
10687                buffer_store.serialize_project_transaction_for_peer(
10688                    project_transaction,
10689                    sender_id,
10690                    cx,
10691                )
10692            })
10693        });
10694        Ok(proto::ApplyCodeActionKindResponse {
10695            transaction: Some(project_transaction),
10696        })
10697    }
10698
10699    async fn shutdown_language_server(
10700        server_state: Option<LanguageServerState>,
10701        name: LanguageServerName,
10702        cx: &mut AsyncApp,
10703    ) {
10704        let server = match server_state {
10705            Some(LanguageServerState::Starting { startup, .. }) => {
10706                let mut timer = cx
10707                    .background_executor()
10708                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10709                    .fuse();
10710
10711                select! {
10712                    server = startup.fuse() => server,
10713                    () = timer => {
10714                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10715                        None
10716                    },
10717                }
10718            }
10719
10720            Some(LanguageServerState::Running { server, .. }) => Some(server),
10721
10722            None => None,
10723        };
10724
10725        let Some(server) = server else { return };
10726        if let Some(shutdown) = server.shutdown() {
10727            shutdown.await;
10728        }
10729    }
10730
10731    // Returns a list of all of the worktrees which no longer have a language server and the root path
10732    // for the stopped server
10733    fn stop_local_language_server(
10734        &mut self,
10735        server_id: LanguageServerId,
10736        cx: &mut Context<Self>,
10737    ) -> Task<()> {
10738        let local = match &mut self.mode {
10739            LspStoreMode::Local(local) => local,
10740            _ => {
10741                return Task::ready(());
10742            }
10743        };
10744
10745        // Remove this server ID from all entries in the given worktree.
10746        local
10747            .language_server_ids
10748            .retain(|_, state| state.id != server_id);
10749        self.buffer_store.update(cx, |buffer_store, cx| {
10750            for buffer in buffer_store.buffers() {
10751                buffer.update(cx, |buffer, cx| {
10752                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10753                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10754                });
10755            }
10756        });
10757
10758        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10759            summaries.retain(|path, summaries_by_server_id| {
10760                if summaries_by_server_id.remove(&server_id).is_some() {
10761                    if let Some((client, project_id)) = self.downstream_client.clone() {
10762                        client
10763                            .send(proto::UpdateDiagnosticSummary {
10764                                project_id,
10765                                worktree_id: worktree_id.to_proto(),
10766                                summary: Some(proto::DiagnosticSummary {
10767                                    path: path.as_ref().to_proto(),
10768                                    language_server_id: server_id.0 as u64,
10769                                    error_count: 0,
10770                                    warning_count: 0,
10771                                }),
10772                                more_summaries: Vec::new(),
10773                            })
10774                            .log_err();
10775                    }
10776                    !summaries_by_server_id.is_empty()
10777                } else {
10778                    true
10779                }
10780            });
10781        }
10782
10783        let local = self.as_local_mut().unwrap();
10784        for diagnostics in local.diagnostics.values_mut() {
10785            diagnostics.retain(|_, diagnostics_by_server_id| {
10786                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10787                    diagnostics_by_server_id.remove(ix);
10788                    !diagnostics_by_server_id.is_empty()
10789                } else {
10790                    true
10791                }
10792            });
10793        }
10794        local.language_server_watched_paths.remove(&server_id);
10795
10796        let server_state = local.language_servers.remove(&server_id);
10797        self.cleanup_lsp_data(server_id);
10798        let name = self
10799            .language_server_statuses
10800            .remove(&server_id)
10801            .map(|status| status.name)
10802            .or_else(|| {
10803                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10804                    Some(adapter.name())
10805                } else {
10806                    None
10807                }
10808            });
10809
10810        if let Some(name) = name {
10811            log::info!("stopping language server {name}");
10812            self.languages
10813                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10814            cx.notify();
10815
10816            return cx.spawn(async move |lsp_store, cx| {
10817                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10818                lsp_store
10819                    .update(cx, |lsp_store, cx| {
10820                        lsp_store
10821                            .languages
10822                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10823                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10824                        cx.notify();
10825                    })
10826                    .ok();
10827            });
10828        }
10829
10830        if server_state.is_some() {
10831            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10832        }
10833        Task::ready(())
10834    }
10835
10836    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10837        self.shutdown_all_language_servers(cx).detach();
10838    }
10839
10840    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
10841        if let Some((client, project_id)) = self.upstream_client() {
10842            let request = client.request(proto::StopLanguageServers {
10843                project_id,
10844                buffer_ids: Vec::new(),
10845                also_servers: Vec::new(),
10846                all: true,
10847            });
10848            cx.background_spawn(async move {
10849                request.await.ok();
10850            })
10851        } else {
10852            let Some(local) = self.as_local_mut() else {
10853                return Task::ready(());
10854            };
10855            let language_servers_to_stop = local
10856                .language_server_ids
10857                .values()
10858                .map(|state| state.id)
10859                .collect();
10860            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10861            let tasks = language_servers_to_stop
10862                .into_iter()
10863                .map(|server| self.stop_local_language_server(server, cx))
10864                .collect::<Vec<_>>();
10865            cx.background_spawn(async move {
10866                futures::future::join_all(tasks).await;
10867            })
10868        }
10869    }
10870
10871    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
10872        let buffers = self.buffer_store.read(cx).buffers().collect();
10873        self.restart_language_servers_for_buffers(buffers, HashSet::default(), cx);
10874    }
10875
10876    pub fn restart_language_servers_for_buffers(
10877        &mut self,
10878        buffers: Vec<Entity<Buffer>>,
10879        only_restart_servers: HashSet<LanguageServerSelector>,
10880        cx: &mut Context<Self>,
10881    ) {
10882        if let Some((client, project_id)) = self.upstream_client() {
10883            let request = client.request(proto::RestartLanguageServers {
10884                project_id,
10885                buffer_ids: buffers
10886                    .into_iter()
10887                    .map(|b| b.read(cx).remote_id().to_proto())
10888                    .collect(),
10889                only_servers: only_restart_servers
10890                    .into_iter()
10891                    .map(|selector| {
10892                        let selector = match selector {
10893                            LanguageServerSelector::Id(language_server_id) => {
10894                                proto::language_server_selector::Selector::ServerId(
10895                                    language_server_id.to_proto(),
10896                                )
10897                            }
10898                            LanguageServerSelector::Name(language_server_name) => {
10899                                proto::language_server_selector::Selector::Name(
10900                                    language_server_name.to_string(),
10901                                )
10902                            }
10903                        };
10904                        proto::LanguageServerSelector {
10905                            selector: Some(selector),
10906                        }
10907                    })
10908                    .collect(),
10909                all: false,
10910            });
10911            cx.background_spawn(request).detach_and_log_err(cx);
10912        } else {
10913            let stop_task = if only_restart_servers.is_empty() {
10914                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10915            } else {
10916                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10917            };
10918            cx.spawn(async move |lsp_store, cx| {
10919                stop_task.await;
10920                lsp_store.update(cx, |lsp_store, cx| {
10921                    for buffer in buffers {
10922                        lsp_store.register_buffer_with_language_servers(
10923                            &buffer,
10924                            only_restart_servers.clone(),
10925                            true,
10926                            cx,
10927                        );
10928                    }
10929                })
10930            })
10931            .detach();
10932        }
10933    }
10934
10935    pub fn stop_language_servers_for_buffers(
10936        &mut self,
10937        buffers: Vec<Entity<Buffer>>,
10938        also_stop_servers: HashSet<LanguageServerSelector>,
10939        cx: &mut Context<Self>,
10940    ) -> Task<Result<()>> {
10941        if let Some((client, project_id)) = self.upstream_client() {
10942            let request = client.request(proto::StopLanguageServers {
10943                project_id,
10944                buffer_ids: buffers
10945                    .into_iter()
10946                    .map(|b| b.read(cx).remote_id().to_proto())
10947                    .collect(),
10948                also_servers: also_stop_servers
10949                    .into_iter()
10950                    .map(|selector| {
10951                        let selector = match selector {
10952                            LanguageServerSelector::Id(language_server_id) => {
10953                                proto::language_server_selector::Selector::ServerId(
10954                                    language_server_id.to_proto(),
10955                                )
10956                            }
10957                            LanguageServerSelector::Name(language_server_name) => {
10958                                proto::language_server_selector::Selector::Name(
10959                                    language_server_name.to_string(),
10960                                )
10961                            }
10962                        };
10963                        proto::LanguageServerSelector {
10964                            selector: Some(selector),
10965                        }
10966                    })
10967                    .collect(),
10968                all: false,
10969            });
10970            cx.background_spawn(async move {
10971                let _ = request.await?;
10972                Ok(())
10973            })
10974        } else {
10975            let task =
10976                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10977            cx.background_spawn(async move {
10978                task.await;
10979                Ok(())
10980            })
10981        }
10982    }
10983
10984    fn stop_local_language_servers_for_buffers(
10985        &mut self,
10986        buffers: &[Entity<Buffer>],
10987        also_stop_servers: HashSet<LanguageServerSelector>,
10988        cx: &mut Context<Self>,
10989    ) -> Task<()> {
10990        let Some(local) = self.as_local_mut() else {
10991            return Task::ready(());
10992        };
10993        let mut language_server_names_to_stop = BTreeSet::default();
10994        let mut language_servers_to_stop = also_stop_servers
10995            .into_iter()
10996            .flat_map(|selector| match selector {
10997                LanguageServerSelector::Id(id) => Some(id),
10998                LanguageServerSelector::Name(name) => {
10999                    language_server_names_to_stop.insert(name);
11000                    None
11001                }
11002            })
11003            .collect::<BTreeSet<_>>();
11004
11005        let mut covered_worktrees = HashSet::default();
11006        for buffer in buffers {
11007            buffer.update(cx, |buffer, cx| {
11008                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11009                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11010                    && covered_worktrees.insert(worktree_id)
11011                {
11012                    language_server_names_to_stop.retain(|name| {
11013                        let old_ids_count = language_servers_to_stop.len();
11014                        let all_language_servers_with_this_name = local
11015                            .language_server_ids
11016                            .iter()
11017                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11018                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11019                        old_ids_count == language_servers_to_stop.len()
11020                    });
11021                }
11022            });
11023        }
11024        for name in language_server_names_to_stop {
11025            language_servers_to_stop.extend(
11026                local
11027                    .language_server_ids
11028                    .iter()
11029                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11030            );
11031        }
11032
11033        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11034        let tasks = language_servers_to_stop
11035            .into_iter()
11036            .map(|server| self.stop_local_language_server(server, cx))
11037            .collect::<Vec<_>>();
11038
11039        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11040    }
11041
11042    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11043        let (worktree, relative_path) =
11044            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11045
11046        let project_path = ProjectPath {
11047            worktree_id: worktree.read(cx).id(),
11048            path: relative_path,
11049        };
11050
11051        Some(
11052            self.buffer_store()
11053                .read(cx)
11054                .get_by_path(&project_path)?
11055                .read(cx),
11056        )
11057    }
11058
11059    #[cfg(any(test, feature = "test-support"))]
11060    pub fn update_diagnostics(
11061        &mut self,
11062        server_id: LanguageServerId,
11063        diagnostics: lsp::PublishDiagnosticsParams,
11064        result_id: Option<SharedString>,
11065        source_kind: DiagnosticSourceKind,
11066        disk_based_sources: &[String],
11067        cx: &mut Context<Self>,
11068    ) -> Result<()> {
11069        self.merge_lsp_diagnostics(
11070            source_kind,
11071            vec![DocumentDiagnosticsUpdate {
11072                diagnostics,
11073                result_id,
11074                server_id,
11075                disk_based_sources: Cow::Borrowed(disk_based_sources),
11076                registration_id: None,
11077            }],
11078            |_, _, _| false,
11079            cx,
11080        )
11081    }
11082
11083    pub fn merge_lsp_diagnostics(
11084        &mut self,
11085        source_kind: DiagnosticSourceKind,
11086        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11087        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11088        cx: &mut Context<Self>,
11089    ) -> Result<()> {
11090        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11091        let updates = lsp_diagnostics
11092            .into_iter()
11093            .filter_map(|update| {
11094                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11095                Some(DocumentDiagnosticsUpdate {
11096                    diagnostics: self.lsp_to_document_diagnostics(
11097                        abs_path,
11098                        source_kind,
11099                        update.server_id,
11100                        update.diagnostics,
11101                        &update.disk_based_sources,
11102                        update.registration_id.clone(),
11103                    ),
11104                    result_id: update.result_id,
11105                    server_id: update.server_id,
11106                    disk_based_sources: update.disk_based_sources,
11107                    registration_id: update.registration_id,
11108                })
11109            })
11110            .collect();
11111        self.merge_diagnostic_entries(updates, merge, cx)?;
11112        Ok(())
11113    }
11114
11115    fn lsp_to_document_diagnostics(
11116        &mut self,
11117        document_abs_path: PathBuf,
11118        source_kind: DiagnosticSourceKind,
11119        server_id: LanguageServerId,
11120        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11121        disk_based_sources: &[String],
11122        registration_id: Option<SharedString>,
11123    ) -> DocumentDiagnostics {
11124        let mut diagnostics = Vec::default();
11125        let mut primary_diagnostic_group_ids = HashMap::default();
11126        let mut sources_by_group_id = HashMap::default();
11127        let mut supporting_diagnostics = HashMap::default();
11128
11129        let adapter = self.language_server_adapter_for_id(server_id);
11130
11131        // Ensure that primary diagnostics are always the most severe
11132        lsp_diagnostics
11133            .diagnostics
11134            .sort_by_key(|item| item.severity);
11135
11136        for diagnostic in &lsp_diagnostics.diagnostics {
11137            let source = diagnostic.source.as_ref();
11138            let range = range_from_lsp(diagnostic.range);
11139            let is_supporting = diagnostic
11140                .related_information
11141                .as_ref()
11142                .is_some_and(|infos| {
11143                    infos.iter().any(|info| {
11144                        primary_diagnostic_group_ids.contains_key(&(
11145                            source,
11146                            diagnostic.code.clone(),
11147                            range_from_lsp(info.location.range),
11148                        ))
11149                    })
11150                });
11151
11152            let is_unnecessary = diagnostic
11153                .tags
11154                .as_ref()
11155                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11156
11157            let underline = self
11158                .language_server_adapter_for_id(server_id)
11159                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11160
11161            if is_supporting {
11162                supporting_diagnostics.insert(
11163                    (source, diagnostic.code.clone(), range),
11164                    (diagnostic.severity, is_unnecessary),
11165                );
11166            } else {
11167                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11168                let is_disk_based =
11169                    source.is_some_and(|source| disk_based_sources.contains(source));
11170
11171                sources_by_group_id.insert(group_id, source);
11172                primary_diagnostic_group_ids
11173                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11174
11175                diagnostics.push(DiagnosticEntry {
11176                    range,
11177                    diagnostic: Diagnostic {
11178                        source: diagnostic.source.clone(),
11179                        source_kind,
11180                        code: diagnostic.code.clone(),
11181                        code_description: diagnostic
11182                            .code_description
11183                            .as_ref()
11184                            .and_then(|d| d.href.clone()),
11185                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11186                        markdown: adapter.as_ref().and_then(|adapter| {
11187                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11188                        }),
11189                        message: diagnostic.message.trim().to_string(),
11190                        group_id,
11191                        is_primary: true,
11192                        is_disk_based,
11193                        is_unnecessary,
11194                        underline,
11195                        data: diagnostic.data.clone(),
11196                        registration_id: registration_id.clone(),
11197                    },
11198                });
11199                if let Some(infos) = &diagnostic.related_information {
11200                    for info in infos {
11201                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11202                            let range = range_from_lsp(info.location.range);
11203                            diagnostics.push(DiagnosticEntry {
11204                                range,
11205                                diagnostic: Diagnostic {
11206                                    source: diagnostic.source.clone(),
11207                                    source_kind,
11208                                    code: diagnostic.code.clone(),
11209                                    code_description: diagnostic
11210                                        .code_description
11211                                        .as_ref()
11212                                        .and_then(|d| d.href.clone()),
11213                                    severity: DiagnosticSeverity::INFORMATION,
11214                                    markdown: adapter.as_ref().and_then(|adapter| {
11215                                        adapter.diagnostic_message_to_markdown(&info.message)
11216                                    }),
11217                                    message: info.message.trim().to_string(),
11218                                    group_id,
11219                                    is_primary: false,
11220                                    is_disk_based,
11221                                    is_unnecessary: false,
11222                                    underline,
11223                                    data: diagnostic.data.clone(),
11224                                    registration_id: registration_id.clone(),
11225                                },
11226                            });
11227                        }
11228                    }
11229                }
11230            }
11231        }
11232
11233        for entry in &mut diagnostics {
11234            let diagnostic = &mut entry.diagnostic;
11235            if !diagnostic.is_primary {
11236                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11237                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11238                    source,
11239                    diagnostic.code.clone(),
11240                    entry.range.clone(),
11241                )) {
11242                    if let Some(severity) = severity {
11243                        diagnostic.severity = severity;
11244                    }
11245                    diagnostic.is_unnecessary = is_unnecessary;
11246                }
11247            }
11248        }
11249
11250        DocumentDiagnostics {
11251            diagnostics,
11252            document_abs_path,
11253            version: lsp_diagnostics.version,
11254        }
11255    }
11256
11257    fn insert_newly_running_language_server(
11258        &mut self,
11259        adapter: Arc<CachedLspAdapter>,
11260        language_server: Arc<LanguageServer>,
11261        server_id: LanguageServerId,
11262        key: LanguageServerSeed,
11263        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11264        cx: &mut Context<Self>,
11265    ) {
11266        let Some(local) = self.as_local_mut() else {
11267            return;
11268        };
11269        // If the language server for this key doesn't match the server id, don't store the
11270        // server. Which will cause it to be dropped, killing the process
11271        if local
11272            .language_server_ids
11273            .get(&key)
11274            .map(|state| state.id != server_id)
11275            .unwrap_or(false)
11276        {
11277            return;
11278        }
11279
11280        // Update language_servers collection with Running variant of LanguageServerState
11281        // indicating that the server is up and running and ready
11282        let workspace_folders = workspace_folders.lock().clone();
11283        language_server.set_workspace_folders(workspace_folders);
11284
11285        let workspace_diagnostics_refresh_tasks = language_server
11286            .capabilities()
11287            .diagnostic_provider
11288            .and_then(|provider| {
11289                local
11290                    .language_server_dynamic_registrations
11291                    .entry(server_id)
11292                    .or_default()
11293                    .diagnostics
11294                    .entry(None)
11295                    .or_insert(provider.clone());
11296                let workspace_refresher =
11297                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11298
11299                Some((None, workspace_refresher))
11300            })
11301            .into_iter()
11302            .collect();
11303        local.language_servers.insert(
11304            server_id,
11305            LanguageServerState::Running {
11306                workspace_diagnostics_refresh_tasks,
11307                adapter: adapter.clone(),
11308                server: language_server.clone(),
11309                simulate_disk_based_diagnostics_completion: None,
11310            },
11311        );
11312        local
11313            .languages
11314            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11315        if let Some(file_ops_caps) = language_server
11316            .capabilities()
11317            .workspace
11318            .as_ref()
11319            .and_then(|ws| ws.file_operations.as_ref())
11320        {
11321            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11322            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11323            if did_rename_caps.or(will_rename_caps).is_some() {
11324                let watcher = RenamePathsWatchedForServer::default()
11325                    .with_did_rename_patterns(did_rename_caps)
11326                    .with_will_rename_patterns(will_rename_caps);
11327                local
11328                    .language_server_paths_watched_for_rename
11329                    .insert(server_id, watcher);
11330            }
11331        }
11332
11333        self.language_server_statuses.insert(
11334            server_id,
11335            LanguageServerStatus {
11336                name: language_server.name(),
11337                server_version: language_server.version(),
11338                pending_work: Default::default(),
11339                has_pending_diagnostic_updates: false,
11340                progress_tokens: Default::default(),
11341                worktree: Some(key.worktree_id),
11342                binary: Some(language_server.binary().clone()),
11343                configuration: Some(language_server.configuration().clone()),
11344                workspace_folders: language_server.workspace_folders(),
11345                process_id: language_server.process_id(),
11346            },
11347        );
11348
11349        cx.emit(LspStoreEvent::LanguageServerAdded(
11350            server_id,
11351            language_server.name(),
11352            Some(key.worktree_id),
11353        ));
11354
11355        let server_capabilities = language_server.capabilities();
11356        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11357            downstream_client
11358                .send(proto::StartLanguageServer {
11359                    project_id: *project_id,
11360                    server: Some(proto::LanguageServer {
11361                        id: server_id.to_proto(),
11362                        name: language_server.name().to_string(),
11363                        worktree_id: Some(key.worktree_id.to_proto()),
11364                    }),
11365                    capabilities: serde_json::to_string(&server_capabilities)
11366                        .expect("serializing server LSP capabilities"),
11367                })
11368                .log_err();
11369        }
11370        self.lsp_server_capabilities
11371            .insert(server_id, server_capabilities);
11372
11373        // Tell the language server about every open buffer in the worktree that matches the language.
11374        // Also check for buffers in worktrees that reused this server
11375        let mut worktrees_using_server = vec![key.worktree_id];
11376        if let Some(local) = self.as_local() {
11377            // Find all worktrees that have this server in their language server tree
11378            for (worktree_id, servers) in &local.lsp_tree.instances {
11379                if *worktree_id != key.worktree_id {
11380                    for server_map in servers.roots.values() {
11381                        if server_map
11382                            .values()
11383                            .any(|(node, _)| node.id() == Some(server_id))
11384                        {
11385                            worktrees_using_server.push(*worktree_id);
11386                        }
11387                    }
11388                }
11389            }
11390        }
11391
11392        let mut buffer_paths_registered = Vec::new();
11393        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11394            let mut lsp_adapters = HashMap::default();
11395            for buffer_handle in buffer_store.buffers() {
11396                let buffer = buffer_handle.read(cx);
11397                let file = match File::from_dyn(buffer.file()) {
11398                    Some(file) => file,
11399                    None => continue,
11400                };
11401                let language = match buffer.language() {
11402                    Some(language) => language,
11403                    None => continue,
11404                };
11405
11406                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11407                    || !lsp_adapters
11408                        .entry(language.name())
11409                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11410                        .iter()
11411                        .any(|a| a.name == key.name)
11412                {
11413                    continue;
11414                }
11415                // didOpen
11416                let file = match file.as_local() {
11417                    Some(file) => file,
11418                    None => continue,
11419                };
11420
11421                let local = self.as_local_mut().unwrap();
11422
11423                let buffer_id = buffer.remote_id();
11424                if local.registered_buffers.contains_key(&buffer_id) {
11425                    let abs_path = file.abs_path(cx);
11426                    let uri = match lsp::Uri::from_file_path(&abs_path) {
11427                        Ok(uri) => uri,
11428                        Err(()) => {
11429                            log::error!("failed to convert path to URI: {:?}", abs_path);
11430                            continue;
11431                        }
11432                    };
11433
11434                    let versions = local
11435                        .buffer_snapshots
11436                        .entry(buffer_id)
11437                        .or_default()
11438                        .entry(server_id)
11439                        .and_modify(|_| {
11440                            assert!(
11441                            false,
11442                            "There should not be an existing snapshot for a newly inserted buffer"
11443                        )
11444                        })
11445                        .or_insert_with(|| {
11446                            vec![LspBufferSnapshot {
11447                                version: 0,
11448                                snapshot: buffer.text_snapshot(),
11449                            }]
11450                        });
11451
11452                    let snapshot = versions.last().unwrap();
11453                    let version = snapshot.version;
11454                    let initial_snapshot = &snapshot.snapshot;
11455                    language_server.register_buffer(
11456                        uri,
11457                        adapter.language_id(&language.name()),
11458                        version,
11459                        initial_snapshot.text(),
11460                    );
11461                    buffer_paths_registered.push((buffer_id, abs_path));
11462                    local
11463                        .buffers_opened_in_servers
11464                        .entry(buffer_id)
11465                        .or_default()
11466                        .insert(server_id);
11467                }
11468                buffer_handle.update(cx, |buffer, cx| {
11469                    buffer.set_completion_triggers(
11470                        server_id,
11471                        language_server
11472                            .capabilities()
11473                            .completion_provider
11474                            .as_ref()
11475                            .and_then(|provider| {
11476                                provider
11477                                    .trigger_characters
11478                                    .as_ref()
11479                                    .map(|characters| characters.iter().cloned().collect())
11480                            })
11481                            .unwrap_or_default(),
11482                        cx,
11483                    )
11484                });
11485            }
11486        });
11487
11488        for (buffer_id, abs_path) in buffer_paths_registered {
11489            cx.emit(LspStoreEvent::LanguageServerUpdate {
11490                language_server_id: server_id,
11491                name: Some(adapter.name()),
11492                message: proto::update_language_server::Variant::RegisteredForBuffer(
11493                    proto::RegisteredForBuffer {
11494                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11495                        buffer_id: buffer_id.to_proto(),
11496                    },
11497                ),
11498            });
11499        }
11500
11501        cx.notify();
11502    }
11503
11504    pub fn language_servers_running_disk_based_diagnostics(
11505        &self,
11506    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11507        self.language_server_statuses
11508            .iter()
11509            .filter_map(|(id, status)| {
11510                if status.has_pending_diagnostic_updates {
11511                    Some(*id)
11512                } else {
11513                    None
11514                }
11515            })
11516    }
11517
11518    pub(crate) fn cancel_language_server_work_for_buffers(
11519        &mut self,
11520        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11521        cx: &mut Context<Self>,
11522    ) {
11523        if let Some((client, project_id)) = self.upstream_client() {
11524            let request = client.request(proto::CancelLanguageServerWork {
11525                project_id,
11526                work: Some(proto::cancel_language_server_work::Work::Buffers(
11527                    proto::cancel_language_server_work::Buffers {
11528                        buffer_ids: buffers
11529                            .into_iter()
11530                            .map(|b| b.read(cx).remote_id().to_proto())
11531                            .collect(),
11532                    },
11533                )),
11534            });
11535            cx.background_spawn(request).detach_and_log_err(cx);
11536        } else if let Some(local) = self.as_local() {
11537            let servers = buffers
11538                .into_iter()
11539                .flat_map(|buffer| {
11540                    buffer.update(cx, |buffer, cx| {
11541                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11542                    })
11543                })
11544                .collect::<HashSet<_>>();
11545            for server_id in servers {
11546                self.cancel_language_server_work(server_id, None, cx);
11547            }
11548        }
11549    }
11550
11551    pub(crate) fn cancel_language_server_work(
11552        &mut self,
11553        server_id: LanguageServerId,
11554        token_to_cancel: Option<ProgressToken>,
11555        cx: &mut Context<Self>,
11556    ) {
11557        if let Some(local) = self.as_local() {
11558            let status = self.language_server_statuses.get(&server_id);
11559            let server = local.language_servers.get(&server_id);
11560            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11561            {
11562                for (token, progress) in &status.pending_work {
11563                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11564                        && token != token_to_cancel
11565                    {
11566                        continue;
11567                    }
11568                    if progress.is_cancellable {
11569                        server
11570                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11571                                WorkDoneProgressCancelParams {
11572                                    token: token.to_lsp(),
11573                                },
11574                            )
11575                            .ok();
11576                    }
11577                }
11578            }
11579        } else if let Some((client, project_id)) = self.upstream_client() {
11580            let request = client.request(proto::CancelLanguageServerWork {
11581                project_id,
11582                work: Some(
11583                    proto::cancel_language_server_work::Work::LanguageServerWork(
11584                        proto::cancel_language_server_work::LanguageServerWork {
11585                            language_server_id: server_id.to_proto(),
11586                            token: token_to_cancel.map(|token| token.to_proto()),
11587                        },
11588                    ),
11589                ),
11590            });
11591            cx.background_spawn(request).detach_and_log_err(cx);
11592        }
11593    }
11594
11595    fn register_supplementary_language_server(
11596        &mut self,
11597        id: LanguageServerId,
11598        name: LanguageServerName,
11599        server: Arc<LanguageServer>,
11600        cx: &mut Context<Self>,
11601    ) {
11602        if let Some(local) = self.as_local_mut() {
11603            local
11604                .supplementary_language_servers
11605                .insert(id, (name.clone(), server));
11606            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11607        }
11608    }
11609
11610    fn unregister_supplementary_language_server(
11611        &mut self,
11612        id: LanguageServerId,
11613        cx: &mut Context<Self>,
11614    ) {
11615        if let Some(local) = self.as_local_mut() {
11616            local.supplementary_language_servers.remove(&id);
11617            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11618        }
11619    }
11620
11621    pub(crate) fn supplementary_language_servers(
11622        &self,
11623    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11624        self.as_local().into_iter().flat_map(|local| {
11625            local
11626                .supplementary_language_servers
11627                .iter()
11628                .map(|(id, (name, _))| (*id, name.clone()))
11629        })
11630    }
11631
11632    pub fn language_server_adapter_for_id(
11633        &self,
11634        id: LanguageServerId,
11635    ) -> Option<Arc<CachedLspAdapter>> {
11636        self.as_local()
11637            .and_then(|local| local.language_servers.get(&id))
11638            .and_then(|language_server_state| match language_server_state {
11639                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11640                _ => None,
11641            })
11642    }
11643
11644    pub(super) fn update_local_worktree_language_servers(
11645        &mut self,
11646        worktree_handle: &Entity<Worktree>,
11647        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11648        cx: &mut Context<Self>,
11649    ) {
11650        if changes.is_empty() {
11651            return;
11652        }
11653
11654        let Some(local) = self.as_local() else { return };
11655
11656        local.prettier_store.update(cx, |prettier_store, cx| {
11657            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11658        });
11659
11660        let worktree_id = worktree_handle.read(cx).id();
11661        let mut language_server_ids = local
11662            .language_server_ids
11663            .iter()
11664            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11665            .collect::<Vec<_>>();
11666        language_server_ids.sort();
11667        language_server_ids.dedup();
11668
11669        // let abs_path = worktree_handle.read(cx).abs_path();
11670        for server_id in &language_server_ids {
11671            if let Some(LanguageServerState::Running { server, .. }) =
11672                local.language_servers.get(server_id)
11673                && let Some(watched_paths) = local
11674                    .language_server_watched_paths
11675                    .get(server_id)
11676                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11677            {
11678                let params = lsp::DidChangeWatchedFilesParams {
11679                    changes: changes
11680                        .iter()
11681                        .filter_map(|(path, _, change)| {
11682                            if !watched_paths.is_match(path.as_std_path()) {
11683                                return None;
11684                            }
11685                            let typ = match change {
11686                                PathChange::Loaded => return None,
11687                                PathChange::Added => lsp::FileChangeType::CREATED,
11688                                PathChange::Removed => lsp::FileChangeType::DELETED,
11689                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11690                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11691                            };
11692                            let uri = lsp::Uri::from_file_path(
11693                                worktree_handle.read(cx).absolutize(&path),
11694                            )
11695                            .ok()?;
11696                            Some(lsp::FileEvent { uri, typ })
11697                        })
11698                        .collect(),
11699                };
11700                if !params.changes.is_empty() {
11701                    server
11702                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11703                        .ok();
11704                }
11705            }
11706        }
11707        for (path, _, _) in changes {
11708            if let Some(file_name) = path.file_name()
11709                && local.watched_manifest_filenames.contains(file_name)
11710            {
11711                self.request_workspace_config_refresh();
11712                break;
11713            }
11714        }
11715    }
11716
11717    pub fn wait_for_remote_buffer(
11718        &mut self,
11719        id: BufferId,
11720        cx: &mut Context<Self>,
11721    ) -> Task<Result<Entity<Buffer>>> {
11722        self.buffer_store.update(cx, |buffer_store, cx| {
11723            buffer_store.wait_for_remote_buffer(id, cx)
11724        })
11725    }
11726
11727    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11728        let mut result = proto::Symbol {
11729            language_server_name: symbol.language_server_name.0.to_string(),
11730            source_worktree_id: symbol.source_worktree_id.to_proto(),
11731            language_server_id: symbol.source_language_server_id.to_proto(),
11732            name: symbol.name.clone(),
11733            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11734            start: Some(proto::PointUtf16 {
11735                row: symbol.range.start.0.row,
11736                column: symbol.range.start.0.column,
11737            }),
11738            end: Some(proto::PointUtf16 {
11739                row: symbol.range.end.0.row,
11740                column: symbol.range.end.0.column,
11741            }),
11742            worktree_id: Default::default(),
11743            path: Default::default(),
11744            signature: Default::default(),
11745            container_name: symbol.container_name.clone(),
11746        };
11747        match &symbol.path {
11748            SymbolLocation::InProject(path) => {
11749                result.worktree_id = path.worktree_id.to_proto();
11750                result.path = path.path.to_proto();
11751            }
11752            SymbolLocation::OutsideProject {
11753                abs_path,
11754                signature,
11755            } => {
11756                result.path = abs_path.to_string_lossy().into_owned();
11757                result.signature = signature.to_vec();
11758            }
11759        }
11760        result
11761    }
11762
11763    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11764        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11765        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11766        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11767
11768        let path = if serialized_symbol.signature.is_empty() {
11769            SymbolLocation::InProject(ProjectPath {
11770                worktree_id,
11771                path: RelPath::from_proto(&serialized_symbol.path)
11772                    .context("invalid symbol path")?,
11773            })
11774        } else {
11775            SymbolLocation::OutsideProject {
11776                abs_path: Path::new(&serialized_symbol.path).into(),
11777                signature: serialized_symbol
11778                    .signature
11779                    .try_into()
11780                    .map_err(|_| anyhow!("invalid signature"))?,
11781            }
11782        };
11783
11784        let start = serialized_symbol.start.context("invalid start")?;
11785        let end = serialized_symbol.end.context("invalid end")?;
11786        Ok(CoreSymbol {
11787            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11788            source_worktree_id,
11789            source_language_server_id: LanguageServerId::from_proto(
11790                serialized_symbol.language_server_id,
11791            ),
11792            path,
11793            name: serialized_symbol.name,
11794            range: Unclipped(PointUtf16::new(start.row, start.column))
11795                ..Unclipped(PointUtf16::new(end.row, end.column)),
11796            kind,
11797            container_name: serialized_symbol.container_name,
11798        })
11799    }
11800
11801    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11802        let mut serialized_completion = proto::Completion {
11803            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11804            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11805            new_text: completion.new_text.clone(),
11806            ..proto::Completion::default()
11807        };
11808        match &completion.source {
11809            CompletionSource::Lsp {
11810                insert_range,
11811                server_id,
11812                lsp_completion,
11813                lsp_defaults,
11814                resolved,
11815            } => {
11816                let (old_insert_start, old_insert_end) = insert_range
11817                    .as_ref()
11818                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11819                    .unzip();
11820
11821                serialized_completion.old_insert_start = old_insert_start;
11822                serialized_completion.old_insert_end = old_insert_end;
11823                serialized_completion.source = proto::completion::Source::Lsp as i32;
11824                serialized_completion.server_id = server_id.0 as u64;
11825                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11826                serialized_completion.lsp_defaults = lsp_defaults
11827                    .as_deref()
11828                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11829                serialized_completion.resolved = *resolved;
11830            }
11831            CompletionSource::BufferWord {
11832                word_range,
11833                resolved,
11834            } => {
11835                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11836                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11837                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11838                serialized_completion.resolved = *resolved;
11839            }
11840            CompletionSource::Custom => {
11841                serialized_completion.source = proto::completion::Source::Custom as i32;
11842                serialized_completion.resolved = true;
11843            }
11844            CompletionSource::Dap { sort_text } => {
11845                serialized_completion.source = proto::completion::Source::Dap as i32;
11846                serialized_completion.sort_text = Some(sort_text.clone());
11847            }
11848        }
11849
11850        serialized_completion
11851    }
11852
11853    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11854        let old_replace_start = completion
11855            .old_replace_start
11856            .and_then(deserialize_anchor)
11857            .context("invalid old start")?;
11858        let old_replace_end = completion
11859            .old_replace_end
11860            .and_then(deserialize_anchor)
11861            .context("invalid old end")?;
11862        let insert_range = {
11863            match completion.old_insert_start.zip(completion.old_insert_end) {
11864                Some((start, end)) => {
11865                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11866                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11867                    Some(start..end)
11868                }
11869                None => None,
11870            }
11871        };
11872        Ok(CoreCompletion {
11873            replace_range: old_replace_start..old_replace_end,
11874            new_text: completion.new_text,
11875            source: match proto::completion::Source::from_i32(completion.source) {
11876                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11877                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11878                    insert_range,
11879                    server_id: LanguageServerId::from_proto(completion.server_id),
11880                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11881                    lsp_defaults: completion
11882                        .lsp_defaults
11883                        .as_deref()
11884                        .map(serde_json::from_slice)
11885                        .transpose()?,
11886                    resolved: completion.resolved,
11887                },
11888                Some(proto::completion::Source::BufferWord) => {
11889                    let word_range = completion
11890                        .buffer_word_start
11891                        .and_then(deserialize_anchor)
11892                        .context("invalid buffer word start")?
11893                        ..completion
11894                            .buffer_word_end
11895                            .and_then(deserialize_anchor)
11896                            .context("invalid buffer word end")?;
11897                    CompletionSource::BufferWord {
11898                        word_range,
11899                        resolved: completion.resolved,
11900                    }
11901                }
11902                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11903                    sort_text: completion
11904                        .sort_text
11905                        .context("expected sort text to exist")?,
11906                },
11907                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11908            },
11909        })
11910    }
11911
11912    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11913        let (kind, lsp_action) = match &action.lsp_action {
11914            LspAction::Action(code_action) => (
11915                proto::code_action::Kind::Action as i32,
11916                serde_json::to_vec(code_action).unwrap(),
11917            ),
11918            LspAction::Command(command) => (
11919                proto::code_action::Kind::Command as i32,
11920                serde_json::to_vec(command).unwrap(),
11921            ),
11922            LspAction::CodeLens(code_lens) => (
11923                proto::code_action::Kind::CodeLens as i32,
11924                serde_json::to_vec(code_lens).unwrap(),
11925            ),
11926        };
11927
11928        proto::CodeAction {
11929            server_id: action.server_id.0 as u64,
11930            start: Some(serialize_anchor(&action.range.start)),
11931            end: Some(serialize_anchor(&action.range.end)),
11932            lsp_action,
11933            kind,
11934            resolved: action.resolved,
11935        }
11936    }
11937
11938    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11939        let start = action
11940            .start
11941            .and_then(deserialize_anchor)
11942            .context("invalid start")?;
11943        let end = action
11944            .end
11945            .and_then(deserialize_anchor)
11946            .context("invalid end")?;
11947        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11948            Some(proto::code_action::Kind::Action) => {
11949                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11950            }
11951            Some(proto::code_action::Kind::Command) => {
11952                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11953            }
11954            Some(proto::code_action::Kind::CodeLens) => {
11955                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11956            }
11957            None => anyhow::bail!("Unknown action kind {}", action.kind),
11958        };
11959        Ok(CodeAction {
11960            server_id: LanguageServerId(action.server_id as usize),
11961            range: start..end,
11962            resolved: action.resolved,
11963            lsp_action,
11964        })
11965    }
11966
11967    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11968        match &formatting_result {
11969            Ok(_) => self.last_formatting_failure = None,
11970            Err(error) => {
11971                let error_string = format!("{error:#}");
11972                log::error!("Formatting failed: {error_string}");
11973                self.last_formatting_failure
11974                    .replace(error_string.lines().join(" "));
11975            }
11976        }
11977    }
11978
11979    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11980        self.lsp_server_capabilities.remove(&for_server);
11981        self.semantic_token_config.remove_server_data(for_server);
11982        for lsp_data in self.lsp_data.values_mut() {
11983            lsp_data.remove_server_data(for_server);
11984        }
11985        if let Some(local) = self.as_local_mut() {
11986            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11987            local
11988                .workspace_pull_diagnostics_result_ids
11989                .remove(&for_server);
11990            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11991                buffer_servers.remove(&for_server);
11992            }
11993        }
11994    }
11995
11996    pub fn result_id_for_buffer_pull(
11997        &self,
11998        server_id: LanguageServerId,
11999        buffer_id: BufferId,
12000        registration_id: &Option<SharedString>,
12001        cx: &App,
12002    ) -> Option<SharedString> {
12003        let abs_path = self
12004            .buffer_store
12005            .read(cx)
12006            .get(buffer_id)
12007            .and_then(|b| File::from_dyn(b.read(cx).file()))
12008            .map(|f| f.abs_path(cx))?;
12009        self.as_local()?
12010            .buffer_pull_diagnostics_result_ids
12011            .get(&server_id)?
12012            .get(registration_id)?
12013            .get(&abs_path)?
12014            .clone()
12015    }
12016
12017    /// Gets all result_ids for a workspace diagnostics pull request.
12018    /// 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.
12019    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12020    pub fn result_ids_for_workspace_refresh(
12021        &self,
12022        server_id: LanguageServerId,
12023        registration_id: &Option<SharedString>,
12024    ) -> HashMap<PathBuf, SharedString> {
12025        let Some(local) = self.as_local() else {
12026            return HashMap::default();
12027        };
12028        local
12029            .workspace_pull_diagnostics_result_ids
12030            .get(&server_id)
12031            .into_iter()
12032            .filter_map(|diagnostics| diagnostics.get(registration_id))
12033            .flatten()
12034            .filter_map(|(abs_path, result_id)| {
12035                let result_id = local
12036                    .buffer_pull_diagnostics_result_ids
12037                    .get(&server_id)
12038                    .and_then(|buffer_ids_result_ids| {
12039                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12040                    })
12041                    .cloned()
12042                    .flatten()
12043                    .or_else(|| result_id.clone())?;
12044                Some((abs_path.clone(), result_id))
12045            })
12046            .collect()
12047    }
12048
12049    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12050        if let Some(LanguageServerState::Running {
12051            workspace_diagnostics_refresh_tasks,
12052            ..
12053        }) = self
12054            .as_local_mut()
12055            .and_then(|local| local.language_servers.get_mut(&server_id))
12056        {
12057            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12058                diagnostics.refresh_tx.try_send(()).ok();
12059            }
12060        }
12061    }
12062
12063    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12064    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12065    /// which requires refreshing both workspace and document diagnostics.
12066    pub fn pull_document_diagnostics_for_server(
12067        &mut self,
12068        server_id: LanguageServerId,
12069        source_buffer_id: Option<BufferId>,
12070        cx: &mut Context<Self>,
12071    ) -> Shared<Task<()>> {
12072        let Some(local) = self.as_local_mut() else {
12073            return Task::ready(()).shared();
12074        };
12075        let mut buffers_to_refresh = HashSet::default();
12076        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12077            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12078                buffers_to_refresh.insert(*buffer_id);
12079            }
12080        }
12081
12082        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12083    }
12084
12085    pub fn pull_document_diagnostics_for_buffer_edit(
12086        &mut self,
12087        buffer_id: BufferId,
12088        cx: &mut Context<Self>,
12089    ) {
12090        let Some(local) = self.as_local_mut() else {
12091            return;
12092        };
12093        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12094        else {
12095            return;
12096        };
12097        for server_id in languages_servers {
12098            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12099        }
12100    }
12101
12102    fn apply_workspace_diagnostic_report(
12103        &mut self,
12104        server_id: LanguageServerId,
12105        report: lsp::WorkspaceDiagnosticReportResult,
12106        registration_id: Option<SharedString>,
12107        cx: &mut Context<Self>,
12108    ) {
12109        let mut workspace_diagnostics =
12110            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12111                report,
12112                server_id,
12113                registration_id,
12114            );
12115        workspace_diagnostics.retain(|d| match &d.diagnostics {
12116            LspPullDiagnostics::Response {
12117                server_id,
12118                registration_id,
12119                ..
12120            } => self.diagnostic_registration_exists(*server_id, registration_id),
12121            LspPullDiagnostics::Default => false,
12122        });
12123        let mut unchanged_buffers = HashMap::default();
12124        let workspace_diagnostics_updates = workspace_diagnostics
12125            .into_iter()
12126            .filter_map(
12127                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12128                    LspPullDiagnostics::Response {
12129                        server_id,
12130                        uri,
12131                        diagnostics,
12132                        registration_id,
12133                    } => Some((
12134                        server_id,
12135                        uri,
12136                        diagnostics,
12137                        workspace_diagnostics.version,
12138                        registration_id,
12139                    )),
12140                    LspPullDiagnostics::Default => None,
12141                },
12142            )
12143            .fold(
12144                HashMap::default(),
12145                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12146                    let (result_id, diagnostics) = match diagnostics {
12147                        PulledDiagnostics::Unchanged { result_id } => {
12148                            unchanged_buffers
12149                                .entry(new_registration_id.clone())
12150                                .or_insert_with(HashSet::default)
12151                                .insert(uri.clone());
12152                            (Some(result_id), Vec::new())
12153                        }
12154                        PulledDiagnostics::Changed {
12155                            result_id,
12156                            diagnostics,
12157                        } => (result_id, diagnostics),
12158                    };
12159                    let disk_based_sources = Cow::Owned(
12160                        self.language_server_adapter_for_id(server_id)
12161                            .as_ref()
12162                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12163                            .unwrap_or(&[])
12164                            .to_vec(),
12165                    );
12166
12167                    let Some(abs_path) = uri.to_file_path().ok() else {
12168                        return acc;
12169                    };
12170                    let Some((worktree, relative_path)) =
12171                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12172                    else {
12173                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12174                        return acc;
12175                    };
12176                    let worktree_id = worktree.read(cx).id();
12177                    let project_path = ProjectPath {
12178                        worktree_id,
12179                        path: relative_path,
12180                    };
12181                    if let Some(local_lsp_store) = self.as_local_mut() {
12182                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12183                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12184                    }
12185                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12186                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12187                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12188                        acc.entry(server_id)
12189                            .or_insert_with(HashMap::default)
12190                            .entry(new_registration_id.clone())
12191                            .or_insert_with(Vec::new)
12192                            .push(DocumentDiagnosticsUpdate {
12193                                server_id,
12194                                diagnostics: lsp::PublishDiagnosticsParams {
12195                                    uri,
12196                                    diagnostics,
12197                                    version,
12198                                },
12199                                result_id: result_id.map(SharedString::new),
12200                                disk_based_sources,
12201                                registration_id: new_registration_id,
12202                            });
12203                    }
12204                    acc
12205                },
12206            );
12207
12208        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12209            for (registration_id, diagnostic_updates) in diagnostic_updates {
12210                self.merge_lsp_diagnostics(
12211                    DiagnosticSourceKind::Pulled,
12212                    diagnostic_updates,
12213                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12214                        DiagnosticSourceKind::Pulled => {
12215                            old_diagnostic.registration_id != registration_id
12216                                || unchanged_buffers
12217                                    .get(&old_diagnostic.registration_id)
12218                                    .is_some_and(|unchanged_buffers| {
12219                                        unchanged_buffers.contains(&document_uri)
12220                                    })
12221                        }
12222                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12223                    },
12224                    cx,
12225                )
12226                .log_err();
12227            }
12228        }
12229    }
12230
12231    fn register_server_capabilities(
12232        &mut self,
12233        server_id: LanguageServerId,
12234        params: lsp::RegistrationParams,
12235        cx: &mut Context<Self>,
12236    ) -> anyhow::Result<()> {
12237        let server = self
12238            .language_server_for_id(server_id)
12239            .with_context(|| format!("no server {server_id} found"))?;
12240        for reg in params.registrations {
12241            match reg.method.as_str() {
12242                "workspace/didChangeWatchedFiles" => {
12243                    if let Some(options) = reg.register_options {
12244                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12245                            let caps = serde_json::from_value(options)?;
12246                            local_lsp_store
12247                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12248                            true
12249                        } else {
12250                            false
12251                        };
12252                        if notify {
12253                            notify_server_capabilities_updated(&server, cx);
12254                        }
12255                    }
12256                }
12257                "workspace/didChangeConfiguration" => {
12258                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12259                }
12260                "workspace/didChangeWorkspaceFolders" => {
12261                    // In this case register options is an empty object, we can ignore it
12262                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12263                        supported: Some(true),
12264                        change_notifications: Some(OneOf::Right(reg.id)),
12265                    };
12266                    server.update_capabilities(|capabilities| {
12267                        capabilities
12268                            .workspace
12269                            .get_or_insert_default()
12270                            .workspace_folders = Some(caps);
12271                    });
12272                    notify_server_capabilities_updated(&server, cx);
12273                }
12274                "workspace/symbol" => {
12275                    let options = parse_register_capabilities(reg)?;
12276                    server.update_capabilities(|capabilities| {
12277                        capabilities.workspace_symbol_provider = Some(options);
12278                    });
12279                    notify_server_capabilities_updated(&server, cx);
12280                }
12281                "workspace/fileOperations" => {
12282                    if let Some(options) = reg.register_options {
12283                        let caps = serde_json::from_value(options)?;
12284                        server.update_capabilities(|capabilities| {
12285                            capabilities
12286                                .workspace
12287                                .get_or_insert_default()
12288                                .file_operations = Some(caps);
12289                        });
12290                        notify_server_capabilities_updated(&server, cx);
12291                    }
12292                }
12293                "workspace/executeCommand" => {
12294                    if let Some(options) = reg.register_options {
12295                        let options = serde_json::from_value(options)?;
12296                        server.update_capabilities(|capabilities| {
12297                            capabilities.execute_command_provider = Some(options);
12298                        });
12299                        notify_server_capabilities_updated(&server, cx);
12300                    }
12301                }
12302                "textDocument/rangeFormatting" => {
12303                    let options = parse_register_capabilities(reg)?;
12304                    server.update_capabilities(|capabilities| {
12305                        capabilities.document_range_formatting_provider = Some(options);
12306                    });
12307                    notify_server_capabilities_updated(&server, cx);
12308                }
12309                "textDocument/onTypeFormatting" => {
12310                    if let Some(options) = reg
12311                        .register_options
12312                        .map(serde_json::from_value)
12313                        .transpose()?
12314                    {
12315                        server.update_capabilities(|capabilities| {
12316                            capabilities.document_on_type_formatting_provider = Some(options);
12317                        });
12318                        notify_server_capabilities_updated(&server, cx);
12319                    }
12320                }
12321                "textDocument/formatting" => {
12322                    let options = parse_register_capabilities(reg)?;
12323                    server.update_capabilities(|capabilities| {
12324                        capabilities.document_formatting_provider = Some(options);
12325                    });
12326                    notify_server_capabilities_updated(&server, cx);
12327                }
12328                "textDocument/rename" => {
12329                    let options = parse_register_capabilities(reg)?;
12330                    server.update_capabilities(|capabilities| {
12331                        capabilities.rename_provider = Some(options);
12332                    });
12333                    notify_server_capabilities_updated(&server, cx);
12334                }
12335                "textDocument/inlayHint" => {
12336                    let options = parse_register_capabilities(reg)?;
12337                    server.update_capabilities(|capabilities| {
12338                        capabilities.inlay_hint_provider = Some(options);
12339                    });
12340                    notify_server_capabilities_updated(&server, cx);
12341                }
12342                "textDocument/documentSymbol" => {
12343                    let options = parse_register_capabilities(reg)?;
12344                    server.update_capabilities(|capabilities| {
12345                        capabilities.document_symbol_provider = Some(options);
12346                    });
12347                    notify_server_capabilities_updated(&server, cx);
12348                }
12349                "textDocument/codeAction" => {
12350                    let options = parse_register_capabilities(reg)?;
12351                    let provider = match options {
12352                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12353                        OneOf::Right(caps) => caps,
12354                    };
12355                    server.update_capabilities(|capabilities| {
12356                        capabilities.code_action_provider = Some(provider);
12357                    });
12358                    notify_server_capabilities_updated(&server, cx);
12359                }
12360                "textDocument/definition" => {
12361                    let options = parse_register_capabilities(reg)?;
12362                    server.update_capabilities(|capabilities| {
12363                        capabilities.definition_provider = Some(options);
12364                    });
12365                    notify_server_capabilities_updated(&server, cx);
12366                }
12367                "textDocument/completion" => {
12368                    if let Some(caps) = reg
12369                        .register_options
12370                        .map(serde_json::from_value::<CompletionOptions>)
12371                        .transpose()?
12372                    {
12373                        server.update_capabilities(|capabilities| {
12374                            capabilities.completion_provider = Some(caps.clone());
12375                        });
12376
12377                        if let Some(local) = self.as_local() {
12378                            let mut buffers_with_language_server = Vec::new();
12379                            for handle in self.buffer_store.read(cx).buffers() {
12380                                let buffer_id = handle.read(cx).remote_id();
12381                                if local
12382                                    .buffers_opened_in_servers
12383                                    .get(&buffer_id)
12384                                    .filter(|s| s.contains(&server_id))
12385                                    .is_some()
12386                                {
12387                                    buffers_with_language_server.push(handle);
12388                                }
12389                            }
12390                            let triggers = caps
12391                                .trigger_characters
12392                                .unwrap_or_default()
12393                                .into_iter()
12394                                .collect::<BTreeSet<_>>();
12395                            for handle in buffers_with_language_server {
12396                                let triggers = triggers.clone();
12397                                let _ = handle.update(cx, move |buffer, cx| {
12398                                    buffer.set_completion_triggers(server_id, triggers, cx);
12399                                });
12400                            }
12401                        }
12402                        notify_server_capabilities_updated(&server, cx);
12403                    }
12404                }
12405                "textDocument/hover" => {
12406                    let options = parse_register_capabilities(reg)?;
12407                    let provider = match options {
12408                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12409                        OneOf::Right(caps) => caps,
12410                    };
12411                    server.update_capabilities(|capabilities| {
12412                        capabilities.hover_provider = Some(provider);
12413                    });
12414                    notify_server_capabilities_updated(&server, cx);
12415                }
12416                "textDocument/signatureHelp" => {
12417                    if let Some(caps) = reg
12418                        .register_options
12419                        .map(serde_json::from_value)
12420                        .transpose()?
12421                    {
12422                        server.update_capabilities(|capabilities| {
12423                            capabilities.signature_help_provider = Some(caps);
12424                        });
12425                        notify_server_capabilities_updated(&server, cx);
12426                    }
12427                }
12428                "textDocument/didChange" => {
12429                    if let Some(sync_kind) = reg
12430                        .register_options
12431                        .and_then(|opts| opts.get("syncKind").cloned())
12432                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12433                        .transpose()?
12434                    {
12435                        server.update_capabilities(|capabilities| {
12436                            let mut sync_options =
12437                                Self::take_text_document_sync_options(capabilities);
12438                            sync_options.change = Some(sync_kind);
12439                            capabilities.text_document_sync =
12440                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12441                        });
12442                        notify_server_capabilities_updated(&server, cx);
12443                    }
12444                }
12445                "textDocument/didSave" => {
12446                    if let Some(include_text) = reg
12447                        .register_options
12448                        .map(|opts| {
12449                            let transpose = opts
12450                                .get("includeText")
12451                                .cloned()
12452                                .map(serde_json::from_value::<Option<bool>>)
12453                                .transpose();
12454                            match transpose {
12455                                Ok(value) => Ok(value.flatten()),
12456                                Err(e) => Err(e),
12457                            }
12458                        })
12459                        .transpose()?
12460                    {
12461                        server.update_capabilities(|capabilities| {
12462                            let mut sync_options =
12463                                Self::take_text_document_sync_options(capabilities);
12464                            sync_options.save =
12465                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12466                                    include_text,
12467                                }));
12468                            capabilities.text_document_sync =
12469                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12470                        });
12471                        notify_server_capabilities_updated(&server, cx);
12472                    }
12473                }
12474                "textDocument/codeLens" => {
12475                    if let Some(caps) = reg
12476                        .register_options
12477                        .map(serde_json::from_value)
12478                        .transpose()?
12479                    {
12480                        server.update_capabilities(|capabilities| {
12481                            capabilities.code_lens_provider = Some(caps);
12482                        });
12483                        notify_server_capabilities_updated(&server, cx);
12484                    }
12485                }
12486                "textDocument/diagnostic" => {
12487                    if let Some(caps) = reg
12488                        .register_options
12489                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12490                        .transpose()?
12491                    {
12492                        let local = self
12493                            .as_local_mut()
12494                            .context("Expected LSP Store to be local")?;
12495                        let state = local
12496                            .language_servers
12497                            .get_mut(&server_id)
12498                            .context("Could not obtain Language Servers state")?;
12499                        local
12500                            .language_server_dynamic_registrations
12501                            .entry(server_id)
12502                            .or_default()
12503                            .diagnostics
12504                            .insert(Some(reg.id.clone()), caps.clone());
12505
12506                        let supports_workspace_diagnostics =
12507                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12508                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12509                                    diagnostic_options.workspace_diagnostics
12510                                }
12511                                DiagnosticServerCapabilities::RegistrationOptions(
12512                                    diagnostic_registration_options,
12513                                ) => {
12514                                    diagnostic_registration_options
12515                                        .diagnostic_options
12516                                        .workspace_diagnostics
12517                                }
12518                            };
12519
12520                        if supports_workspace_diagnostics(&caps) {
12521                            if let LanguageServerState::Running {
12522                                workspace_diagnostics_refresh_tasks,
12523                                ..
12524                            } = state
12525                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12526                                    Some(reg.id.clone()),
12527                                    caps.clone(),
12528                                    server.clone(),
12529                                    cx,
12530                                )
12531                            {
12532                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12533                            }
12534                        }
12535
12536                        server.update_capabilities(|capabilities| {
12537                            capabilities.diagnostic_provider = Some(caps);
12538                        });
12539
12540                        notify_server_capabilities_updated(&server, cx);
12541
12542                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12543                    }
12544                }
12545                "textDocument/documentColor" => {
12546                    let options = parse_register_capabilities(reg)?;
12547                    let provider = match options {
12548                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12549                        OneOf::Right(caps) => caps,
12550                    };
12551                    server.update_capabilities(|capabilities| {
12552                        capabilities.color_provider = Some(provider);
12553                    });
12554                    notify_server_capabilities_updated(&server, cx);
12555                }
12556                "textDocument/foldingRange" => {
12557                    let options = parse_register_capabilities(reg)?;
12558                    let provider = match options {
12559                        OneOf::Left(value) => lsp::FoldingRangeProviderCapability::Simple(value),
12560                        OneOf::Right(caps) => caps,
12561                    };
12562                    server.update_capabilities(|capabilities| {
12563                        capabilities.folding_range_provider = Some(provider);
12564                    });
12565                    notify_server_capabilities_updated(&server, cx);
12566                }
12567                _ => log::warn!("unhandled capability registration: {reg:?}"),
12568            }
12569        }
12570
12571        Ok(())
12572    }
12573
12574    fn unregister_server_capabilities(
12575        &mut self,
12576        server_id: LanguageServerId,
12577        params: lsp::UnregistrationParams,
12578        cx: &mut Context<Self>,
12579    ) -> anyhow::Result<()> {
12580        let server = self
12581            .language_server_for_id(server_id)
12582            .with_context(|| format!("no server {server_id} found"))?;
12583        for unreg in params.unregisterations.iter() {
12584            match unreg.method.as_str() {
12585                "workspace/didChangeWatchedFiles" => {
12586                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12587                        local_lsp_store
12588                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12589                        true
12590                    } else {
12591                        false
12592                    };
12593                    if notify {
12594                        notify_server_capabilities_updated(&server, cx);
12595                    }
12596                }
12597                "workspace/didChangeConfiguration" => {
12598                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12599                }
12600                "workspace/didChangeWorkspaceFolders" => {
12601                    server.update_capabilities(|capabilities| {
12602                        capabilities
12603                            .workspace
12604                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12605                                workspace_folders: None,
12606                                file_operations: None,
12607                            })
12608                            .workspace_folders = None;
12609                    });
12610                    notify_server_capabilities_updated(&server, cx);
12611                }
12612                "workspace/symbol" => {
12613                    server.update_capabilities(|capabilities| {
12614                        capabilities.workspace_symbol_provider = None
12615                    });
12616                    notify_server_capabilities_updated(&server, cx);
12617                }
12618                "workspace/fileOperations" => {
12619                    server.update_capabilities(|capabilities| {
12620                        capabilities
12621                            .workspace
12622                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12623                                workspace_folders: None,
12624                                file_operations: None,
12625                            })
12626                            .file_operations = None;
12627                    });
12628                    notify_server_capabilities_updated(&server, cx);
12629                }
12630                "workspace/executeCommand" => {
12631                    server.update_capabilities(|capabilities| {
12632                        capabilities.execute_command_provider = None;
12633                    });
12634                    notify_server_capabilities_updated(&server, cx);
12635                }
12636                "textDocument/rangeFormatting" => {
12637                    server.update_capabilities(|capabilities| {
12638                        capabilities.document_range_formatting_provider = None
12639                    });
12640                    notify_server_capabilities_updated(&server, cx);
12641                }
12642                "textDocument/onTypeFormatting" => {
12643                    server.update_capabilities(|capabilities| {
12644                        capabilities.document_on_type_formatting_provider = None;
12645                    });
12646                    notify_server_capabilities_updated(&server, cx);
12647                }
12648                "textDocument/formatting" => {
12649                    server.update_capabilities(|capabilities| {
12650                        capabilities.document_formatting_provider = None;
12651                    });
12652                    notify_server_capabilities_updated(&server, cx);
12653                }
12654                "textDocument/rename" => {
12655                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12656                    notify_server_capabilities_updated(&server, cx);
12657                }
12658                "textDocument/codeAction" => {
12659                    server.update_capabilities(|capabilities| {
12660                        capabilities.code_action_provider = None;
12661                    });
12662                    notify_server_capabilities_updated(&server, cx);
12663                }
12664                "textDocument/definition" => {
12665                    server.update_capabilities(|capabilities| {
12666                        capabilities.definition_provider = None;
12667                    });
12668                    notify_server_capabilities_updated(&server, cx);
12669                }
12670                "textDocument/completion" => {
12671                    server.update_capabilities(|capabilities| {
12672                        capabilities.completion_provider = None;
12673                    });
12674                    notify_server_capabilities_updated(&server, cx);
12675                }
12676                "textDocument/hover" => {
12677                    server.update_capabilities(|capabilities| {
12678                        capabilities.hover_provider = None;
12679                    });
12680                    notify_server_capabilities_updated(&server, cx);
12681                }
12682                "textDocument/signatureHelp" => {
12683                    server.update_capabilities(|capabilities| {
12684                        capabilities.signature_help_provider = None;
12685                    });
12686                    notify_server_capabilities_updated(&server, cx);
12687                }
12688                "textDocument/didChange" => {
12689                    server.update_capabilities(|capabilities| {
12690                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12691                        sync_options.change = None;
12692                        capabilities.text_document_sync =
12693                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12694                    });
12695                    notify_server_capabilities_updated(&server, cx);
12696                }
12697                "textDocument/didSave" => {
12698                    server.update_capabilities(|capabilities| {
12699                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12700                        sync_options.save = None;
12701                        capabilities.text_document_sync =
12702                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12703                    });
12704                    notify_server_capabilities_updated(&server, cx);
12705                }
12706                "textDocument/codeLens" => {
12707                    server.update_capabilities(|capabilities| {
12708                        capabilities.code_lens_provider = None;
12709                    });
12710                    notify_server_capabilities_updated(&server, cx);
12711                }
12712                "textDocument/diagnostic" => {
12713                    let local = self
12714                        .as_local_mut()
12715                        .context("Expected LSP Store to be local")?;
12716
12717                    let state = local
12718                        .language_servers
12719                        .get_mut(&server_id)
12720                        .context("Could not obtain Language Servers state")?;
12721                    let registrations = local
12722                        .language_server_dynamic_registrations
12723                        .get_mut(&server_id)
12724                        .with_context(|| {
12725                            format!("Expected dynamic registration to exist for server {server_id}")
12726                        })?;
12727                    registrations.diagnostics
12728                        .remove(&Some(unreg.id.clone()))
12729                        .with_context(|| format!(
12730                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12731                            unreg.id)
12732                        )?;
12733                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12734
12735                    if let LanguageServerState::Running {
12736                        workspace_diagnostics_refresh_tasks,
12737                        ..
12738                    } = state
12739                    {
12740                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12741                    }
12742
12743                    self.clear_unregistered_diagnostics(
12744                        server_id,
12745                        SharedString::from(unreg.id.clone()),
12746                        cx,
12747                    )?;
12748
12749                    if removed_last_diagnostic_provider {
12750                        server.update_capabilities(|capabilities| {
12751                            debug_assert!(capabilities.diagnostic_provider.is_some());
12752                            capabilities.diagnostic_provider = None;
12753                        });
12754                    }
12755
12756                    notify_server_capabilities_updated(&server, cx);
12757                }
12758                "textDocument/documentColor" => {
12759                    server.update_capabilities(|capabilities| {
12760                        capabilities.color_provider = None;
12761                    });
12762                    notify_server_capabilities_updated(&server, cx);
12763                }
12764                "textDocument/foldingRange" => {
12765                    server.update_capabilities(|capabilities| {
12766                        capabilities.folding_range_provider = None;
12767                    });
12768                    notify_server_capabilities_updated(&server, cx);
12769                }
12770                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12771            }
12772        }
12773
12774        Ok(())
12775    }
12776
12777    fn clear_unregistered_diagnostics(
12778        &mut self,
12779        server_id: LanguageServerId,
12780        cleared_registration_id: SharedString,
12781        cx: &mut Context<Self>,
12782    ) -> anyhow::Result<()> {
12783        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12784
12785        self.buffer_store.update(cx, |buffer_store, cx| {
12786            for buffer_handle in buffer_store.buffers() {
12787                let buffer = buffer_handle.read(cx);
12788                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12789                let Some(abs_path) = abs_path else {
12790                    continue;
12791                };
12792                affected_abs_paths.insert(abs_path);
12793            }
12794        });
12795
12796        let local = self.as_local().context("Expected LSP Store to be local")?;
12797        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12798            let Some(worktree) = self
12799                .worktree_store
12800                .read(cx)
12801                .worktree_for_id(*worktree_id, cx)
12802            else {
12803                continue;
12804            };
12805
12806            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
12807                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
12808                    let has_matching_registration =
12809                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
12810                            entry.diagnostic.registration_id.as_ref()
12811                                == Some(&cleared_registration_id)
12812                        });
12813                    if has_matching_registration {
12814                        let abs_path = worktree.read(cx).absolutize(rel_path);
12815                        affected_abs_paths.insert(abs_path);
12816                    }
12817                }
12818            }
12819        }
12820
12821        if affected_abs_paths.is_empty() {
12822            return Ok(());
12823        }
12824
12825        // Send a fake diagnostic update which clears the state for the registration ID
12826        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
12827            affected_abs_paths
12828                .into_iter()
12829                .map(|abs_path| DocumentDiagnosticsUpdate {
12830                    diagnostics: DocumentDiagnostics {
12831                        diagnostics: Vec::new(),
12832                        document_abs_path: abs_path,
12833                        version: None,
12834                    },
12835                    result_id: None,
12836                    registration_id: Some(cleared_registration_id.clone()),
12837                    server_id,
12838                    disk_based_sources: Cow::Borrowed(&[]),
12839                })
12840                .collect();
12841
12842        let merge_registration_id = cleared_registration_id.clone();
12843        self.merge_diagnostic_entries(
12844            clears,
12845            move |_, diagnostic, _| {
12846                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
12847                    diagnostic.registration_id != Some(merge_registration_id.clone())
12848                } else {
12849                    true
12850                }
12851            },
12852            cx,
12853        )?;
12854
12855        Ok(())
12856    }
12857
12858    async fn deduplicate_range_based_lsp_requests<T>(
12859        lsp_store: &Entity<Self>,
12860        server_id: Option<LanguageServerId>,
12861        lsp_request_id: LspRequestId,
12862        proto_request: &T::ProtoRequest,
12863        range: Range<Anchor>,
12864        cx: &mut AsyncApp,
12865    ) -> Result<()>
12866    where
12867        T: LspCommand,
12868        T::ProtoRequest: proto::LspRequestMessage,
12869    {
12870        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12871        let version = deserialize_version(proto_request.buffer_version());
12872        let buffer = lsp_store.update(cx, |this, cx| {
12873            this.buffer_store.read(cx).get_existing(buffer_id)
12874        })?;
12875        buffer
12876            .update(cx, |buffer, _| buffer.wait_for_version(version))
12877            .await?;
12878        lsp_store.update(cx, |lsp_store, cx| {
12879            let buffer_snapshot = buffer.read(cx).snapshot();
12880            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12881            let chunks_queried_for = lsp_data
12882                .inlay_hints
12883                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
12884                .collect::<Vec<_>>();
12885            match chunks_queried_for.as_slice() {
12886                &[chunk] => {
12887                    let key = LspKey {
12888                        request_type: TypeId::of::<T>(),
12889                        server_queried: server_id,
12890                    };
12891                    let previous_request = lsp_data
12892                        .chunk_lsp_requests
12893                        .entry(key)
12894                        .or_default()
12895                        .insert(chunk, lsp_request_id);
12896                    if let Some((previous_request, running_requests)) =
12897                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12898                    {
12899                        running_requests.remove(&previous_request);
12900                    }
12901                }
12902                _ambiguous_chunks => {
12903                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12904                    // there, a buffer version-based check will be performed and outdated requests discarded.
12905                }
12906            }
12907            anyhow::Ok(())
12908        })?;
12909
12910        Ok(())
12911    }
12912
12913    async fn query_lsp_locally<T>(
12914        lsp_store: Entity<Self>,
12915        for_server_id: Option<LanguageServerId>,
12916        sender_id: proto::PeerId,
12917        lsp_request_id: LspRequestId,
12918        proto_request: T::ProtoRequest,
12919        position: Option<Anchor>,
12920        cx: &mut AsyncApp,
12921    ) -> Result<()>
12922    where
12923        T: LspCommand + Clone,
12924        T::ProtoRequest: proto::LspRequestMessage,
12925        <T::ProtoRequest as proto::RequestMessage>::Response:
12926            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12927    {
12928        let (buffer_version, buffer) =
12929            Self::wait_for_buffer_version::<T>(&lsp_store, &proto_request, cx).await?;
12930        let request =
12931            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12932        let key = LspKey {
12933            request_type: TypeId::of::<T>(),
12934            server_queried: for_server_id,
12935        };
12936        lsp_store.update(cx, |lsp_store, cx| {
12937            let request_task = match for_server_id {
12938                Some(server_id) => {
12939                    let server_task = lsp_store.request_lsp(
12940                        buffer.clone(),
12941                        LanguageServerToQuery::Other(server_id),
12942                        request.clone(),
12943                        cx,
12944                    );
12945                    cx.background_spawn(async move {
12946                        let mut responses = Vec::new();
12947                        match server_task.await {
12948                            Ok(response) => responses.push((server_id, response)),
12949                            // rust-analyzer likes to error with this when its still loading up
12950                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
12951                            Err(e) => log::error!(
12952                                "Error handling response for request {request:?}: {e:#}"
12953                            ),
12954                        }
12955                        responses
12956                    })
12957                }
12958                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12959            };
12960            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12961            if T::ProtoRequest::stop_previous_requests() {
12962                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12963                    lsp_requests.clear();
12964                }
12965            }
12966            lsp_data.lsp_requests.entry(key).or_default().insert(
12967                lsp_request_id,
12968                cx.spawn(async move |lsp_store, cx| {
12969                    let response = request_task.await;
12970                    lsp_store
12971                        .update(cx, |lsp_store, cx| {
12972                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12973                            {
12974                                let response = response
12975                                    .into_iter()
12976                                    .map(|(server_id, response)| {
12977                                        (
12978                                            server_id.to_proto(),
12979                                            T::response_to_proto(
12980                                                response,
12981                                                lsp_store,
12982                                                sender_id,
12983                                                &buffer_version,
12984                                                cx,
12985                                            )
12986                                            .into(),
12987                                        )
12988                                    })
12989                                    .collect::<HashMap<_, _>>();
12990                                match client.send_lsp_response::<T::ProtoRequest>(
12991                                    project_id,
12992                                    lsp_request_id,
12993                                    response,
12994                                ) {
12995                                    Ok(()) => {}
12996                                    Err(e) => {
12997                                        log::error!("Failed to send LSP response: {e:#}",)
12998                                    }
12999                                }
13000                            }
13001                        })
13002                        .ok();
13003                }),
13004            );
13005        });
13006        Ok(())
13007    }
13008
13009    async fn wait_for_buffer_version<T>(
13010        lsp_store: &Entity<Self>,
13011        proto_request: &T::ProtoRequest,
13012        cx: &mut AsyncApp,
13013    ) -> Result<(Global, Entity<Buffer>)>
13014    where
13015        T: LspCommand,
13016        T::ProtoRequest: proto::LspRequestMessage,
13017    {
13018        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13019        let version = deserialize_version(proto_request.buffer_version());
13020        let buffer = lsp_store.update(cx, |this, cx| {
13021            this.buffer_store.read(cx).get_existing(buffer_id)
13022        })?;
13023        buffer
13024            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13025            .await?;
13026        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13027        Ok((buffer_version, buffer))
13028    }
13029
13030    fn take_text_document_sync_options(
13031        capabilities: &mut lsp::ServerCapabilities,
13032    ) -> lsp::TextDocumentSyncOptions {
13033        match capabilities.text_document_sync.take() {
13034            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13035            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13036                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13037                sync_options.change = Some(sync_kind);
13038                sync_options
13039            }
13040            None => lsp::TextDocumentSyncOptions::default(),
13041        }
13042    }
13043
13044    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13045        self.downstream_client.clone()
13046    }
13047
13048    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13049        self.worktree_store.clone()
13050    }
13051
13052    /// Gets what's stored in the LSP data for the given buffer.
13053    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13054        self.lsp_data.get_mut(&buffer_id)
13055    }
13056
13057    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13058    /// new [`BufferLspData`] will be created to replace the previous state.
13059    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13060        let (buffer_id, buffer_version) =
13061            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13062        let lsp_data = self
13063            .lsp_data
13064            .entry(buffer_id)
13065            .or_insert_with(|| BufferLspData::new(buffer, cx));
13066        if buffer_version.changed_since(&lsp_data.buffer_version) {
13067            // To send delta requests for semantic tokens, the previous tokens
13068            // need to be kept between buffer changes.
13069            let semantic_tokens = lsp_data.semantic_tokens.take();
13070            *lsp_data = BufferLspData::new(buffer, cx);
13071            lsp_data.semantic_tokens = semantic_tokens;
13072        }
13073        lsp_data
13074    }
13075}
13076
13077// Registration with registerOptions as null, should fallback to true.
13078// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13079fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13080    reg: lsp::Registration,
13081) -> Result<OneOf<bool, T>> {
13082    Ok(match reg.register_options {
13083        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13084        None => OneOf::Left(true),
13085    })
13086}
13087
13088fn subscribe_to_binary_statuses(
13089    languages: &Arc<LanguageRegistry>,
13090    cx: &mut Context<'_, LspStore>,
13091) -> Task<()> {
13092    let mut server_statuses = languages.language_server_binary_statuses();
13093    cx.spawn(async move |lsp_store, cx| {
13094        while let Some((server_name, binary_status)) = server_statuses.next().await {
13095            if lsp_store
13096                .update(cx, |_, cx| {
13097                    let mut message = None;
13098                    let binary_status = match binary_status {
13099                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13100                        BinaryStatus::CheckingForUpdate => {
13101                            proto::ServerBinaryStatus::CheckingForUpdate
13102                        }
13103                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13104                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13105                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13106                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13107                        BinaryStatus::Failed { error } => {
13108                            message = Some(error);
13109                            proto::ServerBinaryStatus::Failed
13110                        }
13111                    };
13112                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13113                        // Binary updates are about the binary that might not have any language server id at that point.
13114                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13115                        language_server_id: LanguageServerId(0),
13116                        name: Some(server_name),
13117                        message: proto::update_language_server::Variant::StatusUpdate(
13118                            proto::StatusUpdate {
13119                                message,
13120                                status: Some(proto::status_update::Status::Binary(
13121                                    binary_status as i32,
13122                                )),
13123                            },
13124                        ),
13125                    });
13126                })
13127                .is_err()
13128            {
13129                break;
13130            }
13131        }
13132    })
13133}
13134
13135fn lsp_workspace_diagnostics_refresh(
13136    registration_id: Option<String>,
13137    options: DiagnosticServerCapabilities,
13138    server: Arc<LanguageServer>,
13139    cx: &mut Context<'_, LspStore>,
13140) -> Option<WorkspaceRefreshTask> {
13141    let identifier = workspace_diagnostic_identifier(&options)?;
13142    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13143
13144    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13145    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13146    refresh_tx.try_send(()).ok();
13147
13148    let request_timeout = ProjectSettings::get_global(cx)
13149        .global_lsp_settings
13150        .get_request_timeout();
13151
13152    // 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.
13153    // This allows users to increase the duration if need be
13154    let timeout = if request_timeout != Duration::ZERO {
13155        request_timeout.max(DEFAULT_LSP_REQUEST_TIMEOUT)
13156    } else {
13157        request_timeout
13158    };
13159
13160    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13161        let mut attempts = 0;
13162        let max_attempts = 50;
13163        let mut requests = 0;
13164
13165        loop {
13166            let Some(()) = refresh_rx.recv().await else {
13167                return;
13168            };
13169
13170            'request: loop {
13171                requests += 1;
13172                if attempts > max_attempts {
13173                    log::error!(
13174                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13175                    );
13176                    return;
13177                }
13178                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13179                cx.background_executor()
13180                    .timer(Duration::from_millis(backoff_millis))
13181                    .await;
13182                attempts += 1;
13183
13184                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13185                    lsp_store
13186                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13187                        .into_iter()
13188                        .filter_map(|(abs_path, result_id)| {
13189                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13190                            Some(lsp::PreviousResultId {
13191                                uri,
13192                                value: result_id.to_string(),
13193                            })
13194                        })
13195                        .collect()
13196                }) else {
13197                    return;
13198                };
13199
13200                let token = if let Some(registration_id) = &registration_id {
13201                    format!(
13202                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13203                        server.server_id(),
13204                    )
13205                } else {
13206                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13207                };
13208
13209                progress_rx.try_recv().ok();
13210                let timer = server.request_timer(timeout).fuse();
13211                let progress = pin!(progress_rx.recv().fuse());
13212                let response_result = server
13213                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13214                        lsp::WorkspaceDiagnosticParams {
13215                            previous_result_ids,
13216                            identifier: identifier.clone(),
13217                            work_done_progress_params: Default::default(),
13218                            partial_result_params: lsp::PartialResultParams {
13219                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13220                            },
13221                        },
13222                        select(timer, progress).then(|either| match either {
13223                            Either::Left((message, ..)) => ready(message).left_future(),
13224                            Either::Right(..) => pending::<String>().right_future(),
13225                        }),
13226                    )
13227                    .await;
13228
13229                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13230                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13231                match response_result {
13232                    ConnectionResult::Timeout => {
13233                        log::error!("Timeout during workspace diagnostics pull");
13234                        continue 'request;
13235                    }
13236                    ConnectionResult::ConnectionReset => {
13237                        log::error!("Server closed a workspace diagnostics pull request");
13238                        continue 'request;
13239                    }
13240                    ConnectionResult::Result(Err(e)) => {
13241                        log::error!("Error during workspace diagnostics pull: {e:#}");
13242                        break 'request;
13243                    }
13244                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13245                        attempts = 0;
13246                        if lsp_store
13247                            .update(cx, |lsp_store, cx| {
13248                                lsp_store.apply_workspace_diagnostic_report(
13249                                    server.server_id(),
13250                                    pulled_diagnostics,
13251                                    registration_id_shared.clone(),
13252                                    cx,
13253                                )
13254                            })
13255                            .is_err()
13256                        {
13257                            return;
13258                        }
13259                        break 'request;
13260                    }
13261                }
13262            }
13263        }
13264    });
13265
13266    Some(WorkspaceRefreshTask {
13267        refresh_tx,
13268        progress_tx,
13269        task: workspace_query_language_server,
13270    })
13271}
13272
13273fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<SharedString> {
13274    match &options {
13275        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => diagnostic_options
13276            .identifier
13277            .as_deref()
13278            .map(SharedString::new),
13279        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13280            let diagnostic_options = &registration_options.diagnostic_options;
13281            diagnostic_options
13282                .identifier
13283                .as_deref()
13284                .map(SharedString::new)
13285        }
13286    }
13287}
13288
13289fn workspace_diagnostic_identifier(
13290    options: &DiagnosticServerCapabilities,
13291) -> Option<Option<String>> {
13292    match &options {
13293        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13294            if !diagnostic_options.workspace_diagnostics {
13295                return None;
13296            }
13297            Some(diagnostic_options.identifier.clone())
13298        }
13299        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13300            let diagnostic_options = &registration_options.diagnostic_options;
13301            if !diagnostic_options.workspace_diagnostics {
13302                return None;
13303            }
13304            Some(diagnostic_options.identifier.clone())
13305        }
13306    }
13307}
13308
13309fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13310    let CompletionSource::BufferWord {
13311        word_range,
13312        resolved,
13313    } = &mut completion.source
13314    else {
13315        return;
13316    };
13317    if *resolved {
13318        return;
13319    }
13320
13321    if completion.new_text
13322        != snapshot
13323            .text_for_range(word_range.clone())
13324            .collect::<String>()
13325    {
13326        return;
13327    }
13328
13329    let mut offset = 0;
13330    for chunk in snapshot.chunks(word_range.clone(), true) {
13331        let end_offset = offset + chunk.text.len();
13332        if let Some(highlight_id) = chunk.syntax_highlight_id {
13333            completion
13334                .label
13335                .runs
13336                .push((offset..end_offset, highlight_id));
13337        }
13338        offset = end_offset;
13339    }
13340    *resolved = true;
13341}
13342
13343impl EventEmitter<LspStoreEvent> for LspStore {}
13344
13345fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13346    hover
13347        .contents
13348        .retain(|hover_block| !hover_block.text.trim().is_empty());
13349    if hover.contents.is_empty() {
13350        None
13351    } else {
13352        Some(hover)
13353    }
13354}
13355
13356async fn populate_labels_for_completions(
13357    new_completions: Vec<CoreCompletion>,
13358    language: Option<Arc<Language>>,
13359    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13360) -> Vec<Completion> {
13361    let lsp_completions = new_completions
13362        .iter()
13363        .filter_map(|new_completion| {
13364            new_completion
13365                .source
13366                .lsp_completion(true)
13367                .map(|lsp_completion| lsp_completion.into_owned())
13368        })
13369        .collect::<Vec<_>>();
13370
13371    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13372        lsp_adapter
13373            .labels_for_completions(&lsp_completions, language)
13374            .await
13375            .log_err()
13376            .unwrap_or_default()
13377    } else {
13378        Vec::new()
13379    }
13380    .into_iter()
13381    .fuse();
13382
13383    let mut completions = Vec::new();
13384    for completion in new_completions {
13385        match completion.source.lsp_completion(true) {
13386            Some(lsp_completion) => {
13387                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13388
13389                let mut label = labels.next().flatten().unwrap_or_else(|| {
13390                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13391                });
13392                ensure_uniform_list_compatible_label(&mut label);
13393                completions.push(Completion {
13394                    label,
13395                    documentation,
13396                    replace_range: completion.replace_range,
13397                    new_text: completion.new_text,
13398                    insert_text_mode: lsp_completion.insert_text_mode,
13399                    source: completion.source,
13400                    icon_path: None,
13401                    confirm: None,
13402                    match_start: None,
13403                    snippet_deduplication_key: None,
13404                });
13405            }
13406            None => {
13407                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13408                ensure_uniform_list_compatible_label(&mut label);
13409                completions.push(Completion {
13410                    label,
13411                    documentation: None,
13412                    replace_range: completion.replace_range,
13413                    new_text: completion.new_text,
13414                    source: completion.source,
13415                    insert_text_mode: None,
13416                    icon_path: None,
13417                    confirm: None,
13418                    match_start: None,
13419                    snippet_deduplication_key: None,
13420                });
13421            }
13422        }
13423    }
13424    completions
13425}
13426
13427#[derive(Debug)]
13428pub enum LanguageServerToQuery {
13429    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13430    FirstCapable,
13431    /// Query a specific language server.
13432    Other(LanguageServerId),
13433}
13434
13435#[derive(Default)]
13436struct RenamePathsWatchedForServer {
13437    did_rename: Vec<RenameActionPredicate>,
13438    will_rename: Vec<RenameActionPredicate>,
13439}
13440
13441impl RenamePathsWatchedForServer {
13442    fn with_did_rename_patterns(
13443        mut self,
13444        did_rename: Option<&FileOperationRegistrationOptions>,
13445    ) -> Self {
13446        if let Some(did_rename) = did_rename {
13447            self.did_rename = did_rename
13448                .filters
13449                .iter()
13450                .filter_map(|filter| filter.try_into().log_err())
13451                .collect();
13452        }
13453        self
13454    }
13455    fn with_will_rename_patterns(
13456        mut self,
13457        will_rename: Option<&FileOperationRegistrationOptions>,
13458    ) -> Self {
13459        if let Some(will_rename) = will_rename {
13460            self.will_rename = will_rename
13461                .filters
13462                .iter()
13463                .filter_map(|filter| filter.try_into().log_err())
13464                .collect();
13465        }
13466        self
13467    }
13468
13469    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13470        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13471    }
13472    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13473        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13474    }
13475}
13476
13477impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13478    type Error = globset::Error;
13479    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13480        Ok(Self {
13481            kind: ops.pattern.matches.clone(),
13482            glob: GlobBuilder::new(&ops.pattern.glob)
13483                .case_insensitive(
13484                    ops.pattern
13485                        .options
13486                        .as_ref()
13487                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13488                )
13489                .build()?
13490                .compile_matcher(),
13491        })
13492    }
13493}
13494struct RenameActionPredicate {
13495    glob: GlobMatcher,
13496    kind: Option<FileOperationPatternKind>,
13497}
13498
13499impl RenameActionPredicate {
13500    // Returns true if language server should be notified
13501    fn eval(&self, path: &str, is_dir: bool) -> bool {
13502        self.kind.as_ref().is_none_or(|kind| {
13503            let expected_kind = if is_dir {
13504                FileOperationPatternKind::Folder
13505            } else {
13506                FileOperationPatternKind::File
13507            };
13508            kind == &expected_kind
13509        }) && self.glob.is_match(path)
13510    }
13511}
13512
13513#[derive(Default)]
13514struct LanguageServerWatchedPaths {
13515    worktree_paths: HashMap<WorktreeId, GlobSet>,
13516    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13517}
13518
13519#[derive(Default)]
13520struct LanguageServerWatchedPathsBuilder {
13521    worktree_paths: HashMap<WorktreeId, GlobSet>,
13522    abs_paths: HashMap<Arc<Path>, GlobSet>,
13523}
13524
13525impl LanguageServerWatchedPathsBuilder {
13526    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13527        self.worktree_paths.insert(worktree_id, glob_set);
13528    }
13529    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13530        self.abs_paths.insert(path, glob_set);
13531    }
13532    fn build(
13533        self,
13534        fs: Arc<dyn Fs>,
13535        language_server_id: LanguageServerId,
13536        cx: &mut Context<LspStore>,
13537    ) -> LanguageServerWatchedPaths {
13538        let lsp_store = cx.weak_entity();
13539
13540        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13541        let abs_paths = self
13542            .abs_paths
13543            .into_iter()
13544            .map(|(abs_path, globset)| {
13545                let task = cx.spawn({
13546                    let abs_path = abs_path.clone();
13547                    let fs = fs.clone();
13548
13549                    let lsp_store = lsp_store.clone();
13550                    async move |_, cx| {
13551                        maybe!(async move {
13552                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13553                            while let Some(update) = push_updates.0.next().await {
13554                                let action = lsp_store
13555                                    .update(cx, |this, _| {
13556                                        let Some(local) = this.as_local() else {
13557                                            return ControlFlow::Break(());
13558                                        };
13559                                        let Some(watcher) = local
13560                                            .language_server_watched_paths
13561                                            .get(&language_server_id)
13562                                        else {
13563                                            return ControlFlow::Break(());
13564                                        };
13565                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13566                                            "Watched abs path is not registered with a watcher",
13567                                        );
13568                                        let matching_entries = update
13569                                            .into_iter()
13570                                            .filter(|event| globs.is_match(&event.path))
13571                                            .collect::<Vec<_>>();
13572                                        this.lsp_notify_abs_paths_changed(
13573                                            language_server_id,
13574                                            matching_entries,
13575                                        );
13576                                        ControlFlow::Continue(())
13577                                    })
13578                                    .ok()?;
13579
13580                                if action.is_break() {
13581                                    break;
13582                                }
13583                            }
13584                            Some(())
13585                        })
13586                        .await;
13587                    }
13588                });
13589                (abs_path, (globset, task))
13590            })
13591            .collect();
13592        LanguageServerWatchedPaths {
13593            worktree_paths: self.worktree_paths,
13594            abs_paths,
13595        }
13596    }
13597}
13598
13599struct LspBufferSnapshot {
13600    version: i32,
13601    snapshot: TextBufferSnapshot,
13602}
13603
13604/// A prompt requested by LSP server.
13605#[derive(Clone, Debug)]
13606pub struct LanguageServerPromptRequest {
13607    pub id: usize,
13608    pub level: PromptLevel,
13609    pub message: String,
13610    pub actions: Vec<MessageActionItem>,
13611    pub lsp_name: String,
13612    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13613}
13614
13615impl LanguageServerPromptRequest {
13616    pub fn new(
13617        level: PromptLevel,
13618        message: String,
13619        actions: Vec<MessageActionItem>,
13620        lsp_name: String,
13621        response_channel: smol::channel::Sender<MessageActionItem>,
13622    ) -> Self {
13623        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13624        LanguageServerPromptRequest {
13625            id,
13626            level,
13627            message,
13628            actions,
13629            lsp_name,
13630            response_channel,
13631        }
13632    }
13633    pub async fn respond(self, index: usize) -> Option<()> {
13634        if let Some(response) = self.actions.into_iter().nth(index) {
13635            self.response_channel.send(response).await.ok()
13636        } else {
13637            None
13638        }
13639    }
13640
13641    #[cfg(any(test, feature = "test-support"))]
13642    pub fn test(
13643        level: PromptLevel,
13644        message: String,
13645        actions: Vec<MessageActionItem>,
13646        lsp_name: String,
13647    ) -> Self {
13648        let (tx, _rx) = smol::channel::unbounded();
13649        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13650    }
13651}
13652impl PartialEq for LanguageServerPromptRequest {
13653    fn eq(&self, other: &Self) -> bool {
13654        self.message == other.message && self.actions == other.actions
13655    }
13656}
13657
13658#[derive(Clone, Debug, PartialEq)]
13659pub enum LanguageServerLogType {
13660    Log(MessageType),
13661    Trace { verbose_info: Option<String> },
13662    Rpc { received: bool },
13663}
13664
13665impl LanguageServerLogType {
13666    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13667        match self {
13668            Self::Log(log_type) => {
13669                use proto::log_message::LogLevel;
13670                let level = match *log_type {
13671                    MessageType::ERROR => LogLevel::Error,
13672                    MessageType::WARNING => LogLevel::Warning,
13673                    MessageType::INFO => LogLevel::Info,
13674                    MessageType::LOG => LogLevel::Log,
13675                    other => {
13676                        log::warn!("Unknown lsp log message type: {other:?}");
13677                        LogLevel::Log
13678                    }
13679                };
13680                proto::language_server_log::LogType::Log(proto::LogMessage {
13681                    level: level as i32,
13682                })
13683            }
13684            Self::Trace { verbose_info } => {
13685                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13686                    verbose_info: verbose_info.to_owned(),
13687                })
13688            }
13689            Self::Rpc { received } => {
13690                let kind = if *received {
13691                    proto::rpc_message::Kind::Received
13692                } else {
13693                    proto::rpc_message::Kind::Sent
13694                };
13695                let kind = kind as i32;
13696                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13697            }
13698        }
13699    }
13700
13701    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13702        use proto::log_message::LogLevel;
13703        use proto::rpc_message;
13704        match log_type {
13705            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13706                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13707                    LogLevel::Error => MessageType::ERROR,
13708                    LogLevel::Warning => MessageType::WARNING,
13709                    LogLevel::Info => MessageType::INFO,
13710                    LogLevel::Log => MessageType::LOG,
13711                },
13712            ),
13713            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13714                verbose_info: trace_message.verbose_info,
13715            },
13716            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13717                received: match rpc_message::Kind::from_i32(message.kind)
13718                    .unwrap_or(rpc_message::Kind::Received)
13719                {
13720                    rpc_message::Kind::Received => true,
13721                    rpc_message::Kind::Sent => false,
13722                },
13723            },
13724        }
13725    }
13726}
13727
13728pub struct WorkspaceRefreshTask {
13729    refresh_tx: mpsc::Sender<()>,
13730    progress_tx: mpsc::Sender<()>,
13731    #[allow(dead_code)]
13732    task: Task<()>,
13733}
13734
13735pub enum LanguageServerState {
13736    Starting {
13737        startup: Task<Option<Arc<LanguageServer>>>,
13738        /// List of language servers that will be added to the workspace once it's initialization completes.
13739        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13740    },
13741
13742    Running {
13743        adapter: Arc<CachedLspAdapter>,
13744        server: Arc<LanguageServer>,
13745        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13746        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13747    },
13748}
13749
13750impl LanguageServerState {
13751    fn add_workspace_folder(&self, uri: Uri) {
13752        match self {
13753            LanguageServerState::Starting {
13754                pending_workspace_folders,
13755                ..
13756            } => {
13757                pending_workspace_folders.lock().insert(uri);
13758            }
13759            LanguageServerState::Running { server, .. } => {
13760                server.add_workspace_folder(uri);
13761            }
13762        }
13763    }
13764    fn _remove_workspace_folder(&self, uri: Uri) {
13765        match self {
13766            LanguageServerState::Starting {
13767                pending_workspace_folders,
13768                ..
13769            } => {
13770                pending_workspace_folders.lock().remove(&uri);
13771            }
13772            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13773        }
13774    }
13775}
13776
13777impl std::fmt::Debug for LanguageServerState {
13778    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13779        match self {
13780            LanguageServerState::Starting { .. } => {
13781                f.debug_struct("LanguageServerState::Starting").finish()
13782            }
13783            LanguageServerState::Running { .. } => {
13784                f.debug_struct("LanguageServerState::Running").finish()
13785            }
13786        }
13787    }
13788}
13789
13790#[derive(Clone, Debug, Serialize)]
13791pub struct LanguageServerProgress {
13792    pub is_disk_based_diagnostics_progress: bool,
13793    pub is_cancellable: bool,
13794    pub title: Option<String>,
13795    pub message: Option<String>,
13796    pub percentage: Option<usize>,
13797    #[serde(skip_serializing)]
13798    pub last_update_at: Instant,
13799}
13800
13801#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13802pub struct DiagnosticSummary {
13803    pub error_count: usize,
13804    pub warning_count: usize,
13805}
13806
13807impl DiagnosticSummary {
13808    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13809        let mut this = Self {
13810            error_count: 0,
13811            warning_count: 0,
13812        };
13813
13814        for entry in diagnostics {
13815            if entry.diagnostic.is_primary {
13816                match entry.diagnostic.severity {
13817                    DiagnosticSeverity::ERROR => this.error_count += 1,
13818                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13819                    _ => {}
13820                }
13821            }
13822        }
13823
13824        this
13825    }
13826
13827    pub fn is_empty(&self) -> bool {
13828        self.error_count == 0 && self.warning_count == 0
13829    }
13830
13831    pub fn to_proto(
13832        self,
13833        language_server_id: LanguageServerId,
13834        path: &RelPath,
13835    ) -> proto::DiagnosticSummary {
13836        proto::DiagnosticSummary {
13837            path: path.to_proto(),
13838            language_server_id: language_server_id.0 as u64,
13839            error_count: self.error_count as u32,
13840            warning_count: self.warning_count as u32,
13841        }
13842    }
13843}
13844
13845#[derive(Clone, Debug)]
13846pub enum CompletionDocumentation {
13847    /// There is no documentation for this completion.
13848    Undocumented,
13849    /// A single line of documentation.
13850    SingleLine(SharedString),
13851    /// Multiple lines of plain text documentation.
13852    MultiLinePlainText(SharedString),
13853    /// Markdown documentation.
13854    MultiLineMarkdown(SharedString),
13855    /// Both single line and multiple lines of plain text documentation.
13856    SingleLineAndMultiLinePlainText {
13857        single_line: SharedString,
13858        plain_text: Option<SharedString>,
13859    },
13860}
13861
13862impl CompletionDocumentation {
13863    #[cfg(any(test, feature = "test-support"))]
13864    pub fn text(&self) -> SharedString {
13865        match self {
13866            CompletionDocumentation::Undocumented => "".into(),
13867            CompletionDocumentation::SingleLine(s) => s.clone(),
13868            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13869            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13870            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13871                single_line.clone()
13872            }
13873        }
13874    }
13875}
13876
13877impl From<lsp::Documentation> for CompletionDocumentation {
13878    fn from(docs: lsp::Documentation) -> Self {
13879        match docs {
13880            lsp::Documentation::String(text) => {
13881                if text.lines().count() <= 1 {
13882                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
13883                } else {
13884                    CompletionDocumentation::MultiLinePlainText(text.into())
13885                }
13886            }
13887
13888            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13889                lsp::MarkupKind::PlainText => {
13890                    if value.lines().count() <= 1 {
13891                        CompletionDocumentation::SingleLine(value.into())
13892                    } else {
13893                        CompletionDocumentation::MultiLinePlainText(value.into())
13894                    }
13895                }
13896
13897                lsp::MarkupKind::Markdown => {
13898                    CompletionDocumentation::MultiLineMarkdown(value.into())
13899                }
13900            },
13901        }
13902    }
13903}
13904
13905pub enum ResolvedHint {
13906    Resolved(InlayHint),
13907    Resolving(Shared<Task<()>>),
13908}
13909
13910pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
13911    glob.components()
13912        .take_while(|component| match component {
13913            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13914            _ => true,
13915        })
13916        .collect()
13917}
13918
13919pub struct SshLspAdapter {
13920    name: LanguageServerName,
13921    binary: LanguageServerBinary,
13922    initialization_options: Option<String>,
13923    code_action_kinds: Option<Vec<CodeActionKind>>,
13924}
13925
13926impl SshLspAdapter {
13927    pub fn new(
13928        name: LanguageServerName,
13929        binary: LanguageServerBinary,
13930        initialization_options: Option<String>,
13931        code_action_kinds: Option<String>,
13932    ) -> Self {
13933        Self {
13934            name,
13935            binary,
13936            initialization_options,
13937            code_action_kinds: code_action_kinds
13938                .as_ref()
13939                .and_then(|c| serde_json::from_str(c).ok()),
13940        }
13941    }
13942}
13943
13944impl LspInstaller for SshLspAdapter {
13945    type BinaryVersion = ();
13946    async fn check_if_user_installed(
13947        &self,
13948        _: &dyn LspAdapterDelegate,
13949        _: Option<Toolchain>,
13950        _: &AsyncApp,
13951    ) -> Option<LanguageServerBinary> {
13952        Some(self.binary.clone())
13953    }
13954
13955    async fn cached_server_binary(
13956        &self,
13957        _: PathBuf,
13958        _: &dyn LspAdapterDelegate,
13959    ) -> Option<LanguageServerBinary> {
13960        None
13961    }
13962
13963    async fn fetch_latest_server_version(
13964        &self,
13965        _: &dyn LspAdapterDelegate,
13966        _: bool,
13967        _: &mut AsyncApp,
13968    ) -> Result<()> {
13969        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13970    }
13971
13972    async fn fetch_server_binary(
13973        &self,
13974        _: (),
13975        _: PathBuf,
13976        _: &dyn LspAdapterDelegate,
13977    ) -> Result<LanguageServerBinary> {
13978        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13979    }
13980}
13981
13982#[async_trait(?Send)]
13983impl LspAdapter for SshLspAdapter {
13984    fn name(&self) -> LanguageServerName {
13985        self.name.clone()
13986    }
13987
13988    async fn initialization_options(
13989        self: Arc<Self>,
13990        _: &Arc<dyn LspAdapterDelegate>,
13991        _: &mut AsyncApp,
13992    ) -> Result<Option<serde_json::Value>> {
13993        let Some(options) = &self.initialization_options else {
13994            return Ok(None);
13995        };
13996        let result = serde_json::from_str(options)?;
13997        Ok(result)
13998    }
13999
14000    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14001        self.code_action_kinds.clone()
14002    }
14003}
14004
14005pub fn language_server_settings<'a>(
14006    delegate: &'a dyn LspAdapterDelegate,
14007    language: &LanguageServerName,
14008    cx: &'a App,
14009) -> Option<&'a LspSettings> {
14010    language_server_settings_for(
14011        SettingsLocation {
14012            worktree_id: delegate.worktree_id(),
14013            path: RelPath::empty(),
14014        },
14015        language,
14016        cx,
14017    )
14018}
14019
14020pub fn language_server_settings_for<'a>(
14021    location: SettingsLocation<'a>,
14022    language: &LanguageServerName,
14023    cx: &'a App,
14024) -> Option<&'a LspSettings> {
14025    ProjectSettings::get(Some(location), cx).lsp.get(language)
14026}
14027
14028pub struct LocalLspAdapterDelegate {
14029    lsp_store: WeakEntity<LspStore>,
14030    worktree: worktree::Snapshot,
14031    fs: Arc<dyn Fs>,
14032    http_client: Arc<dyn HttpClient>,
14033    language_registry: Arc<LanguageRegistry>,
14034    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14035}
14036
14037impl LocalLspAdapterDelegate {
14038    pub fn new(
14039        language_registry: Arc<LanguageRegistry>,
14040        environment: &Entity<ProjectEnvironment>,
14041        lsp_store: WeakEntity<LspStore>,
14042        worktree: &Entity<Worktree>,
14043        http_client: Arc<dyn HttpClient>,
14044        fs: Arc<dyn Fs>,
14045        cx: &mut App,
14046    ) -> Arc<Self> {
14047        let load_shell_env_task =
14048            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14049
14050        Arc::new(Self {
14051            lsp_store,
14052            worktree: worktree.read(cx).snapshot(),
14053            fs,
14054            http_client,
14055            language_registry,
14056            load_shell_env_task,
14057        })
14058    }
14059
14060    pub fn from_local_lsp(
14061        local: &LocalLspStore,
14062        worktree: &Entity<Worktree>,
14063        cx: &mut App,
14064    ) -> Arc<Self> {
14065        Self::new(
14066            local.languages.clone(),
14067            &local.environment,
14068            local.weak.clone(),
14069            worktree,
14070            local.http_client.clone(),
14071            local.fs.clone(),
14072            cx,
14073        )
14074    }
14075}
14076
14077#[async_trait]
14078impl LspAdapterDelegate for LocalLspAdapterDelegate {
14079    fn show_notification(&self, message: &str, cx: &mut App) {
14080        self.lsp_store
14081            .update(cx, |_, cx| {
14082                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14083            })
14084            .ok();
14085    }
14086
14087    fn http_client(&self) -> Arc<dyn HttpClient> {
14088        self.http_client.clone()
14089    }
14090
14091    fn worktree_id(&self) -> WorktreeId {
14092        self.worktree.id()
14093    }
14094
14095    fn worktree_root_path(&self) -> &Path {
14096        self.worktree.abs_path().as_ref()
14097    }
14098
14099    fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
14100        self.worktree.resolve_relative_path(path)
14101    }
14102
14103    async fn shell_env(&self) -> HashMap<String, String> {
14104        let task = self.load_shell_env_task.clone();
14105        task.await.unwrap_or_default()
14106    }
14107
14108    async fn npm_package_installed_version(
14109        &self,
14110        package_name: &str,
14111    ) -> Result<Option<(PathBuf, Version)>> {
14112        let local_package_directory = self.worktree_root_path();
14113        let node_modules_directory = local_package_directory.join("node_modules");
14114
14115        if let Some(version) =
14116            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14117        {
14118            return Ok(Some((node_modules_directory, version)));
14119        }
14120        let Some(npm) = self.which("npm".as_ref()).await else {
14121            log::warn!(
14122                "Failed to find npm executable for {:?}",
14123                local_package_directory
14124            );
14125            return Ok(None);
14126        };
14127
14128        let env = self.shell_env().await;
14129        let output = util::command::new_command(&npm)
14130            .args(["root", "-g"])
14131            .envs(env)
14132            .current_dir(local_package_directory)
14133            .output()
14134            .await?;
14135        let global_node_modules =
14136            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14137
14138        if let Some(version) =
14139            read_package_installed_version(global_node_modules.clone(), package_name).await?
14140        {
14141            return Ok(Some((global_node_modules, version)));
14142        }
14143        return Ok(None);
14144    }
14145
14146    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14147        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14148        if self.fs.is_file(&worktree_abs_path).await {
14149            worktree_abs_path.pop();
14150        }
14151
14152        let env = self.shell_env().await;
14153
14154        let shell_path = env.get("PATH").cloned();
14155
14156        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14157    }
14158
14159    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14160        let mut working_dir = self.worktree_root_path().to_path_buf();
14161        if self.fs.is_file(&working_dir).await {
14162            working_dir.pop();
14163        }
14164        let output = util::command::new_command(&command.path)
14165            .args(command.arguments)
14166            .envs(command.env.clone().unwrap_or_default())
14167            .current_dir(working_dir)
14168            .output()
14169            .await?;
14170
14171        anyhow::ensure!(
14172            output.status.success(),
14173            "{}, stdout: {:?}, stderr: {:?}",
14174            output.status,
14175            String::from_utf8_lossy(&output.stdout),
14176            String::from_utf8_lossy(&output.stderr)
14177        );
14178        Ok(())
14179    }
14180
14181    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14182        self.language_registry
14183            .update_lsp_binary_status(server_name, status);
14184    }
14185
14186    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14187        self.language_registry
14188            .all_lsp_adapters()
14189            .into_iter()
14190            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14191            .collect()
14192    }
14193
14194    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14195        let dir = self.language_registry.language_server_download_dir(name)?;
14196
14197        if !dir.exists() {
14198            smol::fs::create_dir_all(&dir)
14199                .await
14200                .context("failed to create container directory")
14201                .log_err()?;
14202        }
14203
14204        Some(dir)
14205    }
14206
14207    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14208        let entry = self
14209            .worktree
14210            .entry_for_path(path)
14211            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14212        let abs_path = self.worktree.absolutize(&entry.path);
14213        self.fs.load(&abs_path).await
14214    }
14215}
14216
14217async fn populate_labels_for_symbols(
14218    symbols: Vec<CoreSymbol>,
14219    language_registry: &Arc<LanguageRegistry>,
14220    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14221    output: &mut Vec<Symbol>,
14222) {
14223    #[allow(clippy::mutable_key_type)]
14224    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14225
14226    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14227    for symbol in symbols {
14228        let Some(file_name) = symbol.path.file_name() else {
14229            continue;
14230        };
14231        let language = language_registry
14232            .load_language_for_file_path(Path::new(file_name))
14233            .await
14234            .ok()
14235            .or_else(|| {
14236                unknown_paths.insert(file_name.into());
14237                None
14238            });
14239        symbols_by_language
14240            .entry(language)
14241            .or_default()
14242            .push(symbol);
14243    }
14244
14245    for unknown_path in unknown_paths {
14246        log::info!("no language found for symbol in file {unknown_path:?}");
14247    }
14248
14249    let mut label_params = Vec::new();
14250    for (language, mut symbols) in symbols_by_language {
14251        label_params.clear();
14252        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14253            name: mem::take(&mut symbol.name),
14254            kind: symbol.kind,
14255            container_name: symbol.container_name.take(),
14256        }));
14257
14258        let mut labels = Vec::new();
14259        if let Some(language) = language {
14260            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14261                language_registry
14262                    .lsp_adapters(&language.name())
14263                    .first()
14264                    .cloned()
14265            });
14266            if let Some(lsp_adapter) = lsp_adapter {
14267                labels = lsp_adapter
14268                    .labels_for_symbols(&label_params, &language)
14269                    .await
14270                    .log_err()
14271                    .unwrap_or_default();
14272            }
14273        }
14274
14275        for (
14276            (
14277                symbol,
14278                language::Symbol {
14279                    name,
14280                    container_name,
14281                    ..
14282                },
14283            ),
14284            label,
14285        ) in symbols
14286            .into_iter()
14287            .zip(label_params.drain(..))
14288            .zip(labels.into_iter().chain(iter::repeat(None)))
14289        {
14290            output.push(Symbol {
14291                language_server_name: symbol.language_server_name,
14292                source_worktree_id: symbol.source_worktree_id,
14293                source_language_server_id: symbol.source_language_server_id,
14294                path: symbol.path,
14295                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14296                name,
14297                kind: symbol.kind,
14298                range: symbol.range,
14299                container_name,
14300            });
14301        }
14302    }
14303}
14304
14305pub(crate) fn collapse_newlines(text: &str, separator: &str) -> String {
14306    text.lines()
14307        .map(|line| line.trim())
14308        .filter(|line| !line.is_empty())
14309        .join(separator)
14310}
14311
14312fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14313    match server.capabilities().text_document_sync.as_ref()? {
14314        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14315            // Server wants didSave but didn't specify includeText.
14316            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14317            // Server doesn't want didSave at all.
14318            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14319            // Server provided SaveOptions.
14320            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14321                Some(save_options.include_text.unwrap_or(false))
14322            }
14323        },
14324        // We do not have any save info. Kind affects didChange only.
14325        lsp::TextDocumentSyncCapability::Kind(_) => None,
14326    }
14327}
14328
14329/// Completion items are displayed in a `UniformList`.
14330/// Usually, those items are single-line strings, but in LSP responses,
14331/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14332/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14333/// 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,
14334/// breaking the completions menu presentation.
14335///
14336/// 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.
14337pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14338    let mut new_text = String::with_capacity(label.text.len());
14339    let mut offset_map = vec![0; label.text.len() + 1];
14340    let mut last_char_was_space = false;
14341    let mut new_idx = 0;
14342    let chars = label.text.char_indices().fuse();
14343    let mut newlines_removed = false;
14344
14345    for (idx, c) in chars {
14346        offset_map[idx] = new_idx;
14347
14348        match c {
14349            '\n' if last_char_was_space => {
14350                newlines_removed = true;
14351            }
14352            '\t' | ' ' if last_char_was_space => {}
14353            '\n' if !last_char_was_space => {
14354                new_text.push(' ');
14355                new_idx += 1;
14356                last_char_was_space = true;
14357                newlines_removed = true;
14358            }
14359            ' ' | '\t' => {
14360                new_text.push(' ');
14361                new_idx += 1;
14362                last_char_was_space = true;
14363            }
14364            _ => {
14365                new_text.push(c);
14366                new_idx += c.len_utf8();
14367                last_char_was_space = false;
14368            }
14369        }
14370    }
14371    offset_map[label.text.len()] = new_idx;
14372
14373    // Only modify the label if newlines were removed.
14374    if !newlines_removed {
14375        return;
14376    }
14377
14378    let last_index = new_idx;
14379    let mut run_ranges_errors = Vec::new();
14380    label.runs.retain_mut(|(range, _)| {
14381        match offset_map.get(range.start) {
14382            Some(&start) => range.start = start,
14383            None => {
14384                run_ranges_errors.push(range.clone());
14385                return false;
14386            }
14387        }
14388
14389        match offset_map.get(range.end) {
14390            Some(&end) => range.end = end,
14391            None => {
14392                run_ranges_errors.push(range.clone());
14393                range.end = last_index;
14394            }
14395        }
14396        true
14397    });
14398    if !run_ranges_errors.is_empty() {
14399        log::error!(
14400            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14401            label.text
14402        );
14403    }
14404
14405    let mut wrong_filter_range = None;
14406    if label.filter_range == (0..label.text.len()) {
14407        label.filter_range = 0..new_text.len();
14408    } else {
14409        let mut original_filter_range = Some(label.filter_range.clone());
14410        match offset_map.get(label.filter_range.start) {
14411            Some(&start) => label.filter_range.start = start,
14412            None => {
14413                wrong_filter_range = original_filter_range.take();
14414                label.filter_range.start = last_index;
14415            }
14416        }
14417
14418        match offset_map.get(label.filter_range.end) {
14419            Some(&end) => label.filter_range.end = end,
14420            None => {
14421                wrong_filter_range = original_filter_range.take();
14422                label.filter_range.end = last_index;
14423            }
14424        }
14425    }
14426    if let Some(wrong_filter_range) = wrong_filter_range {
14427        log::error!(
14428            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14429            label.text
14430        );
14431    }
14432
14433    label.text = new_text;
14434}