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