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::{Candidate, Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   66use gpui::{
   67    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString,
   68    Subscription, Task, WeakEntity,
   69};
   70use http_client::HttpClient;
   71use itertools::Itertools as _;
   72use language::{
   73    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, Capability, CodeLabel,
   74    Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language,
   75    LanguageName, LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller,
   76    ManifestDelegate, ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16,
   77    Toolchain, Transaction, Unclipped,
   78    language_settings::{
   79        AllLanguageSettings, FormatOnSave, Formatter, LanguageSettings, all_language_settings,
   80        language_settings,
   81    },
   82    point_to_lsp,
   83    proto::{
   84        deserialize_anchor, deserialize_anchor_range, deserialize_version, serialize_anchor,
   85        serialize_anchor_range, serialize_version,
   86    },
   87    range_from_lsp, range_to_lsp,
   88    row_chunk::RowChunk,
   89};
   90use lsp::{
   91    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   92    DEFAULT_LSP_REQUEST_TIMEOUT, DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   93    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   94    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LanguageServer,
   95    LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId, LanguageServerName,
   96    LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType, OneOf,
   97    RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles,
   98    WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   99};
  100use node_runtime::read_package_installed_version;
  101use parking_lot::Mutex;
  102use postage::{mpsc, sink::Sink, stream::Stream, watch};
  103use rand::prelude::*;
  104use rpc::{
  105    AnyProtoClient, ErrorCode, ErrorExt as _,
  106    proto::{LspRequestId, LspRequestMessage as _},
  107};
  108use semver::Version;
  109use serde::Serialize;
  110use serde_json::Value;
  111use settings::{Settings, SettingsLocation, SettingsStore};
  112use sha2::{Digest, Sha256};
  113use snippet::Snippet;
  114use std::{
  115    any::TypeId,
  116    borrow::Cow,
  117    cell::RefCell,
  118    cmp::{Ordering, Reverse},
  119    collections::{VecDeque, hash_map},
  120    convert::TryInto,
  121    ffi::OsStr,
  122    future::ready,
  123    iter, mem,
  124    ops::{ControlFlow, Range},
  125    path::{self, Path, PathBuf},
  126    pin::pin,
  127    rc::Rc,
  128    sync::{
  129        Arc,
  130        atomic::{self, AtomicUsize},
  131    },
  132    time::{Duration, Instant},
  133    vec,
  134};
  135use sum_tree::Dimensions;
  136use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  137
  138use util::{
  139    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  140    paths::{PathStyle, SanitizedPath, UrlExt},
  141    post_inc,
  142    redact::redact_command,
  143    rel_path::RelPath,
  144};
  145
  146pub use document_colors::DocumentColors;
  147pub use folding_ranges::LspFoldingRange;
  148pub use fs::*;
  149pub use language::Location;
  150pub use lsp_store::inlay_hints::{CacheInlayHints, InvalidationStrategy};
  151#[cfg(any(test, feature = "test-support"))]
  152pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  153pub use semantic_tokens::{
  154    BufferSemanticToken, BufferSemanticTokens, RefreshForServer, SemanticTokenStylizer, TokenType,
  155};
  156
  157pub use worktree::{
  158    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  159    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  160};
  161
  162const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  163pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  164const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  165const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  166static NEXT_PROMPT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
  167
  168#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  169pub enum ProgressToken {
  170    Number(i32),
  171    String(SharedString),
  172}
  173
  174impl std::fmt::Display for ProgressToken {
  175    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  176        match self {
  177            Self::Number(number) => write!(f, "{number}"),
  178            Self::String(string) => write!(f, "{string}"),
  179        }
  180    }
  181}
  182
  183impl ProgressToken {
  184    fn from_lsp(value: lsp::NumberOrString) -> Self {
  185        match value {
  186            lsp::NumberOrString::Number(number) => Self::Number(number),
  187            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  188        }
  189    }
  190
  191    fn to_lsp(&self) -> lsp::NumberOrString {
  192        match self {
  193            Self::Number(number) => lsp::NumberOrString::Number(*number),
  194            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  195        }
  196    }
  197
  198    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  199        Some(match value.value? {
  200            proto::progress_token::Value::Number(number) => Self::Number(number),
  201            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  202        })
  203    }
  204
  205    fn to_proto(&self) -> proto::ProgressToken {
  206        proto::ProgressToken {
  207            value: Some(match self {
  208                Self::Number(number) => proto::progress_token::Value::Number(*number),
  209                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  210            }),
  211        }
  212    }
  213}
  214
  215#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  216pub enum FormatTrigger {
  217    Save,
  218    Manual,
  219}
  220
  221pub enum LspFormatTarget {
  222    Buffers,
  223    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  224}
  225
  226#[derive(Debug, Clone, PartialEq, Eq, Hash)]
  227pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  228
  229struct OpenLspBuffer(Entity<Buffer>);
  230
  231impl FormatTrigger {
  232    fn from_proto(value: i32) -> FormatTrigger {
  233        match value {
  234            0 => FormatTrigger::Save,
  235            1 => FormatTrigger::Manual,
  236            _ => FormatTrigger::Save,
  237        }
  238    }
  239}
  240
  241#[derive(Clone)]
  242struct UnifiedLanguageServer {
  243    id: LanguageServerId,
  244    project_roots: HashSet<Arc<RelPath>>,
  245}
  246
  247/// Settings that affect language server identity.
  248///
  249/// Dynamic settings (`LspSettings::settings`) are excluded because they can be
  250/// updated via `workspace/didChangeConfiguration` without restarting the server.
  251#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  252struct LanguageServerSeedSettings {
  253    binary: Option<BinarySettings>,
  254    initialization_options: Option<serde_json::Value>,
  255}
  256
  257#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  258struct LanguageServerSeed {
  259    worktree_id: WorktreeId,
  260    name: LanguageServerName,
  261    toolchain: Option<Toolchain>,
  262    settings: LanguageServerSeedSettings,
  263}
  264
  265#[derive(Debug)]
  266pub struct DocumentDiagnosticsUpdate<'a, D> {
  267    pub diagnostics: D,
  268    pub result_id: Option<SharedString>,
  269    pub registration_id: Option<SharedString>,
  270    pub server_id: LanguageServerId,
  271    pub disk_based_sources: Cow<'a, [String]>,
  272}
  273
  274pub struct DocumentDiagnostics {
  275    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  276    document_abs_path: PathBuf,
  277    version: Option<i32>,
  278}
  279
  280#[derive(Default, Debug)]
  281struct DynamicRegistrations {
  282    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  283    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  284}
  285
  286pub struct LocalLspStore {
  287    weak: WeakEntity<LspStore>,
  288    pub worktree_store: Entity<WorktreeStore>,
  289    toolchain_store: Entity<LocalToolchainStore>,
  290    http_client: Arc<dyn HttpClient>,
  291    environment: Entity<ProjectEnvironment>,
  292    fs: Arc<dyn Fs>,
  293    languages: Arc<LanguageRegistry>,
  294    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  295    yarn: Entity<YarnPathStore>,
  296    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  297    buffers_being_formatted: HashSet<BufferId>,
  298    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  299    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  300    watched_manifest_filenames: HashSet<ManifestName>,
  301    language_server_paths_watched_for_rename:
  302        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  303    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  304    supplementary_language_servers:
  305        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  306    prettier_store: Entity<PrettierStore>,
  307    next_diagnostic_group_id: usize,
  308    diagnostics: HashMap<
  309        WorktreeId,
  310        HashMap<
  311            Arc<RelPath>,
  312            Vec<(
  313                LanguageServerId,
  314                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  315            )>,
  316        >,
  317    >,
  318    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  319    _subscription: gpui::Subscription,
  320    lsp_tree: LanguageServerTree,
  321    registered_buffers: HashMap<BufferId, usize>,
  322    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  323    buffer_pull_diagnostics_result_ids: HashMap<
  324        LanguageServerId,
  325        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  326    >,
  327    workspace_pull_diagnostics_result_ids: HashMap<
  328        LanguageServerId,
  329        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  330    >,
  331    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  332
  333    buffers_to_refresh_hash_set: HashSet<BufferId>,
  334    buffers_to_refresh_queue: VecDeque<BufferId>,
  335    _background_diagnostics_worker: Shared<Task<()>>,
  336}
  337
  338impl LocalLspStore {
  339    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  340    pub fn running_language_server_for_id(
  341        &self,
  342        id: LanguageServerId,
  343    ) -> Option<&Arc<LanguageServer>> {
  344        let language_server_state = self.language_servers.get(&id)?;
  345
  346        match language_server_state {
  347            LanguageServerState::Running { server, .. } => Some(server),
  348            LanguageServerState::Starting { .. } => None,
  349        }
  350    }
  351
  352    fn get_or_insert_language_server(
  353        &mut self,
  354        worktree_handle: &Entity<Worktree>,
  355        delegate: Arc<LocalLspAdapterDelegate>,
  356        disposition: &Arc<LaunchDisposition>,
  357        language_name: &LanguageName,
  358        cx: &mut App,
  359    ) -> LanguageServerId {
  360        let key = LanguageServerSeed {
  361            worktree_id: worktree_handle.read(cx).id(),
  362            name: disposition.server_name.clone(),
  363            settings: LanguageServerSeedSettings {
  364                binary: disposition.settings.binary.clone(),
  365                initialization_options: disposition.settings.initialization_options.clone(),
  366            },
  367            toolchain: disposition.toolchain.clone(),
  368        };
  369        if let Some(state) = self.language_server_ids.get_mut(&key) {
  370            state.project_roots.insert(disposition.path.path.clone());
  371            state.id
  372        } else {
  373            let adapter = self
  374                .languages
  375                .lsp_adapters(language_name)
  376                .into_iter()
  377                .find(|adapter| adapter.name() == disposition.server_name)
  378                .expect("To find LSP adapter");
  379            let new_language_server_id = self.start_language_server(
  380                worktree_handle,
  381                delegate,
  382                adapter,
  383                disposition.settings.clone(),
  384                key.clone(),
  385                language_name.clone(),
  386                cx,
  387            );
  388            if let Some(state) = self.language_server_ids.get_mut(&key) {
  389                state.project_roots.insert(disposition.path.path.clone());
  390            } else {
  391                debug_assert!(
  392                    false,
  393                    "Expected `start_language_server` to ensure that `key` exists in a map"
  394                );
  395            }
  396            new_language_server_id
  397        }
  398    }
  399
  400    fn start_language_server(
  401        &mut self,
  402        worktree_handle: &Entity<Worktree>,
  403        delegate: Arc<LocalLspAdapterDelegate>,
  404        adapter: Arc<CachedLspAdapter>,
  405        settings: Arc<LspSettings>,
  406        key: LanguageServerSeed,
  407        language_name: LanguageName,
  408        cx: &mut App,
  409    ) -> LanguageServerId {
  410        let worktree = worktree_handle.read(cx);
  411
  412        let worktree_id = worktree.id();
  413        let worktree_abs_path = worktree.abs_path();
  414        let toolchain = key.toolchain.clone();
  415        let override_options = settings.initialization_options.clone();
  416
  417        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  418
  419        let server_id = self.languages.next_language_server_id();
  420        log::trace!(
  421            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  422            adapter.name.0
  423        );
  424
  425        let wait_until_worktree_trust =
  426            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  427                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  428                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  429                });
  430                if can_trust {
  431                    self.restricted_worktrees_tasks.remove(&worktree_id);
  432                    None
  433                } else {
  434                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  435                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  436                        hash_map::Entry::Vacant(v) => {
  437                            let (mut tx, rx) = watch::channel::<bool>();
  438                            let lsp_store = self.weak.clone();
  439                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  440                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  441                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  442                                        tx.blocking_send(true).ok();
  443                                        lsp_store
  444                                            .update(cx, |lsp_store, _| {
  445                                                if let Some(local_lsp_store) =
  446                                                    lsp_store.as_local_mut()
  447                                                {
  448                                                    local_lsp_store
  449                                                        .restricted_worktrees_tasks
  450                                                        .remove(&worktree_id);
  451                                                }
  452                                            })
  453                                            .ok();
  454                                    }
  455                                }
  456                            });
  457                            v.insert((subscription, rx.clone()));
  458                            Some(rx)
  459                        }
  460                    }
  461                }
  462            });
  463        let update_binary_status = wait_until_worktree_trust.is_none();
  464
  465        let binary = self.get_language_server_binary(
  466            worktree_abs_path.clone(),
  467            adapter.clone(),
  468            settings,
  469            toolchain.clone(),
  470            delegate.clone(),
  471            true,
  472            wait_until_worktree_trust,
  473            cx,
  474        );
  475        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  476
  477        let pending_server = cx.spawn({
  478            let adapter = adapter.clone();
  479            let server_name = adapter.name.clone();
  480            let stderr_capture = stderr_capture.clone();
  481            #[cfg(any(test, feature = "test-support"))]
  482            let lsp_store = self.weak.clone();
  483            let pending_workspace_folders = pending_workspace_folders.clone();
  484            async move |cx| {
  485                let binary = binary.await?;
  486                #[cfg(any(test, feature = "test-support"))]
  487                if let Some(server) = lsp_store
  488                    .update(&mut cx.clone(), |this, cx| {
  489                        this.languages.create_fake_language_server(
  490                            server_id,
  491                            &server_name,
  492                            binary.clone(),
  493                            &mut cx.to_async(),
  494                        )
  495                    })
  496                    .ok()
  497                    .flatten()
  498                {
  499                    return Ok(server);
  500                }
  501
  502                let code_action_kinds = adapter.code_action_kinds();
  503                lsp::LanguageServer::new(
  504                    stderr_capture,
  505                    server_id,
  506                    server_name,
  507                    binary,
  508                    &worktree_abs_path,
  509                    code_action_kinds,
  510                    Some(pending_workspace_folders),
  511                    cx,
  512                )
  513            }
  514        });
  515
  516        let startup = {
  517            let server_name = adapter.name.0.clone();
  518            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  519            let key = key.clone();
  520            let adapter = adapter.clone();
  521            let lsp_store = self.weak.clone();
  522            let pending_workspace_folders = pending_workspace_folders.clone();
  523            let pull_diagnostics = ProjectSettings::get_global(cx)
  524                .diagnostics
  525                .lsp_pull_diagnostics
  526                .enabled;
  527            let settings_location = SettingsLocation {
  528                worktree_id,
  529                path: RelPath::empty(),
  530            };
  531            let augments_syntax_tokens = AllLanguageSettings::get(Some(settings_location), cx)
  532                .language(Some(settings_location), Some(&language_name), cx)
  533                .semantic_tokens
  534                .use_tree_sitter();
  535            cx.spawn(async move |cx| {
  536                let result = async {
  537                    let language_server = pending_server.await?;
  538
  539                    let workspace_config = Self::workspace_configuration_for_adapter(
  540                        adapter.adapter.clone(),
  541                        &delegate,
  542                        toolchain,
  543                        None,
  544                        cx,
  545                    )
  546                    .await?;
  547
  548                    let mut initialization_options = Self::initialization_options_for_adapter(
  549                        adapter.adapter.clone(),
  550                        &delegate,
  551                    )
  552                    .await?;
  553
  554                    match (&mut initialization_options, override_options) {
  555                        (Some(initialization_options), Some(override_options)) => {
  556                            merge_json_value_into(override_options, initialization_options);
  557                        }
  558                        (None, override_options) => initialization_options = override_options,
  559                        _ => {}
  560                    }
  561
  562                    let initialization_params = cx.update(|cx| {
  563                        let mut params = language_server.default_initialize_params(
  564                            pull_diagnostics,
  565                            augments_syntax_tokens,
  566                            cx,
  567                        );
  568                        params.initialization_options = initialization_options;
  569                        adapter.adapter.prepare_initialize_params(params, cx)
  570                    })?;
  571
  572                    Self::setup_lsp_messages(
  573                        lsp_store.clone(),
  574                        &language_server,
  575                        delegate.clone(),
  576                        adapter.clone(),
  577                    );
  578
  579                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  580                        settings: workspace_config,
  581                    };
  582                    let language_server = cx
  583                        .update(|cx| {
  584                            let request_timeout = ProjectSettings::get_global(cx)
  585                                .global_lsp_settings
  586                                .get_request_timeout();
  587
  588                            language_server.initialize(
  589                                initialization_params,
  590                                Arc::new(did_change_configuration_params.clone()),
  591                                request_timeout,
  592                                cx,
  593                            )
  594                        })
  595                        .await
  596                        .inspect_err(|_| {
  597                            if let Some(lsp_store) = lsp_store.upgrade() {
  598                                lsp_store.update(cx, |lsp_store, cx| {
  599                                    lsp_store.cleanup_lsp_data(server_id);
  600                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  601                                });
  602                            }
  603                        })?;
  604
  605                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  606                        did_change_configuration_params,
  607                    )?;
  608
  609                    anyhow::Ok(language_server)
  610                }
  611                .await;
  612
  613                match result {
  614                    Ok(server) => {
  615                        lsp_store
  616                            .update(cx, |lsp_store, cx| {
  617                                lsp_store.insert_newly_running_language_server(
  618                                    adapter,
  619                                    server.clone(),
  620                                    server_id,
  621                                    key,
  622                                    pending_workspace_folders,
  623                                    cx,
  624                                );
  625                            })
  626                            .ok();
  627                        stderr_capture.lock().take();
  628                        Some(server)
  629                    }
  630
  631                    Err(err) => {
  632                        let log = stderr_capture.lock().take().unwrap_or_default();
  633                        delegate.update_status(
  634                            adapter.name(),
  635                            BinaryStatus::Failed {
  636                                error: if log.is_empty() {
  637                                    format!("{err:#}")
  638                                } else {
  639                                    format!("{err:#}\n-- stderr --\n{log}")
  640                                },
  641                            },
  642                        );
  643                        log::error!(
  644                            "Failed to start language server {server_name:?}: {}",
  645                            redact_command(&format!("{err:?}"))
  646                        );
  647                        if !log.is_empty() {
  648                            log::error!("server stderr: {}", redact_command(&log));
  649                        }
  650                        None
  651                    }
  652                }
  653            })
  654        };
  655        let state = LanguageServerState::Starting {
  656            startup,
  657            pending_workspace_folders,
  658        };
  659
  660        if update_binary_status {
  661            self.languages
  662                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  663        }
  664
  665        self.language_servers.insert(server_id, state);
  666        self.language_server_ids
  667            .entry(key)
  668            .or_insert(UnifiedLanguageServer {
  669                id: server_id,
  670                project_roots: Default::default(),
  671            });
  672        server_id
  673    }
  674
  675    fn get_language_server_binary(
  676        &self,
  677        worktree_abs_path: Arc<Path>,
  678        adapter: Arc<CachedLspAdapter>,
  679        settings: Arc<LspSettings>,
  680        toolchain: Option<Toolchain>,
  681        delegate: Arc<dyn LspAdapterDelegate>,
  682        allow_binary_download: bool,
  683        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  684        cx: &mut App,
  685    ) -> Task<Result<LanguageServerBinary>> {
  686        if let Some(settings) = &settings.binary
  687            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  688        {
  689            let settings = settings.clone();
  690            let languages = self.languages.clone();
  691            return cx.background_spawn(async move {
  692                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  693                    let already_trusted =  *wait_until_worktree_trust.borrow();
  694                    if !already_trusted {
  695                        log::info!(
  696                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  697                            adapter.name(),
  698                        );
  699                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  700                            if worktree_trusted {
  701                                break;
  702                            }
  703                        }
  704                        log::info!(
  705                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  706                            adapter.name(),
  707                        );
  708                    }
  709                    languages
  710                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  711                }
  712                let mut env = delegate.shell_env().await;
  713                env.extend(settings.env.unwrap_or_default());
  714
  715                Ok(LanguageServerBinary {
  716                    path: delegate.resolve_relative_path(path),
  717                    env: Some(env),
  718                    arguments: settings
  719                        .arguments
  720                        .unwrap_or_default()
  721                        .iter()
  722                        .map(Into::into)
  723                        .collect(),
  724                })
  725            });
  726        }
  727        let lsp_binary_options = LanguageServerBinaryOptions {
  728            allow_path_lookup: !settings
  729                .binary
  730                .as_ref()
  731                .and_then(|b| b.ignore_system_version)
  732                .unwrap_or_default(),
  733            allow_binary_download,
  734            pre_release: settings
  735                .fetch
  736                .as_ref()
  737                .and_then(|f| f.pre_release)
  738                .unwrap_or(false),
  739        };
  740
  741        cx.spawn(async move |cx| {
  742            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  743                let already_trusted =  *wait_until_worktree_trust.borrow();
  744                if !already_trusted {
  745                    log::info!(
  746                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  747                        adapter.name(),
  748                    );
  749                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  750                        if worktree_trusted {
  751                            break;
  752                        }
  753                    }
  754                    log::info!(
  755                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  756                            adapter.name(),
  757                    );
  758                }
  759            }
  760
  761            let (existing_binary, maybe_download_binary) = adapter
  762                .clone()
  763                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  764                .await
  765                .await;
  766
  767            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  768
  769            let mut binary = match (existing_binary, maybe_download_binary) {
  770                (binary, None) => binary?,
  771                (Err(_), Some(downloader)) => downloader.await?,
  772                (Ok(existing_binary), Some(downloader)) => {
  773                    let mut download_timeout = cx
  774                        .background_executor()
  775                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  776                        .fuse();
  777                    let mut downloader = downloader.fuse();
  778                    futures::select! {
  779                        _ = download_timeout => {
  780                            // Return existing binary and kick the existing work to the background.
  781                            cx.spawn(async move |_| downloader.await).detach();
  782                            Ok(existing_binary)
  783                        },
  784                        downloaded_or_existing_binary = downloader => {
  785                            // If download fails, this results in the existing binary.
  786                            downloaded_or_existing_binary
  787                        }
  788                    }?
  789                }
  790            };
  791            let mut shell_env = delegate.shell_env().await;
  792
  793            shell_env.extend(binary.env.unwrap_or_default());
  794
  795            if let Some(settings) = settings.binary.as_ref() {
  796                if let Some(arguments) = &settings.arguments {
  797                    binary.arguments = arguments.iter().map(Into::into).collect();
  798                }
  799                if let Some(env) = &settings.env {
  800                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  801                }
  802            }
  803
  804            binary.env = Some(shell_env);
  805            Ok(binary)
  806        })
  807    }
  808
  809    fn setup_lsp_messages(
  810        lsp_store: WeakEntity<LspStore>,
  811        language_server: &LanguageServer,
  812        delegate: Arc<dyn LspAdapterDelegate>,
  813        adapter: Arc<CachedLspAdapter>,
  814    ) {
  815        let name = language_server.name();
  816        let server_id = language_server.server_id();
  817        language_server
  818            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  819                let adapter = adapter.clone();
  820                let this = lsp_store.clone();
  821                move |mut params, cx| {
  822                    let adapter = adapter.clone();
  823                    if let Some(this) = this.upgrade() {
  824                        this.update(cx, |this, cx| {
  825                            {
  826                                let buffer = params
  827                                    .uri
  828                                    .to_file_path()
  829                                    .map(|file_path| this.get_buffer(&file_path, cx))
  830                                    .ok()
  831                                    .flatten();
  832                                adapter.process_diagnostics(&mut params, server_id, buffer);
  833                            }
  834
  835                            this.merge_lsp_diagnostics(
  836                                DiagnosticSourceKind::Pushed,
  837                                vec![DocumentDiagnosticsUpdate {
  838                                    server_id,
  839                                    diagnostics: params,
  840                                    result_id: None,
  841                                    disk_based_sources: Cow::Borrowed(
  842                                        &adapter.disk_based_diagnostic_sources,
  843                                    ),
  844                                    registration_id: None,
  845                                }],
  846                                |_, diagnostic, cx| match diagnostic.source_kind {
  847                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  848                                        adapter.retain_old_diagnostic(diagnostic, cx)
  849                                    }
  850                                    DiagnosticSourceKind::Pulled => true,
  851                                },
  852                                cx,
  853                            )
  854                            .log_err();
  855                        });
  856                    }
  857                }
  858            })
  859            .detach();
  860        language_server
  861            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  862                let adapter = adapter.adapter.clone();
  863                let delegate = delegate.clone();
  864                let this = lsp_store.clone();
  865                move |params, cx| {
  866                    let adapter = adapter.clone();
  867                    let delegate = delegate.clone();
  868                    let this = this.clone();
  869                    let mut cx = cx.clone();
  870                    async move {
  871                        let toolchain_for_id = this
  872                            .update(&mut cx, |this, _| {
  873                                this.as_local()?.language_server_ids.iter().find_map(
  874                                    |(seed, value)| {
  875                                        (value.id == server_id).then(|| seed.toolchain.clone())
  876                                    },
  877                                )
  878                            })?
  879                            .context("Expected the LSP store to be in a local mode")?;
  880
  881                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  882                        for item in &params.items {
  883                            let scope_uri = item.scope_uri.clone();
  884                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  885                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  886                            else {
  887                                // We've already queried workspace configuration of this URI.
  888                                continue;
  889                            };
  890                            let workspace_config = Self::workspace_configuration_for_adapter(
  891                                adapter.clone(),
  892                                &delegate,
  893                                toolchain_for_id.clone(),
  894                                scope_uri,
  895                                &mut cx,
  896                            )
  897                            .await?;
  898                            new_scope_uri.insert(workspace_config);
  899                        }
  900
  901                        Ok(params
  902                            .items
  903                            .into_iter()
  904                            .filter_map(|item| {
  905                                let workspace_config =
  906                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  907                                if let Some(section) = &item.section {
  908                                    Some(
  909                                        workspace_config
  910                                            .get(section)
  911                                            .cloned()
  912                                            .unwrap_or(serde_json::Value::Null),
  913                                    )
  914                                } else {
  915                                    Some(workspace_config.clone())
  916                                }
  917                            })
  918                            .collect())
  919                    }
  920                }
  921            })
  922            .detach();
  923
  924        language_server
  925            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  926                let this = lsp_store.clone();
  927                move |_, cx| {
  928                    let this = this.clone();
  929                    let cx = cx.clone();
  930                    async move {
  931                        let Some(server) =
  932                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  933                        else {
  934                            return Ok(None);
  935                        };
  936                        let root = server.workspace_folders();
  937                        Ok(Some(
  938                            root.into_iter()
  939                                .map(|uri| WorkspaceFolder {
  940                                    uri,
  941                                    name: Default::default(),
  942                                })
  943                                .collect(),
  944                        ))
  945                    }
  946                }
  947            })
  948            .detach();
  949        // Even though we don't have handling for these requests, respond to them to
  950        // avoid stalling any language server like `gopls` which waits for a response
  951        // to these requests when initializing.
  952        language_server
  953            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  954                let this = lsp_store.clone();
  955                move |params, cx| {
  956                    let this = this.clone();
  957                    let mut cx = cx.clone();
  958                    async move {
  959                        this.update(&mut cx, |this, _| {
  960                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  961                            {
  962                                status
  963                                    .progress_tokens
  964                                    .insert(ProgressToken::from_lsp(params.token));
  965                            }
  966                        })?;
  967
  968                        Ok(())
  969                    }
  970                }
  971            })
  972            .detach();
  973
  974        language_server
  975            .on_request::<lsp::request::RegisterCapability, _, _>({
  976                let lsp_store = lsp_store.clone();
  977                move |params, cx| {
  978                    let lsp_store = lsp_store.clone();
  979                    let mut cx = cx.clone();
  980                    async move {
  981                        lsp_store
  982                            .update(&mut cx, |lsp_store, cx| {
  983                                if lsp_store.as_local().is_some() {
  984                                    match lsp_store
  985                                        .register_server_capabilities(server_id, params, cx)
  986                                    {
  987                                        Ok(()) => {}
  988                                        Err(e) => {
  989                                            log::error!(
  990                                                "Failed to register server capabilities: {e:#}"
  991                                            );
  992                                        }
  993                                    };
  994                                }
  995                            })
  996                            .ok();
  997                        Ok(())
  998                    }
  999                }
 1000            })
 1001            .detach();
 1002
 1003        language_server
 1004            .on_request::<lsp::request::UnregisterCapability, _, _>({
 1005                let lsp_store = lsp_store.clone();
 1006                move |params, cx| {
 1007                    let lsp_store = lsp_store.clone();
 1008                    let mut cx = cx.clone();
 1009                    async move {
 1010                        lsp_store
 1011                            .update(&mut cx, |lsp_store, cx| {
 1012                                if lsp_store.as_local().is_some() {
 1013                                    match lsp_store
 1014                                        .unregister_server_capabilities(server_id, params, cx)
 1015                                    {
 1016                                        Ok(()) => {}
 1017                                        Err(e) => {
 1018                                            log::error!(
 1019                                                "Failed to unregister server capabilities: {e:#}"
 1020                                            );
 1021                                        }
 1022                                    }
 1023                                }
 1024                            })
 1025                            .ok();
 1026                        Ok(())
 1027                    }
 1028                }
 1029            })
 1030            .detach();
 1031
 1032        language_server
 1033            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
 1034                let this = lsp_store.clone();
 1035                move |params, cx| {
 1036                    let mut cx = cx.clone();
 1037                    let this = this.clone();
 1038                    async move {
 1039                        LocalLspStore::on_lsp_workspace_edit(
 1040                            this.clone(),
 1041                            params,
 1042                            server_id,
 1043                            &mut cx,
 1044                        )
 1045                        .await
 1046                    }
 1047                }
 1048            })
 1049            .detach();
 1050
 1051        language_server
 1052            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1053                let lsp_store = lsp_store.clone();
 1054                let request_id = Arc::new(AtomicUsize::new(0));
 1055                move |(), cx| {
 1056                    let lsp_store = lsp_store.clone();
 1057                    let request_id = request_id.clone();
 1058                    let mut cx = cx.clone();
 1059                    async move {
 1060                        lsp_store
 1061                            .update(&mut cx, |lsp_store, cx| {
 1062                                let request_id =
 1063                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1064                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1065                                    server_id,
 1066                                    request_id,
 1067                                });
 1068                                lsp_store
 1069                                    .downstream_client
 1070                                    .as_ref()
 1071                                    .map(|(client, project_id)| {
 1072                                        client.send(proto::RefreshInlayHints {
 1073                                            project_id: *project_id,
 1074                                            server_id: server_id.to_proto(),
 1075                                            request_id: request_id.map(|id| id as u64),
 1076                                        })
 1077                                    })
 1078                            })?
 1079                            .transpose()?;
 1080                        Ok(())
 1081                    }
 1082                }
 1083            })
 1084            .detach();
 1085
 1086        language_server
 1087            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1088                let this = lsp_store.clone();
 1089                move |(), cx| {
 1090                    let this = this.clone();
 1091                    let mut cx = cx.clone();
 1092                    async move {
 1093                        this.update(&mut cx, |this, cx| {
 1094                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1095                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1096                                client.send(proto::RefreshCodeLens {
 1097                                    project_id: *project_id,
 1098                                })
 1099                            })
 1100                        })?
 1101                        .transpose()?;
 1102                        Ok(())
 1103                    }
 1104                }
 1105            })
 1106            .detach();
 1107
 1108        language_server
 1109            .on_request::<lsp::request::SemanticTokensRefresh, _, _>({
 1110                let lsp_store = lsp_store.clone();
 1111                let request_id = Arc::new(AtomicUsize::new(0));
 1112                move |(), cx| {
 1113                    let lsp_store = lsp_store.clone();
 1114                    let request_id = request_id.clone();
 1115                    let mut cx = cx.clone();
 1116                    async move {
 1117                        lsp_store
 1118                            .update(&mut cx, |lsp_store, cx| {
 1119                                let request_id =
 1120                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1121                                cx.emit(LspStoreEvent::RefreshSemanticTokens {
 1122                                    server_id,
 1123                                    request_id,
 1124                                });
 1125                                lsp_store
 1126                                    .downstream_client
 1127                                    .as_ref()
 1128                                    .map(|(client, project_id)| {
 1129                                        client.send(proto::RefreshSemanticTokens {
 1130                                            project_id: *project_id,
 1131                                            server_id: server_id.to_proto(),
 1132                                            request_id: request_id.map(|id| id as u64),
 1133                                        })
 1134                                    })
 1135                            })?
 1136                            .transpose()?;
 1137                        Ok(())
 1138                    }
 1139                }
 1140            })
 1141            .detach();
 1142
 1143        language_server
 1144            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1145                let this = lsp_store.clone();
 1146                move |(), cx| {
 1147                    let this = this.clone();
 1148                    let mut cx = cx.clone();
 1149                    async move {
 1150                        this.update(&mut cx, |lsp_store, cx| {
 1151                            lsp_store.pull_workspace_diagnostics(server_id);
 1152                            lsp_store
 1153                                .downstream_client
 1154                                .as_ref()
 1155                                .map(|(client, project_id)| {
 1156                                    client.send(proto::PullWorkspaceDiagnostics {
 1157                                        project_id: *project_id,
 1158                                        server_id: server_id.to_proto(),
 1159                                    })
 1160                                })
 1161                                .transpose()?;
 1162                            anyhow::Ok(
 1163                                lsp_store.pull_document_diagnostics_for_server(server_id, None, cx),
 1164                            )
 1165                        })??
 1166                        .await;
 1167                        Ok(())
 1168                    }
 1169                }
 1170            })
 1171            .detach();
 1172
 1173        language_server
 1174            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1175                let this = lsp_store.clone();
 1176                let name = name.to_string();
 1177                let adapter = adapter.clone();
 1178                move |params, cx| {
 1179                    let this = this.clone();
 1180                    let name = name.to_string();
 1181                    let adapter = adapter.clone();
 1182                    let mut cx = cx.clone();
 1183                    async move {
 1184                        let actions = params.actions.unwrap_or_default();
 1185                        let message = params.message.clone();
 1186                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1187                        let level = match params.typ {
 1188                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1189                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1190                            _ => PromptLevel::Info,
 1191                        };
 1192                        let request = LanguageServerPromptRequest::new(
 1193                            level,
 1194                            params.message,
 1195                            actions,
 1196                            name.clone(),
 1197                            tx,
 1198                        );
 1199
 1200                        let did_update = this
 1201                            .update(&mut cx, |_, cx| {
 1202                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1203                            })
 1204                            .is_ok();
 1205                        if did_update {
 1206                            let response = rx.recv().await.ok();
 1207                            if let Some(ref selected_action) = response {
 1208                                let context = language::PromptResponseContext {
 1209                                    message,
 1210                                    selected_action: selected_action.clone(),
 1211                                };
 1212                                adapter.process_prompt_response(&context, &mut cx)
 1213                            }
 1214
 1215                            Ok(response)
 1216                        } else {
 1217                            Ok(None)
 1218                        }
 1219                    }
 1220                }
 1221            })
 1222            .detach();
 1223        language_server
 1224            .on_notification::<lsp::notification::ShowMessage, _>({
 1225                let this = lsp_store.clone();
 1226                let name = name.to_string();
 1227                move |params, cx| {
 1228                    let this = this.clone();
 1229                    let name = name.to_string();
 1230                    let mut cx = cx.clone();
 1231
 1232                    let (tx, _) = smol::channel::bounded(1);
 1233                    let level = match params.typ {
 1234                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1235                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1236                        _ => PromptLevel::Info,
 1237                    };
 1238                    let request =
 1239                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1240
 1241                    let _ = this.update(&mut cx, |_, cx| {
 1242                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1243                    });
 1244                }
 1245            })
 1246            .detach();
 1247
 1248        let disk_based_diagnostics_progress_token =
 1249            adapter.disk_based_diagnostics_progress_token.clone();
 1250
 1251        language_server
 1252            .on_notification::<lsp::notification::Progress, _>({
 1253                let this = lsp_store.clone();
 1254                move |params, cx| {
 1255                    if let Some(this) = this.upgrade() {
 1256                        this.update(cx, |this, cx| {
 1257                            this.on_lsp_progress(
 1258                                params,
 1259                                server_id,
 1260                                disk_based_diagnostics_progress_token.clone(),
 1261                                cx,
 1262                            );
 1263                        });
 1264                    }
 1265                }
 1266            })
 1267            .detach();
 1268
 1269        language_server
 1270            .on_notification::<lsp::notification::LogMessage, _>({
 1271                let this = lsp_store.clone();
 1272                move |params, cx| {
 1273                    if let Some(this) = this.upgrade() {
 1274                        this.update(cx, |_, cx| {
 1275                            cx.emit(LspStoreEvent::LanguageServerLog(
 1276                                server_id,
 1277                                LanguageServerLogType::Log(params.typ),
 1278                                params.message,
 1279                            ));
 1280                        });
 1281                    }
 1282                }
 1283            })
 1284            .detach();
 1285
 1286        language_server
 1287            .on_notification::<lsp::notification::LogTrace, _>({
 1288                let this = lsp_store.clone();
 1289                move |params, cx| {
 1290                    let mut cx = cx.clone();
 1291                    if let Some(this) = this.upgrade() {
 1292                        this.update(&mut cx, |_, cx| {
 1293                            cx.emit(LspStoreEvent::LanguageServerLog(
 1294                                server_id,
 1295                                LanguageServerLogType::Trace {
 1296                                    verbose_info: params.verbose,
 1297                                },
 1298                                params.message,
 1299                            ));
 1300                        });
 1301                    }
 1302                }
 1303            })
 1304            .detach();
 1305
 1306        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1307        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1308        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1309        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1310    }
 1311
 1312    fn shutdown_language_servers_on_quit(&mut self) -> impl Future<Output = ()> + use<> {
 1313        let shutdown_futures = self
 1314            .language_servers
 1315            .drain()
 1316            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1317            .collect::<Vec<_>>();
 1318
 1319        async move {
 1320            join_all(shutdown_futures).await;
 1321        }
 1322    }
 1323
 1324    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1325        match server_state {
 1326            LanguageServerState::Running { server, .. } => {
 1327                if let Some(shutdown) = server.shutdown() {
 1328                    shutdown.await;
 1329                }
 1330            }
 1331            LanguageServerState::Starting { startup, .. } => {
 1332                if let Some(server) = startup.await
 1333                    && let Some(shutdown) = server.shutdown()
 1334                {
 1335                    shutdown.await;
 1336                }
 1337            }
 1338        }
 1339        Ok(())
 1340    }
 1341
 1342    fn language_servers_for_worktree(
 1343        &self,
 1344        worktree_id: WorktreeId,
 1345    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1346        self.language_server_ids
 1347            .iter()
 1348            .filter_map(move |(seed, state)| {
 1349                if seed.worktree_id != worktree_id {
 1350                    return None;
 1351                }
 1352
 1353                if let Some(LanguageServerState::Running { server, .. }) =
 1354                    self.language_servers.get(&state.id)
 1355                {
 1356                    Some(server)
 1357                } else {
 1358                    None
 1359                }
 1360            })
 1361    }
 1362
 1363    fn language_server_ids_for_project_path(
 1364        &self,
 1365        project_path: ProjectPath,
 1366        language: &Language,
 1367        cx: &mut App,
 1368    ) -> Vec<LanguageServerId> {
 1369        let Some(worktree) = self
 1370            .worktree_store
 1371            .read(cx)
 1372            .worktree_for_id(project_path.worktree_id, cx)
 1373        else {
 1374            return Vec::new();
 1375        };
 1376        let delegate: Arc<dyn ManifestDelegate> =
 1377            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1378
 1379        self.lsp_tree
 1380            .get(
 1381                project_path,
 1382                language.name(),
 1383                language.manifest(),
 1384                &delegate,
 1385                cx,
 1386            )
 1387            .collect::<Vec<_>>()
 1388    }
 1389
 1390    fn language_server_ids_for_buffer(
 1391        &self,
 1392        buffer: &Buffer,
 1393        cx: &mut App,
 1394    ) -> Vec<LanguageServerId> {
 1395        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1396            let worktree_id = file.worktree_id(cx);
 1397
 1398            let path: Arc<RelPath> = file
 1399                .path()
 1400                .parent()
 1401                .map(Arc::from)
 1402                .unwrap_or_else(|| file.path().clone());
 1403            let worktree_path = ProjectPath { worktree_id, path };
 1404            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1405        } else {
 1406            Vec::new()
 1407        }
 1408    }
 1409
 1410    fn language_servers_for_buffer<'a>(
 1411        &'a self,
 1412        buffer: &'a Buffer,
 1413        cx: &'a mut App,
 1414    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1415        self.language_server_ids_for_buffer(buffer, cx)
 1416            .into_iter()
 1417            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1418                LanguageServerState::Running {
 1419                    adapter, server, ..
 1420                } => Some((adapter, server)),
 1421                _ => None,
 1422            })
 1423    }
 1424
 1425    async fn execute_code_action_kind_locally(
 1426        lsp_store: WeakEntity<LspStore>,
 1427        mut buffers: Vec<Entity<Buffer>>,
 1428        kind: CodeActionKind,
 1429        push_to_history: bool,
 1430        cx: &mut AsyncApp,
 1431    ) -> anyhow::Result<ProjectTransaction> {
 1432        // Do not allow multiple concurrent code actions requests for the
 1433        // same buffer.
 1434        lsp_store.update(cx, |this, cx| {
 1435            let this = this.as_local_mut().unwrap();
 1436            buffers.retain(|buffer| {
 1437                this.buffers_being_formatted
 1438                    .insert(buffer.read(cx).remote_id())
 1439            });
 1440        })?;
 1441        let _cleanup = defer({
 1442            let this = lsp_store.clone();
 1443            let mut cx = cx.clone();
 1444            let buffers = &buffers;
 1445            move || {
 1446                this.update(&mut cx, |this, cx| {
 1447                    let this = this.as_local_mut().unwrap();
 1448                    for buffer in buffers {
 1449                        this.buffers_being_formatted
 1450                            .remove(&buffer.read(cx).remote_id());
 1451                    }
 1452                })
 1453                .ok();
 1454            }
 1455        });
 1456        let mut project_transaction = ProjectTransaction::default();
 1457
 1458        for buffer in &buffers {
 1459            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1460                buffer.update(cx, |buffer, cx| {
 1461                    lsp_store
 1462                        .as_local()
 1463                        .unwrap()
 1464                        .language_servers_for_buffer(buffer, cx)
 1465                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1466                        .collect::<Vec<_>>()
 1467                })
 1468            })?;
 1469            for (_, language_server) in adapters_and_servers.iter() {
 1470                let actions = Self::get_server_code_actions_from_action_kinds(
 1471                    &lsp_store,
 1472                    language_server.server_id(),
 1473                    vec![kind.clone()],
 1474                    buffer,
 1475                    cx,
 1476                )
 1477                .await?;
 1478                Self::execute_code_actions_on_server(
 1479                    &lsp_store,
 1480                    language_server,
 1481                    actions,
 1482                    push_to_history,
 1483                    &mut project_transaction,
 1484                    cx,
 1485                )
 1486                .await?;
 1487            }
 1488        }
 1489        Ok(project_transaction)
 1490    }
 1491
 1492    async fn format_locally(
 1493        lsp_store: WeakEntity<LspStore>,
 1494        mut buffers: Vec<FormattableBuffer>,
 1495        push_to_history: bool,
 1496        trigger: FormatTrigger,
 1497        logger: zlog::Logger,
 1498        cx: &mut AsyncApp,
 1499    ) -> anyhow::Result<ProjectTransaction> {
 1500        // Do not allow multiple concurrent formatting requests for the
 1501        // same buffer.
 1502        lsp_store.update(cx, |this, cx| {
 1503            let this = this.as_local_mut().unwrap();
 1504            buffers.retain(|buffer| {
 1505                this.buffers_being_formatted
 1506                    .insert(buffer.handle.read(cx).remote_id())
 1507            });
 1508        })?;
 1509
 1510        let _cleanup = defer({
 1511            let this = lsp_store.clone();
 1512            let mut cx = cx.clone();
 1513            let buffers = &buffers;
 1514            move || {
 1515                this.update(&mut cx, |this, cx| {
 1516                    let this = this.as_local_mut().unwrap();
 1517                    for buffer in buffers {
 1518                        this.buffers_being_formatted
 1519                            .remove(&buffer.handle.read(cx).remote_id());
 1520                    }
 1521                })
 1522                .ok();
 1523            }
 1524        });
 1525
 1526        let mut project_transaction = ProjectTransaction::default();
 1527
 1528        for buffer in &buffers {
 1529            zlog::debug!(
 1530                logger =>
 1531                "formatting buffer '{:?}'",
 1532                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1533            );
 1534            // Create an empty transaction to hold all of the formatting edits.
 1535            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1536                // ensure no transactions created while formatting are
 1537                // grouped with the previous transaction in the history
 1538                // based on the transaction group interval
 1539                buffer.finalize_last_transaction();
 1540                buffer
 1541                    .start_transaction()
 1542                    .context("transaction already open")?;
 1543                buffer.end_transaction(cx);
 1544                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1545                buffer.finalize_last_transaction();
 1546                anyhow::Ok(transaction_id)
 1547            })?;
 1548
 1549            let result = Self::format_buffer_locally(
 1550                lsp_store.clone(),
 1551                buffer,
 1552                formatting_transaction_id,
 1553                trigger,
 1554                logger,
 1555                cx,
 1556            )
 1557            .await;
 1558
 1559            buffer.handle.update(cx, |buffer, cx| {
 1560                let Some(formatting_transaction) =
 1561                    buffer.get_transaction(formatting_transaction_id).cloned()
 1562                else {
 1563                    zlog::warn!(logger => "no formatting transaction");
 1564                    return;
 1565                };
 1566                if formatting_transaction.edit_ids.is_empty() {
 1567                    zlog::debug!(logger => "no changes made while formatting");
 1568                    buffer.forget_transaction(formatting_transaction_id);
 1569                    return;
 1570                }
 1571                if !push_to_history {
 1572                    zlog::trace!(logger => "forgetting format transaction");
 1573                    buffer.forget_transaction(formatting_transaction.id);
 1574                }
 1575                project_transaction
 1576                    .0
 1577                    .insert(cx.entity(), formatting_transaction);
 1578            });
 1579
 1580            result?;
 1581        }
 1582
 1583        Ok(project_transaction)
 1584    }
 1585
 1586    async fn format_buffer_locally(
 1587        lsp_store: WeakEntity<LspStore>,
 1588        buffer: &FormattableBuffer,
 1589        formatting_transaction_id: clock::Lamport,
 1590        trigger: FormatTrigger,
 1591        logger: zlog::Logger,
 1592        cx: &mut AsyncApp,
 1593    ) -> Result<()> {
 1594        let (adapters_and_servers, settings, request_timeout) =
 1595            lsp_store.update(cx, |lsp_store, cx| {
 1596                buffer.handle.update(cx, |buffer, cx| {
 1597                    let adapters_and_servers = lsp_store
 1598                        .as_local()
 1599                        .unwrap()
 1600                        .language_servers_for_buffer(buffer, cx)
 1601                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1602                        .collect::<Vec<_>>();
 1603                    let settings =
 1604                        language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1605                            .into_owned();
 1606                    let request_timeout = ProjectSettings::get_global(cx)
 1607                        .global_lsp_settings
 1608                        .get_request_timeout();
 1609                    (adapters_and_servers, settings, request_timeout)
 1610                })
 1611            })?;
 1612
 1613        /// Apply edits to the buffer that will become part of the formatting transaction.
 1614        /// Fails if the buffer has been edited since the start of that transaction.
 1615        fn extend_formatting_transaction(
 1616            buffer: &FormattableBuffer,
 1617            formatting_transaction_id: text::TransactionId,
 1618            cx: &mut AsyncApp,
 1619            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1620        ) -> anyhow::Result<()> {
 1621            buffer.handle.update(cx, |buffer, cx| {
 1622                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1623                if last_transaction_id != Some(formatting_transaction_id) {
 1624                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1625                }
 1626                buffer.start_transaction();
 1627                operation(buffer, cx);
 1628                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1629                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1630                }
 1631                Ok(())
 1632            })
 1633        }
 1634
 1635        // handle whitespace formatting
 1636        if settings.remove_trailing_whitespace_on_save {
 1637            zlog::trace!(logger => "removing trailing whitespace");
 1638            let diff = buffer
 1639                .handle
 1640                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1641                .await;
 1642            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1643                buffer.apply_diff(diff, cx);
 1644            })?;
 1645        }
 1646
 1647        if settings.ensure_final_newline_on_save {
 1648            zlog::trace!(logger => "ensuring final newline");
 1649            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1650                buffer.ensure_final_newline(cx);
 1651            })?;
 1652        }
 1653
 1654        // Formatter for `code_actions_on_format` that runs before
 1655        // the rest of the formatters
 1656        let mut code_actions_on_format_formatters = None;
 1657        let should_run_code_actions_on_format = !matches!(
 1658            (trigger, &settings.format_on_save),
 1659            (FormatTrigger::Save, &FormatOnSave::Off)
 1660        );
 1661        if should_run_code_actions_on_format {
 1662            let have_code_actions_to_run_on_format = settings
 1663                .code_actions_on_format
 1664                .values()
 1665                .any(|enabled| *enabled);
 1666            if have_code_actions_to_run_on_format {
 1667                zlog::trace!(logger => "going to run code actions on format");
 1668                code_actions_on_format_formatters = Some(
 1669                    settings
 1670                        .code_actions_on_format
 1671                        .iter()
 1672                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1673                        .cloned()
 1674                        .map(Formatter::CodeAction)
 1675                        .collect::<Vec<_>>(),
 1676                );
 1677            }
 1678        }
 1679
 1680        let formatters = match (trigger, &settings.format_on_save) {
 1681            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1682            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1683                settings.formatter.as_ref()
 1684            }
 1685        };
 1686
 1687        let formatters = code_actions_on_format_formatters
 1688            .iter()
 1689            .flatten()
 1690            .chain(formatters);
 1691
 1692        for formatter in formatters {
 1693            let formatter = if formatter == &Formatter::Auto {
 1694                if settings.prettier.allowed {
 1695                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1696                    &Formatter::Prettier
 1697                } else {
 1698                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1699                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1700                }
 1701            } else {
 1702                formatter
 1703            };
 1704            match formatter {
 1705                Formatter::Auto => unreachable!("Auto resolved above"),
 1706                Formatter::Prettier => {
 1707                    let logger = zlog::scoped!(logger => "prettier");
 1708                    zlog::trace!(logger => "formatting");
 1709                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1710
 1711                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1712                        lsp_store.prettier_store().unwrap().downgrade()
 1713                    })?;
 1714                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1715                        .await
 1716                        .transpose()?;
 1717                    let Some(diff) = diff else {
 1718                        zlog::trace!(logger => "No changes");
 1719                        continue;
 1720                    };
 1721
 1722                    extend_formatting_transaction(
 1723                        buffer,
 1724                        formatting_transaction_id,
 1725                        cx,
 1726                        |buffer, cx| {
 1727                            buffer.apply_diff(diff, cx);
 1728                        },
 1729                    )?;
 1730                }
 1731                Formatter::External { command, arguments } => {
 1732                    let logger = zlog::scoped!(logger => "command");
 1733                    zlog::trace!(logger => "formatting");
 1734                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1735
 1736                    let diff = Self::format_via_external_command(
 1737                        buffer,
 1738                        &command,
 1739                        arguments.as_deref(),
 1740                        cx,
 1741                    )
 1742                    .await
 1743                    .with_context(|| {
 1744                        format!("Failed to format buffer via external command: {}", command)
 1745                    })?;
 1746                    let Some(diff) = diff else {
 1747                        zlog::trace!(logger => "No changes");
 1748                        continue;
 1749                    };
 1750
 1751                    extend_formatting_transaction(
 1752                        buffer,
 1753                        formatting_transaction_id,
 1754                        cx,
 1755                        |buffer, cx| {
 1756                            buffer.apply_diff(diff, cx);
 1757                        },
 1758                    )?;
 1759                }
 1760                Formatter::LanguageServer(specifier) => {
 1761                    let logger = zlog::scoped!(logger => "language-server");
 1762                    zlog::trace!(logger => "formatting");
 1763                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1764
 1765                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1766                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1767                        continue;
 1768                    };
 1769
 1770                    let language_server = match specifier {
 1771                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1772                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1773                                if adapter.name.0.as_ref() == name {
 1774                                    Some(server.clone())
 1775                                } else {
 1776                                    None
 1777                                }
 1778                            })
 1779                        }
 1780                        settings::LanguageServerFormatterSpecifier::Current => {
 1781                            adapters_and_servers.first().map(|e| e.1.clone())
 1782                        }
 1783                    };
 1784
 1785                    let Some(language_server) = language_server else {
 1786                        log::debug!(
 1787                            "No language server found to format buffer '{:?}'. Skipping",
 1788                            buffer_path_abs.as_path().to_string_lossy()
 1789                        );
 1790                        continue;
 1791                    };
 1792
 1793                    zlog::trace!(
 1794                        logger =>
 1795                        "Formatting buffer '{:?}' using language server '{:?}'",
 1796                        buffer_path_abs.as_path().to_string_lossy(),
 1797                        language_server.name()
 1798                    );
 1799
 1800                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1801                        zlog::trace!(logger => "formatting ranges");
 1802                        Self::format_ranges_via_lsp(
 1803                            &lsp_store,
 1804                            &buffer.handle,
 1805                            ranges,
 1806                            buffer_path_abs,
 1807                            &language_server,
 1808                            &settings,
 1809                            cx,
 1810                        )
 1811                        .await
 1812                        .context("Failed to format ranges via language server")?
 1813                    } else {
 1814                        zlog::trace!(logger => "formatting full");
 1815                        Self::format_via_lsp(
 1816                            &lsp_store,
 1817                            &buffer.handle,
 1818                            buffer_path_abs,
 1819                            &language_server,
 1820                            &settings,
 1821                            cx,
 1822                        )
 1823                        .await
 1824                        .context("failed to format via language server")?
 1825                    };
 1826
 1827                    if edits.is_empty() {
 1828                        zlog::trace!(logger => "No changes");
 1829                        continue;
 1830                    }
 1831                    extend_formatting_transaction(
 1832                        buffer,
 1833                        formatting_transaction_id,
 1834                        cx,
 1835                        |buffer, cx| {
 1836                            buffer.edit(edits, None, cx);
 1837                        },
 1838                    )?;
 1839                }
 1840                Formatter::CodeAction(code_action_name) => {
 1841                    let logger = zlog::scoped!(logger => "code-actions");
 1842                    zlog::trace!(logger => "formatting");
 1843                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1844
 1845                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1846                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1847                        continue;
 1848                    };
 1849
 1850                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1851                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1852
 1853                    let mut actions_and_servers = Vec::new();
 1854
 1855                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1856                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1857                            &lsp_store,
 1858                            language_server.server_id(),
 1859                            vec![code_action_kind.clone()],
 1860                            &buffer.handle,
 1861                            cx,
 1862                        )
 1863                        .await
 1864                        .with_context(|| {
 1865                            format!(
 1866                                "Failed to resolve code action {:?} with language server {}",
 1867                                code_action_kind,
 1868                                language_server.name()
 1869                            )
 1870                        });
 1871                        let Ok(actions) = actions_result else {
 1872                            // note: it may be better to set result to the error and break formatters here
 1873                            // but for now we try to execute the actions that we can resolve and skip the rest
 1874                            zlog::error!(
 1875                                logger =>
 1876                                "Failed to resolve code action {:?} with language server {}",
 1877                                code_action_kind,
 1878                                language_server.name()
 1879                            );
 1880                            continue;
 1881                        };
 1882                        for action in actions {
 1883                            actions_and_servers.push((action, index));
 1884                        }
 1885                    }
 1886
 1887                    if actions_and_servers.is_empty() {
 1888                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1889                        continue;
 1890                    }
 1891
 1892                    'actions: for (mut action, server_index) in actions_and_servers {
 1893                        let server = &adapters_and_servers[server_index].1;
 1894
 1895                        let describe_code_action = |action: &CodeAction| {
 1896                            format!(
 1897                                "code action '{}' with title \"{}\" on server {}",
 1898                                action
 1899                                    .lsp_action
 1900                                    .action_kind()
 1901                                    .unwrap_or("unknown".into())
 1902                                    .as_str(),
 1903                                action.lsp_action.title(),
 1904                                server.name(),
 1905                            )
 1906                        };
 1907
 1908                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1909
 1910                        if let Err(err) =
 1911                            Self::try_resolve_code_action(server, &mut action, request_timeout)
 1912                                .await
 1913                        {
 1914                            zlog::error!(
 1915                                logger =>
 1916                                "Failed to resolve {}. Error: {}",
 1917                                describe_code_action(&action),
 1918                                err
 1919                            );
 1920                            continue;
 1921                        }
 1922
 1923                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1924                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1925                            // but filters out and logs warnings for code actions that require unreasonably
 1926                            // difficult handling on our part, such as:
 1927                            // - applying edits that call commands
 1928                            //   which can result in arbitrary workspace edits being sent from the server that
 1929                            //   have no way of being tied back to the command that initiated them (i.e. we
 1930                            //   can't know which edits are part of the format request, or if the server is done sending
 1931                            //   actions in response to the command)
 1932                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1933                            //   as we then would need to handle such changes correctly in the local history as well
 1934                            //   as the remote history through the ProjectTransaction
 1935                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1936                            // Supporting these actions is not impossible, but not supported as of yet.
 1937                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1938                                zlog::trace!(
 1939                                    logger =>
 1940                                    "No changes for code action. Skipping {}",
 1941                                    describe_code_action(&action),
 1942                                );
 1943                                continue;
 1944                            }
 1945
 1946                            let mut operations = Vec::new();
 1947                            if let Some(document_changes) = edit.document_changes {
 1948                                match document_changes {
 1949                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1950                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1951                                    ),
 1952                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1953                                }
 1954                            } else if let Some(changes) = edit.changes {
 1955                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1956                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1957                                        text_document:
 1958                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1959                                                uri,
 1960                                                version: None,
 1961                                            },
 1962                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1963                                    })
 1964                                }));
 1965                            }
 1966
 1967                            let mut edits = Vec::with_capacity(operations.len());
 1968
 1969                            if operations.is_empty() {
 1970                                zlog::trace!(
 1971                                    logger =>
 1972                                    "No changes for code action. Skipping {}",
 1973                                    describe_code_action(&action),
 1974                                );
 1975                                continue;
 1976                            }
 1977                            for operation in operations {
 1978                                let op = match operation {
 1979                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1980                                    lsp::DocumentChangeOperation::Op(_) => {
 1981                                        zlog::warn!(
 1982                                            logger =>
 1983                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1984                                            describe_code_action(&action),
 1985                                        );
 1986                                        continue 'actions;
 1987                                    }
 1988                                };
 1989                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1990                                    zlog::warn!(
 1991                                        logger =>
 1992                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1993                                        &op.text_document.uri,
 1994                                        describe_code_action(&action),
 1995                                    );
 1996                                    continue 'actions;
 1997                                };
 1998                                if &file_path != buffer_path_abs {
 1999                                    zlog::warn!(
 2000                                        logger =>
 2001                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 2002                                        file_path,
 2003                                        buffer_path_abs,
 2004                                        describe_code_action(&action),
 2005                                    );
 2006                                    continue 'actions;
 2007                                }
 2008
 2009                                let mut lsp_edits = Vec::new();
 2010                                for edit in op.edits {
 2011                                    match edit {
 2012                                        Edit::Plain(edit) => {
 2013                                            if !lsp_edits.contains(&edit) {
 2014                                                lsp_edits.push(edit);
 2015                                            }
 2016                                        }
 2017                                        Edit::Annotated(edit) => {
 2018                                            if !lsp_edits.contains(&edit.text_edit) {
 2019                                                lsp_edits.push(edit.text_edit);
 2020                                            }
 2021                                        }
 2022                                        Edit::Snippet(_) => {
 2023                                            zlog::warn!(
 2024                                                logger =>
 2025                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 2026                                                describe_code_action(&action),
 2027                                            );
 2028                                            continue 'actions;
 2029                                        }
 2030                                    }
 2031                                }
 2032                                let edits_result = lsp_store
 2033                                    .update(cx, |lsp_store, cx| {
 2034                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 2035                                            &buffer.handle,
 2036                                            lsp_edits,
 2037                                            server.server_id(),
 2038                                            op.text_document.version,
 2039                                            cx,
 2040                                        )
 2041                                    })?
 2042                                    .await;
 2043                                let Ok(resolved_edits) = edits_result else {
 2044                                    zlog::warn!(
 2045                                        logger =>
 2046                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 2047                                        buffer_path_abs.as_path(),
 2048                                        describe_code_action(&action),
 2049                                    );
 2050                                    continue 'actions;
 2051                                };
 2052                                edits.extend(resolved_edits);
 2053                            }
 2054
 2055                            if edits.is_empty() {
 2056                                zlog::warn!(logger => "No edits resolved from LSP");
 2057                                continue;
 2058                            }
 2059
 2060                            extend_formatting_transaction(
 2061                                buffer,
 2062                                formatting_transaction_id,
 2063                                cx,
 2064                                |buffer, cx| {
 2065                                    zlog::info!(
 2066                                        "Applying edits {edits:?}. Content: {:?}",
 2067                                        buffer.text()
 2068                                    );
 2069                                    buffer.edit(edits, None, cx);
 2070                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 2071                                },
 2072                            )?;
 2073                        }
 2074
 2075                        // bail early if command is invalid
 2076                        let Some(command) = action.lsp_action.command() else {
 2077                            continue;
 2078                        };
 2079
 2080                        zlog::warn!(
 2081                            logger =>
 2082                            "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 2083                            &command.command,
 2084                        );
 2085
 2086                        let server_capabilities = server.capabilities();
 2087                        let available_commands = server_capabilities
 2088                            .execute_command_provider
 2089                            .as_ref()
 2090                            .map(|options| options.commands.as_slice())
 2091                            .unwrap_or_default();
 2092                        if !available_commands.contains(&command.command) {
 2093                            zlog::warn!(
 2094                                logger =>
 2095                                "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2096                                command.command,
 2097                                server.name(),
 2098                            );
 2099                            continue;
 2100                        }
 2101
 2102                        // noop so we just ensure buffer hasn't been edited since resolving code actions
 2103                        extend_formatting_transaction(
 2104                            buffer,
 2105                            formatting_transaction_id,
 2106                            cx,
 2107                            |_, _| {},
 2108                        )?;
 2109                        zlog::info!(logger => "Executing command {}", &command.command);
 2110
 2111                        lsp_store.update(cx, |this, _| {
 2112                            this.as_local_mut()
 2113                                .unwrap()
 2114                                .last_workspace_edits_by_language_server
 2115                                .remove(&server.server_id());
 2116                        })?;
 2117
 2118                        let execute_command_result = server
 2119                            .request::<lsp::request::ExecuteCommand>(
 2120                                lsp::ExecuteCommandParams {
 2121                                    command: command.command.clone(),
 2122                                    arguments: command.arguments.clone().unwrap_or_default(),
 2123                                    ..Default::default()
 2124                                },
 2125                                request_timeout,
 2126                            )
 2127                            .await
 2128                            .into_response();
 2129
 2130                        if execute_command_result.is_err() {
 2131                            zlog::error!(
 2132                                logger =>
 2133                                "Failed to execute command '{}' as part of {}",
 2134                                &command.command,
 2135                                describe_code_action(&action),
 2136                            );
 2137                            continue 'actions;
 2138                        }
 2139
 2140                        let mut project_transaction_command = lsp_store.update(cx, |this, _| {
 2141                            this.as_local_mut()
 2142                                .unwrap()
 2143                                .last_workspace_edits_by_language_server
 2144                                .remove(&server.server_id())
 2145                                .unwrap_or_default()
 2146                        })?;
 2147
 2148                        if let Some(transaction) =
 2149                            project_transaction_command.0.remove(&buffer.handle)
 2150                        {
 2151                            zlog::trace!(
 2152                                logger =>
 2153                                "Successfully captured {} edits that resulted from command {}",
 2154                                transaction.edit_ids.len(),
 2155                                &command.command,
 2156                            );
 2157                            let transaction_id_project_transaction = transaction.id;
 2158                            buffer.handle.update(cx, |buffer, _| {
 2159                                // it may have been removed from history if push_to_history was
 2160                                // false in deserialize_workspace_edit. If so push it so we
 2161                                // can merge it with the format transaction
 2162                                // and pop the combined transaction off the history stack
 2163                                // later if push_to_history is false
 2164                                if buffer.get_transaction(transaction.id).is_none() {
 2165                                    buffer.push_transaction(transaction, Instant::now());
 2166                                }
 2167                                buffer.merge_transactions(
 2168                                    transaction_id_project_transaction,
 2169                                    formatting_transaction_id,
 2170                                );
 2171                            });
 2172                        }
 2173
 2174                        if project_transaction_command.0.is_empty() {
 2175                            continue;
 2176                        }
 2177
 2178                        let mut extra_buffers = String::new();
 2179                        for buffer in project_transaction_command.0.keys() {
 2180                            buffer.read_with(cx, |b, cx| {
 2181                                let Some(path) = b.project_path(cx) else {
 2182                                    return;
 2183                                };
 2184
 2185                                if !extra_buffers.is_empty() {
 2186                                    extra_buffers.push_str(", ");
 2187                                }
 2188                                extra_buffers.push_str(path.path.as_unix_str());
 2189                            });
 2190                        }
 2191                        zlog::warn!(
 2192                            logger =>
 2193                            "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2194                            &command.command,
 2195                            extra_buffers,
 2196                        );
 2197                        // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2198                        // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2199                        // add it so it's included, and merge it into the format transaction when its created later
 2200                    }
 2201                }
 2202            }
 2203        }
 2204
 2205        Ok(())
 2206    }
 2207
 2208    pub async fn format_ranges_via_lsp(
 2209        this: &WeakEntity<LspStore>,
 2210        buffer_handle: &Entity<Buffer>,
 2211        ranges: &[Range<Anchor>],
 2212        abs_path: &Path,
 2213        language_server: &Arc<LanguageServer>,
 2214        settings: &LanguageSettings,
 2215        cx: &mut AsyncApp,
 2216    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2217        let capabilities = &language_server.capabilities();
 2218        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2219        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2220            anyhow::bail!(
 2221                "{} language server does not support range formatting",
 2222                language_server.name()
 2223            );
 2224        }
 2225
 2226        let uri = file_path_to_lsp_url(abs_path)?;
 2227        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2228
 2229        let request_timeout = cx.update(|app| {
 2230            ProjectSettings::get_global(app)
 2231                .global_lsp_settings
 2232                .get_request_timeout()
 2233        });
 2234        let lsp_edits = {
 2235            let mut lsp_ranges = Vec::new();
 2236            this.update(cx, |_this, cx| {
 2237                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2238                // not have been sent to the language server. This seems like a fairly systemic
 2239                // issue, though, the resolution probably is not specific to formatting.
 2240                //
 2241                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2242                // LSP.
 2243                let snapshot = buffer_handle.read(cx).snapshot();
 2244                for range in ranges {
 2245                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2246                }
 2247                anyhow::Ok(())
 2248            })??;
 2249
 2250            let mut edits = None;
 2251            for range in lsp_ranges {
 2252                if let Some(mut edit) = language_server
 2253                    .request::<lsp::request::RangeFormatting>(
 2254                        lsp::DocumentRangeFormattingParams {
 2255                            text_document: text_document.clone(),
 2256                            range,
 2257                            options: lsp_command::lsp_formatting_options(settings),
 2258                            work_done_progress_params: Default::default(),
 2259                        },
 2260                        request_timeout,
 2261                    )
 2262                    .await
 2263                    .into_response()?
 2264                {
 2265                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2266                }
 2267            }
 2268            edits
 2269        };
 2270
 2271        if let Some(lsp_edits) = lsp_edits {
 2272            this.update(cx, |this, cx| {
 2273                this.as_local_mut().unwrap().edits_from_lsp(
 2274                    buffer_handle,
 2275                    lsp_edits,
 2276                    language_server.server_id(),
 2277                    None,
 2278                    cx,
 2279                )
 2280            })?
 2281            .await
 2282        } else {
 2283            Ok(Vec::with_capacity(0))
 2284        }
 2285    }
 2286
 2287    async fn format_via_lsp(
 2288        this: &WeakEntity<LspStore>,
 2289        buffer: &Entity<Buffer>,
 2290        abs_path: &Path,
 2291        language_server: &Arc<LanguageServer>,
 2292        settings: &LanguageSettings,
 2293        cx: &mut AsyncApp,
 2294    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2295        let logger = zlog::scoped!("lsp_format");
 2296        zlog::debug!(logger => "Formatting via LSP");
 2297
 2298        let uri = file_path_to_lsp_url(abs_path)?;
 2299        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2300        let capabilities = &language_server.capabilities();
 2301
 2302        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2303        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2304
 2305        let request_timeout = cx.update(|app| {
 2306            ProjectSettings::get_global(app)
 2307                .global_lsp_settings
 2308                .get_request_timeout()
 2309        });
 2310
 2311        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2312            let _timer = zlog::time!(logger => "format-full");
 2313            language_server
 2314                .request::<lsp::request::Formatting>(
 2315                    lsp::DocumentFormattingParams {
 2316                        text_document,
 2317                        options: lsp_command::lsp_formatting_options(settings),
 2318                        work_done_progress_params: Default::default(),
 2319                    },
 2320                    request_timeout,
 2321                )
 2322                .await
 2323                .into_response()?
 2324        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2325            let _timer = zlog::time!(logger => "format-range");
 2326            let buffer_start = lsp::Position::new(0, 0);
 2327            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2328            language_server
 2329                .request::<lsp::request::RangeFormatting>(
 2330                    lsp::DocumentRangeFormattingParams {
 2331                        text_document: text_document.clone(),
 2332                        range: lsp::Range::new(buffer_start, buffer_end),
 2333                        options: lsp_command::lsp_formatting_options(settings),
 2334                        work_done_progress_params: Default::default(),
 2335                    },
 2336                    request_timeout,
 2337                )
 2338                .await
 2339                .into_response()?
 2340        } else {
 2341            None
 2342        };
 2343
 2344        if let Some(lsp_edits) = lsp_edits {
 2345            this.update(cx, |this, cx| {
 2346                this.as_local_mut().unwrap().edits_from_lsp(
 2347                    buffer,
 2348                    lsp_edits,
 2349                    language_server.server_id(),
 2350                    None,
 2351                    cx,
 2352                )
 2353            })?
 2354            .await
 2355        } else {
 2356            Ok(Vec::with_capacity(0))
 2357        }
 2358    }
 2359
 2360    async fn format_via_external_command(
 2361        buffer: &FormattableBuffer,
 2362        command: &str,
 2363        arguments: Option<&[String]>,
 2364        cx: &mut AsyncApp,
 2365    ) -> Result<Option<Diff>> {
 2366        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2367            let file = File::from_dyn(buffer.file())?;
 2368            let worktree = file.worktree.read(cx);
 2369            let mut worktree_path = worktree.abs_path().to_path_buf();
 2370            if worktree.root_entry()?.is_file() {
 2371                worktree_path.pop();
 2372            }
 2373            Some(worktree_path)
 2374        });
 2375
 2376        use util::command::Stdio;
 2377        let mut child = util::command::new_command(command);
 2378
 2379        if let Some(buffer_env) = buffer.env.as_ref() {
 2380            child.envs(buffer_env);
 2381        }
 2382
 2383        if let Some(working_dir_path) = working_dir_path {
 2384            child.current_dir(working_dir_path);
 2385        }
 2386
 2387        if let Some(arguments) = arguments {
 2388            child.args(arguments.iter().map(|arg| {
 2389                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2390                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2391                } else {
 2392                    arg.replace("{buffer_path}", "Untitled")
 2393                }
 2394            }));
 2395        }
 2396
 2397        let mut child = child
 2398            .stdin(Stdio::piped())
 2399            .stdout(Stdio::piped())
 2400            .stderr(Stdio::piped())
 2401            .spawn()?;
 2402
 2403        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2404        let text = buffer
 2405            .handle
 2406            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2407        for chunk in text.chunks() {
 2408            stdin.write_all(chunk.as_bytes()).await?;
 2409        }
 2410        stdin.flush().await?;
 2411
 2412        let output = child.output().await?;
 2413        anyhow::ensure!(
 2414            output.status.success(),
 2415            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2416            output.status.code(),
 2417            String::from_utf8_lossy(&output.stdout),
 2418            String::from_utf8_lossy(&output.stderr),
 2419        );
 2420
 2421        let stdout = String::from_utf8(output.stdout)?;
 2422        Ok(Some(
 2423            buffer
 2424                .handle
 2425                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2426                .await,
 2427        ))
 2428    }
 2429
 2430    async fn try_resolve_code_action(
 2431        lang_server: &LanguageServer,
 2432        action: &mut CodeAction,
 2433        request_timeout: Duration,
 2434    ) -> anyhow::Result<()> {
 2435        match &mut action.lsp_action {
 2436            LspAction::Action(lsp_action) => {
 2437                if !action.resolved
 2438                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2439                    && lsp_action.data.is_some()
 2440                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2441                {
 2442                    **lsp_action = lang_server
 2443                        .request::<lsp::request::CodeActionResolveRequest>(
 2444                            *lsp_action.clone(),
 2445                            request_timeout,
 2446                        )
 2447                        .await
 2448                        .into_response()?;
 2449                }
 2450            }
 2451            LspAction::CodeLens(lens) => {
 2452                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2453                    *lens = lang_server
 2454                        .request::<lsp::request::CodeLensResolve>(lens.clone(), request_timeout)
 2455                        .await
 2456                        .into_response()?;
 2457                }
 2458            }
 2459            LspAction::Command(_) => {}
 2460        }
 2461
 2462        action.resolved = true;
 2463        anyhow::Ok(())
 2464    }
 2465
 2466    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2467        let buffer = buffer_handle.read(cx);
 2468
 2469        let file = buffer.file().cloned();
 2470
 2471        let Some(file) = File::from_dyn(file.as_ref()) else {
 2472            return;
 2473        };
 2474        if !file.is_local() {
 2475            return;
 2476        }
 2477        let path = ProjectPath::from_file(file, cx);
 2478        let worktree_id = file.worktree_id(cx);
 2479        let language = buffer.language().cloned();
 2480
 2481        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2482            for (server_id, diagnostics) in
 2483                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2484            {
 2485                self.update_buffer_diagnostics(
 2486                    buffer_handle,
 2487                    server_id,
 2488                    None,
 2489                    None,
 2490                    None,
 2491                    Vec::new(),
 2492                    diagnostics,
 2493                    cx,
 2494                )
 2495                .log_err();
 2496            }
 2497        }
 2498        let Some(language) = language else {
 2499            return;
 2500        };
 2501        let Some(snapshot) = self
 2502            .worktree_store
 2503            .read(cx)
 2504            .worktree_for_id(worktree_id, cx)
 2505            .map(|worktree| worktree.read(cx).snapshot())
 2506        else {
 2507            return;
 2508        };
 2509        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2510
 2511        for server_id in
 2512            self.lsp_tree
 2513                .get(path, language.name(), language.manifest(), &delegate, cx)
 2514        {
 2515            let server = self
 2516                .language_servers
 2517                .get(&server_id)
 2518                .and_then(|server_state| {
 2519                    if let LanguageServerState::Running { server, .. } = server_state {
 2520                        Some(server.clone())
 2521                    } else {
 2522                        None
 2523                    }
 2524                });
 2525            let server = match server {
 2526                Some(server) => server,
 2527                None => continue,
 2528            };
 2529
 2530            buffer_handle.update(cx, |buffer, cx| {
 2531                buffer.set_completion_triggers(
 2532                    server.server_id(),
 2533                    server
 2534                        .capabilities()
 2535                        .completion_provider
 2536                        .as_ref()
 2537                        .and_then(|provider| {
 2538                            provider
 2539                                .trigger_characters
 2540                                .as_ref()
 2541                                .map(|characters| characters.iter().cloned().collect())
 2542                        })
 2543                        .unwrap_or_default(),
 2544                    cx,
 2545                );
 2546            });
 2547        }
 2548    }
 2549
 2550    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2551        buffer.update(cx, |buffer, cx| {
 2552            let Some(language) = buffer.language() else {
 2553                return;
 2554            };
 2555            let path = ProjectPath {
 2556                worktree_id: old_file.worktree_id(cx),
 2557                path: old_file.path.clone(),
 2558            };
 2559            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2560                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2561                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2562            }
 2563        });
 2564    }
 2565
 2566    fn update_buffer_diagnostics(
 2567        &mut self,
 2568        buffer: &Entity<Buffer>,
 2569        server_id: LanguageServerId,
 2570        registration_id: Option<Option<SharedString>>,
 2571        result_id: Option<SharedString>,
 2572        version: Option<i32>,
 2573        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2574        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2575        cx: &mut Context<LspStore>,
 2576    ) -> Result<()> {
 2577        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2578            Ordering::Equal
 2579                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2580                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2581                .then_with(|| a.severity.cmp(&b.severity))
 2582                .then_with(|| a.message.cmp(&b.message))
 2583        }
 2584
 2585        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2586        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2587        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2588
 2589        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2590            Ordering::Equal
 2591                .then_with(|| a.range.start.cmp(&b.range.start))
 2592                .then_with(|| b.range.end.cmp(&a.range.end))
 2593                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2594        });
 2595
 2596        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2597
 2598        let edits_since_save = std::cell::LazyCell::new(|| {
 2599            let saved_version = buffer.read(cx).saved_version();
 2600            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2601        });
 2602
 2603        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2604
 2605        for (new_diagnostic, entry) in diagnostics {
 2606            let start;
 2607            let end;
 2608            if new_diagnostic && entry.diagnostic.is_disk_based {
 2609                // Some diagnostics are based on files on disk instead of buffers'
 2610                // current contents. Adjust these diagnostics' ranges to reflect
 2611                // any unsaved edits.
 2612                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2613                // and were properly adjusted on reuse.
 2614                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2615                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2616            } else {
 2617                start = entry.range.start;
 2618                end = entry.range.end;
 2619            }
 2620
 2621            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2622                ..snapshot.clip_point_utf16(end, Bias::Right);
 2623
 2624            // Expand empty ranges by one codepoint
 2625            if range.start == range.end {
 2626                // This will be go to the next boundary when being clipped
 2627                range.end.column += 1;
 2628                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2629                if range.start == range.end && range.end.column > 0 {
 2630                    range.start.column -= 1;
 2631                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2632                }
 2633            }
 2634
 2635            sanitized_diagnostics.push(DiagnosticEntry {
 2636                range,
 2637                diagnostic: entry.diagnostic,
 2638            });
 2639        }
 2640        drop(edits_since_save);
 2641
 2642        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2643        buffer.update(cx, |buffer, cx| {
 2644            if let Some(registration_id) = registration_id {
 2645                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2646                    self.buffer_pull_diagnostics_result_ids
 2647                        .entry(server_id)
 2648                        .or_default()
 2649                        .entry(registration_id)
 2650                        .or_default()
 2651                        .insert(abs_path, result_id);
 2652                }
 2653            }
 2654
 2655            buffer.update_diagnostics(server_id, set, cx)
 2656        });
 2657
 2658        Ok(())
 2659    }
 2660
 2661    fn register_language_server_for_invisible_worktree(
 2662        &mut self,
 2663        worktree: &Entity<Worktree>,
 2664        language_server_id: LanguageServerId,
 2665        cx: &mut App,
 2666    ) {
 2667        let worktree = worktree.read(cx);
 2668        let worktree_id = worktree.id();
 2669        debug_assert!(!worktree.is_visible());
 2670        let Some(mut origin_seed) = self
 2671            .language_server_ids
 2672            .iter()
 2673            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2674        else {
 2675            return;
 2676        };
 2677        origin_seed.worktree_id = worktree_id;
 2678        self.language_server_ids
 2679            .entry(origin_seed)
 2680            .or_insert_with(|| UnifiedLanguageServer {
 2681                id: language_server_id,
 2682                project_roots: Default::default(),
 2683            });
 2684    }
 2685
 2686    fn register_buffer_with_language_servers(
 2687        &mut self,
 2688        buffer_handle: &Entity<Buffer>,
 2689        only_register_servers: HashSet<LanguageServerSelector>,
 2690        cx: &mut Context<LspStore>,
 2691    ) {
 2692        let buffer = buffer_handle.read(cx);
 2693        let buffer_id = buffer.remote_id();
 2694
 2695        let Some(file) = File::from_dyn(buffer.file()) else {
 2696            return;
 2697        };
 2698        if !file.is_local() {
 2699            return;
 2700        }
 2701
 2702        let abs_path = file.abs_path(cx);
 2703        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2704            return;
 2705        };
 2706        let initial_snapshot = buffer.text_snapshot();
 2707        let worktree_id = file.worktree_id(cx);
 2708
 2709        let Some(language) = buffer.language().cloned() else {
 2710            return;
 2711        };
 2712        let path: Arc<RelPath> = file
 2713            .path()
 2714            .parent()
 2715            .map(Arc::from)
 2716            .unwrap_or_else(|| file.path().clone());
 2717        let Some(worktree) = self
 2718            .worktree_store
 2719            .read(cx)
 2720            .worktree_for_id(worktree_id, cx)
 2721        else {
 2722            return;
 2723        };
 2724        let language_name = language.name();
 2725        let (reused, delegate, servers) = self
 2726            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2727            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2728            .unwrap_or_else(|| {
 2729                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2730                let delegate: Arc<dyn ManifestDelegate> =
 2731                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2732
 2733                let servers = self
 2734                    .lsp_tree
 2735                    .walk(
 2736                        ProjectPath { worktree_id, path },
 2737                        language.name(),
 2738                        language.manifest(),
 2739                        &delegate,
 2740                        cx,
 2741                    )
 2742                    .collect::<Vec<_>>();
 2743                (false, lsp_delegate, servers)
 2744            });
 2745        let servers_and_adapters = servers
 2746            .into_iter()
 2747            .filter_map(|server_node| {
 2748                if reused && server_node.server_id().is_none() {
 2749                    return None;
 2750                }
 2751                if !only_register_servers.is_empty() {
 2752                    if let Some(server_id) = server_node.server_id()
 2753                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2754                    {
 2755                        return None;
 2756                    }
 2757                    if let Some(name) = server_node.name()
 2758                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2759                    {
 2760                        return None;
 2761                    }
 2762                }
 2763
 2764                let server_id = server_node.server_id_or_init(|disposition| {
 2765                    let path = &disposition.path;
 2766
 2767                    {
 2768                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2769
 2770                        let server_id = self.get_or_insert_language_server(
 2771                            &worktree,
 2772                            delegate.clone(),
 2773                            disposition,
 2774                            &language_name,
 2775                            cx,
 2776                        );
 2777
 2778                        if let Some(state) = self.language_servers.get(&server_id)
 2779                            && let Ok(uri) = uri
 2780                        {
 2781                            state.add_workspace_folder(uri);
 2782                        };
 2783                        server_id
 2784                    }
 2785                })?;
 2786                let server_state = self.language_servers.get(&server_id)?;
 2787                if let LanguageServerState::Running {
 2788                    server, adapter, ..
 2789                } = server_state
 2790                {
 2791                    Some((server.clone(), adapter.clone()))
 2792                } else {
 2793                    None
 2794                }
 2795            })
 2796            .collect::<Vec<_>>();
 2797        for (server, adapter) in servers_and_adapters {
 2798            buffer_handle.update(cx, |buffer, cx| {
 2799                buffer.set_completion_triggers(
 2800                    server.server_id(),
 2801                    server
 2802                        .capabilities()
 2803                        .completion_provider
 2804                        .as_ref()
 2805                        .and_then(|provider| {
 2806                            provider
 2807                                .trigger_characters
 2808                                .as_ref()
 2809                                .map(|characters| characters.iter().cloned().collect())
 2810                        })
 2811                        .unwrap_or_default(),
 2812                    cx,
 2813                );
 2814            });
 2815
 2816            let snapshot = LspBufferSnapshot {
 2817                version: 0,
 2818                snapshot: initial_snapshot.clone(),
 2819            };
 2820
 2821            let mut registered = false;
 2822            self.buffer_snapshots
 2823                .entry(buffer_id)
 2824                .or_default()
 2825                .entry(server.server_id())
 2826                .or_insert_with(|| {
 2827                    registered = true;
 2828                    server.register_buffer(
 2829                        uri.clone(),
 2830                        adapter.language_id(&language.name()),
 2831                        0,
 2832                        initial_snapshot.text(),
 2833                    );
 2834
 2835                    vec![snapshot]
 2836                });
 2837
 2838            self.buffers_opened_in_servers
 2839                .entry(buffer_id)
 2840                .or_default()
 2841                .insert(server.server_id());
 2842            if registered {
 2843                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2844                    language_server_id: server.server_id(),
 2845                    name: None,
 2846                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2847                        proto::RegisteredForBuffer {
 2848                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2849                            buffer_id: buffer_id.to_proto(),
 2850                        },
 2851                    ),
 2852                });
 2853            }
 2854        }
 2855    }
 2856
 2857    fn reuse_existing_language_server<'lang_name>(
 2858        &self,
 2859        server_tree: &LanguageServerTree,
 2860        worktree: &Entity<Worktree>,
 2861        language_name: &'lang_name LanguageName,
 2862        cx: &mut App,
 2863    ) -> Option<(
 2864        Arc<LocalLspAdapterDelegate>,
 2865        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2866    )> {
 2867        if worktree.read(cx).is_visible() {
 2868            return None;
 2869        }
 2870
 2871        let worktree_store = self.worktree_store.read(cx);
 2872        let servers = server_tree
 2873            .instances
 2874            .iter()
 2875            .filter(|(worktree_id, _)| {
 2876                worktree_store
 2877                    .worktree_for_id(**worktree_id, cx)
 2878                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2879            })
 2880            .flat_map(|(worktree_id, servers)| {
 2881                servers
 2882                    .roots
 2883                    .iter()
 2884                    .flat_map(|(_, language_servers)| language_servers)
 2885                    .map(move |(_, (server_node, server_languages))| {
 2886                        (worktree_id, server_node, server_languages)
 2887                    })
 2888                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2889                    .map(|(worktree_id, server_node, _)| {
 2890                        (
 2891                            *worktree_id,
 2892                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2893                        )
 2894                    })
 2895            })
 2896            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2897                acc.entry(worktree_id)
 2898                    .or_insert_with(Vec::new)
 2899                    .push(server_node);
 2900                acc
 2901            })
 2902            .into_values()
 2903            .max_by_key(|servers| servers.len())?;
 2904
 2905        let worktree_id = worktree.read(cx).id();
 2906        let apply = move |tree: &mut LanguageServerTree| {
 2907            for server_node in &servers {
 2908                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2909            }
 2910            servers
 2911        };
 2912
 2913        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2914        Some((delegate, apply))
 2915    }
 2916
 2917    pub(crate) fn unregister_old_buffer_from_language_servers(
 2918        &mut self,
 2919        buffer: &Entity<Buffer>,
 2920        old_file: &File,
 2921        cx: &mut App,
 2922    ) {
 2923        let old_path = match old_file.as_local() {
 2924            Some(local) => local.abs_path(cx),
 2925            None => return,
 2926        };
 2927
 2928        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2929            debug_panic!("{old_path:?} is not parseable as an URI");
 2930            return;
 2931        };
 2932        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2933    }
 2934
 2935    pub(crate) fn unregister_buffer_from_language_servers(
 2936        &mut self,
 2937        buffer: &Entity<Buffer>,
 2938        file_url: &lsp::Uri,
 2939        cx: &mut App,
 2940    ) {
 2941        buffer.update(cx, |buffer, cx| {
 2942            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2943
 2944            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2945                if snapshots
 2946                    .as_mut()
 2947                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2948                {
 2949                    language_server.unregister_buffer(file_url.clone());
 2950                }
 2951            }
 2952        });
 2953    }
 2954
 2955    fn buffer_snapshot_for_lsp_version(
 2956        &mut self,
 2957        buffer: &Entity<Buffer>,
 2958        server_id: LanguageServerId,
 2959        version: Option<i32>,
 2960        cx: &App,
 2961    ) -> Result<TextBufferSnapshot> {
 2962        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2963
 2964        if let Some(version) = version {
 2965            let buffer_id = buffer.read(cx).remote_id();
 2966            let snapshots = if let Some(snapshots) = self
 2967                .buffer_snapshots
 2968                .get_mut(&buffer_id)
 2969                .and_then(|m| m.get_mut(&server_id))
 2970            {
 2971                snapshots
 2972            } else if version == 0 {
 2973                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2974                // We detect this case and treat it as if the version was `None`.
 2975                return Ok(buffer.read(cx).text_snapshot());
 2976            } else {
 2977                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2978            };
 2979
 2980            let found_snapshot = snapshots
 2981                    .binary_search_by_key(&version, |e| e.version)
 2982                    .map(|ix| snapshots[ix].snapshot.clone())
 2983                    .map_err(|_| {
 2984                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2985                    })?;
 2986
 2987            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2988            Ok(found_snapshot)
 2989        } else {
 2990            Ok((buffer.read(cx)).text_snapshot())
 2991        }
 2992    }
 2993
 2994    async fn get_server_code_actions_from_action_kinds(
 2995        lsp_store: &WeakEntity<LspStore>,
 2996        language_server_id: LanguageServerId,
 2997        code_action_kinds: Vec<lsp::CodeActionKind>,
 2998        buffer: &Entity<Buffer>,
 2999        cx: &mut AsyncApp,
 3000    ) -> Result<Vec<CodeAction>> {
 3001        let actions = lsp_store
 3002            .update(cx, move |this, cx| {
 3003                let request = GetCodeActions {
 3004                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 3005                    kinds: Some(code_action_kinds),
 3006                };
 3007                let server = LanguageServerToQuery::Other(language_server_id);
 3008                this.request_lsp(buffer.clone(), server, request, cx)
 3009            })?
 3010            .await?;
 3011        Ok(actions)
 3012    }
 3013
 3014    pub async fn execute_code_actions_on_server(
 3015        lsp_store: &WeakEntity<LspStore>,
 3016        language_server: &Arc<LanguageServer>,
 3017        actions: Vec<CodeAction>,
 3018        push_to_history: bool,
 3019        project_transaction: &mut ProjectTransaction,
 3020        cx: &mut AsyncApp,
 3021    ) -> anyhow::Result<()> {
 3022        let request_timeout = cx.update(|app| {
 3023            ProjectSettings::get_global(app)
 3024                .global_lsp_settings
 3025                .get_request_timeout()
 3026        });
 3027
 3028        for mut action in actions {
 3029            Self::try_resolve_code_action(language_server, &mut action, request_timeout)
 3030                .await
 3031                .context("resolving a formatting code action")?;
 3032
 3033            if let Some(edit) = action.lsp_action.edit() {
 3034                if edit.changes.is_none() && edit.document_changes.is_none() {
 3035                    continue;
 3036                }
 3037
 3038                let new = Self::deserialize_workspace_edit(
 3039                    lsp_store.upgrade().context("project dropped")?,
 3040                    edit.clone(),
 3041                    push_to_history,
 3042                    language_server.clone(),
 3043                    cx,
 3044                )
 3045                .await?;
 3046                project_transaction.0.extend(new.0);
 3047            }
 3048
 3049            let Some(command) = action.lsp_action.command() else {
 3050                continue;
 3051            };
 3052
 3053            let server_capabilities = language_server.capabilities();
 3054            let available_commands = server_capabilities
 3055                .execute_command_provider
 3056                .as_ref()
 3057                .map(|options| options.commands.as_slice())
 3058                .unwrap_or_default();
 3059            if !available_commands.contains(&command.command) {
 3060                log::warn!(
 3061                    "Cannot execute a command {} not listed in the language server capabilities",
 3062                    command.command
 3063                );
 3064                continue;
 3065            }
 3066
 3067            lsp_store.update(cx, |lsp_store, _| {
 3068                if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 3069                    mode.last_workspace_edits_by_language_server
 3070                        .remove(&language_server.server_id());
 3071                }
 3072            })?;
 3073
 3074            language_server
 3075                .request::<lsp::request::ExecuteCommand>(
 3076                    lsp::ExecuteCommandParams {
 3077                        command: command.command.clone(),
 3078                        arguments: command.arguments.clone().unwrap_or_default(),
 3079                        ..Default::default()
 3080                    },
 3081                    request_timeout,
 3082                )
 3083                .await
 3084                .into_response()
 3085                .context("execute command")?;
 3086
 3087            lsp_store.update(cx, |this, _| {
 3088                if let LspStoreMode::Local(mode) = &mut this.mode {
 3089                    project_transaction.0.extend(
 3090                        mode.last_workspace_edits_by_language_server
 3091                            .remove(&language_server.server_id())
 3092                            .unwrap_or_default()
 3093                            .0,
 3094                    )
 3095                }
 3096            })?;
 3097        }
 3098        Ok(())
 3099    }
 3100
 3101    pub async fn deserialize_text_edits(
 3102        this: Entity<LspStore>,
 3103        buffer_to_edit: Entity<Buffer>,
 3104        edits: Vec<lsp::TextEdit>,
 3105        push_to_history: bool,
 3106        _: Arc<CachedLspAdapter>,
 3107        language_server: Arc<LanguageServer>,
 3108        cx: &mut AsyncApp,
 3109    ) -> Result<Option<Transaction>> {
 3110        let edits = this
 3111            .update(cx, |this, cx| {
 3112                this.as_local_mut().unwrap().edits_from_lsp(
 3113                    &buffer_to_edit,
 3114                    edits,
 3115                    language_server.server_id(),
 3116                    None,
 3117                    cx,
 3118                )
 3119            })
 3120            .await?;
 3121
 3122        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3123            buffer.finalize_last_transaction();
 3124            buffer.start_transaction();
 3125            for (range, text) in edits {
 3126                buffer.edit([(range, text)], None, cx);
 3127            }
 3128
 3129            if buffer.end_transaction(cx).is_some() {
 3130                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3131                if !push_to_history {
 3132                    buffer.forget_transaction(transaction.id);
 3133                }
 3134                Some(transaction)
 3135            } else {
 3136                None
 3137            }
 3138        });
 3139
 3140        Ok(transaction)
 3141    }
 3142
 3143    #[allow(clippy::type_complexity)]
 3144    pub fn edits_from_lsp(
 3145        &mut self,
 3146        buffer: &Entity<Buffer>,
 3147        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3148        server_id: LanguageServerId,
 3149        version: Option<i32>,
 3150        cx: &mut Context<LspStore>,
 3151    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3152        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3153        cx.background_spawn(async move {
 3154            let snapshot = snapshot?;
 3155            let mut lsp_edits = lsp_edits
 3156                .into_iter()
 3157                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3158                .collect::<Vec<_>>();
 3159
 3160            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 3161
 3162            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3163            let mut edits = Vec::new();
 3164            while let Some((range, mut new_text)) = lsp_edits.next() {
 3165                // Clip invalid ranges provided by the language server.
 3166                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3167                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3168
 3169                // Combine any LSP edits that are adjacent.
 3170                //
 3171                // Also, combine LSP edits that are separated from each other by only
 3172                // a newline. This is important because for some code actions,
 3173                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3174                // are separated by unchanged newline characters.
 3175                //
 3176                // In order for the diffing logic below to work properly, any edits that
 3177                // cancel each other out must be combined into one.
 3178                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3179                    if next_range.start.0 > range.end {
 3180                        if next_range.start.0.row > range.end.row + 1
 3181                            || next_range.start.0.column > 0
 3182                            || snapshot.clip_point_utf16(
 3183                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3184                                Bias::Left,
 3185                            ) > range.end
 3186                        {
 3187                            break;
 3188                        }
 3189                        new_text.push('\n');
 3190                    }
 3191                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3192                    new_text.push_str(next_text);
 3193                    lsp_edits.next();
 3194                }
 3195
 3196                // For multiline edits, perform a diff of the old and new text so that
 3197                // we can identify the changes more precisely, preserving the locations
 3198                // of any anchors positioned in the unchanged regions.
 3199                if range.end.row > range.start.row {
 3200                    let offset = range.start.to_offset(&snapshot);
 3201                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3202                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3203                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3204                        (
 3205                            snapshot.anchor_after(offset + range.start)
 3206                                ..snapshot.anchor_before(offset + range.end),
 3207                            replacement,
 3208                        )
 3209                    }));
 3210                } else if range.end == range.start {
 3211                    let anchor = snapshot.anchor_after(range.start);
 3212                    edits.push((anchor..anchor, new_text.into()));
 3213                } else {
 3214                    let edit_start = snapshot.anchor_after(range.start);
 3215                    let edit_end = snapshot.anchor_before(range.end);
 3216                    edits.push((edit_start..edit_end, new_text.into()));
 3217                }
 3218            }
 3219
 3220            Ok(edits)
 3221        })
 3222    }
 3223
 3224    pub(crate) async fn deserialize_workspace_edit(
 3225        this: Entity<LspStore>,
 3226        edit: lsp::WorkspaceEdit,
 3227        push_to_history: bool,
 3228        language_server: Arc<LanguageServer>,
 3229        cx: &mut AsyncApp,
 3230    ) -> Result<ProjectTransaction> {
 3231        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3232
 3233        let mut operations = Vec::new();
 3234        if let Some(document_changes) = edit.document_changes {
 3235            match document_changes {
 3236                lsp::DocumentChanges::Edits(edits) => {
 3237                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3238                }
 3239                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3240            }
 3241        } else if let Some(changes) = edit.changes {
 3242            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3243                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3244                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3245                        uri,
 3246                        version: None,
 3247                    },
 3248                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3249                })
 3250            }));
 3251        }
 3252
 3253        let mut project_transaction = ProjectTransaction::default();
 3254        for operation in operations {
 3255            match operation {
 3256                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3257                    let abs_path = op
 3258                        .uri
 3259                        .to_file_path()
 3260                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3261
 3262                    if let Some(parent_path) = abs_path.parent() {
 3263                        fs.create_dir(parent_path).await?;
 3264                    }
 3265                    if abs_path.ends_with("/") {
 3266                        fs.create_dir(&abs_path).await?;
 3267                    } else {
 3268                        fs.create_file(
 3269                            &abs_path,
 3270                            op.options
 3271                                .map(|options| fs::CreateOptions {
 3272                                    overwrite: options.overwrite.unwrap_or(false),
 3273                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3274                                })
 3275                                .unwrap_or_default(),
 3276                        )
 3277                        .await?;
 3278                    }
 3279                }
 3280
 3281                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3282                    let source_abs_path = op
 3283                        .old_uri
 3284                        .to_file_path()
 3285                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3286                    let target_abs_path = op
 3287                        .new_uri
 3288                        .to_file_path()
 3289                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3290
 3291                    let options = fs::RenameOptions {
 3292                        overwrite: op
 3293                            .options
 3294                            .as_ref()
 3295                            .and_then(|options| options.overwrite)
 3296                            .unwrap_or(false),
 3297                        ignore_if_exists: op
 3298                            .options
 3299                            .as_ref()
 3300                            .and_then(|options| options.ignore_if_exists)
 3301                            .unwrap_or(false),
 3302                        create_parents: true,
 3303                    };
 3304
 3305                    fs.rename(&source_abs_path, &target_abs_path, options)
 3306                        .await?;
 3307                }
 3308
 3309                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3310                    let abs_path = op
 3311                        .uri
 3312                        .to_file_path()
 3313                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3314                    let options = op
 3315                        .options
 3316                        .map(|options| fs::RemoveOptions {
 3317                            recursive: options.recursive.unwrap_or(false),
 3318                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3319                        })
 3320                        .unwrap_or_default();
 3321                    if abs_path.ends_with("/") {
 3322                        fs.remove_dir(&abs_path, options).await?;
 3323                    } else {
 3324                        fs.remove_file(&abs_path, options).await?;
 3325                    }
 3326                }
 3327
 3328                lsp::DocumentChangeOperation::Edit(op) => {
 3329                    let buffer_to_edit = this
 3330                        .update(cx, |this, cx| {
 3331                            this.open_local_buffer_via_lsp(
 3332                                op.text_document.uri.clone(),
 3333                                language_server.server_id(),
 3334                                cx,
 3335                            )
 3336                        })
 3337                        .await?;
 3338
 3339                    let edits = this
 3340                        .update(cx, |this, cx| {
 3341                            let path = buffer_to_edit.read(cx).project_path(cx);
 3342                            let active_entry = this.active_entry;
 3343                            let is_active_entry = path.is_some_and(|project_path| {
 3344                                this.worktree_store
 3345                                    .read(cx)
 3346                                    .entry_for_path(&project_path, cx)
 3347                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3348                            });
 3349                            let local = this.as_local_mut().unwrap();
 3350
 3351                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3352                            for edit in op.edits {
 3353                                match edit {
 3354                                    Edit::Plain(edit) => {
 3355                                        if !edits.contains(&edit) {
 3356                                            edits.push(edit)
 3357                                        }
 3358                                    }
 3359                                    Edit::Annotated(edit) => {
 3360                                        if !edits.contains(&edit.text_edit) {
 3361                                            edits.push(edit.text_edit)
 3362                                        }
 3363                                    }
 3364                                    Edit::Snippet(edit) => {
 3365                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3366                                        else {
 3367                                            continue;
 3368                                        };
 3369
 3370                                        if is_active_entry {
 3371                                            snippet_edits.push((edit.range, snippet));
 3372                                        } else {
 3373                                            // Since this buffer is not focused, apply a normal edit.
 3374                                            let new_edit = TextEdit {
 3375                                                range: edit.range,
 3376                                                new_text: snippet.text,
 3377                                            };
 3378                                            if !edits.contains(&new_edit) {
 3379                                                edits.push(new_edit);
 3380                                            }
 3381                                        }
 3382                                    }
 3383                                }
 3384                            }
 3385                            if !snippet_edits.is_empty() {
 3386                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3387                                let version = if let Some(buffer_version) = op.text_document.version
 3388                                {
 3389                                    local
 3390                                        .buffer_snapshot_for_lsp_version(
 3391                                            &buffer_to_edit,
 3392                                            language_server.server_id(),
 3393                                            Some(buffer_version),
 3394                                            cx,
 3395                                        )
 3396                                        .ok()
 3397                                        .map(|snapshot| snapshot.version)
 3398                                } else {
 3399                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3400                                };
 3401
 3402                                let most_recent_edit =
 3403                                    version.and_then(|version| version.most_recent());
 3404                                // Check if the edit that triggered that edit has been made by this participant.
 3405
 3406                                if let Some(most_recent_edit) = most_recent_edit {
 3407                                    cx.emit(LspStoreEvent::SnippetEdit {
 3408                                        buffer_id,
 3409                                        edits: snippet_edits,
 3410                                        most_recent_edit,
 3411                                    });
 3412                                }
 3413                            }
 3414
 3415                            local.edits_from_lsp(
 3416                                &buffer_to_edit,
 3417                                edits,
 3418                                language_server.server_id(),
 3419                                op.text_document.version,
 3420                                cx,
 3421                            )
 3422                        })
 3423                        .await?;
 3424
 3425                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3426                        buffer.finalize_last_transaction();
 3427                        buffer.start_transaction();
 3428                        for (range, text) in edits {
 3429                            buffer.edit([(range, text)], None, cx);
 3430                        }
 3431
 3432                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3433                            if push_to_history {
 3434                                buffer.finalize_last_transaction();
 3435                                buffer.get_transaction(transaction_id).cloned()
 3436                            } else {
 3437                                buffer.forget_transaction(transaction_id)
 3438                            }
 3439                        })
 3440                    });
 3441                    if let Some(transaction) = transaction {
 3442                        project_transaction.0.insert(buffer_to_edit, transaction);
 3443                    }
 3444                }
 3445            }
 3446        }
 3447
 3448        Ok(project_transaction)
 3449    }
 3450
 3451    async fn on_lsp_workspace_edit(
 3452        this: WeakEntity<LspStore>,
 3453        params: lsp::ApplyWorkspaceEditParams,
 3454        server_id: LanguageServerId,
 3455        cx: &mut AsyncApp,
 3456    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3457        let this = this.upgrade().context("project project closed")?;
 3458        let language_server = this
 3459            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3460            .context("language server not found")?;
 3461        let transaction = Self::deserialize_workspace_edit(
 3462            this.clone(),
 3463            params.edit,
 3464            true,
 3465            language_server.clone(),
 3466            cx,
 3467        )
 3468        .await
 3469        .log_err();
 3470        this.update(cx, |this, cx| {
 3471            if let Some(transaction) = transaction {
 3472                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3473
 3474                this.as_local_mut()
 3475                    .unwrap()
 3476                    .last_workspace_edits_by_language_server
 3477                    .insert(server_id, transaction);
 3478            }
 3479        });
 3480        Ok(lsp::ApplyWorkspaceEditResponse {
 3481            applied: true,
 3482            failed_change: None,
 3483            failure_reason: None,
 3484        })
 3485    }
 3486
 3487    fn remove_worktree(
 3488        &mut self,
 3489        id_to_remove: WorktreeId,
 3490        cx: &mut Context<LspStore>,
 3491    ) -> Vec<LanguageServerId> {
 3492        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3493        self.diagnostics.remove(&id_to_remove);
 3494        self.prettier_store.update(cx, |prettier_store, cx| {
 3495            prettier_store.remove_worktree(id_to_remove, cx);
 3496        });
 3497
 3498        let mut servers_to_remove = BTreeSet::default();
 3499        let mut servers_to_preserve = HashSet::default();
 3500        for (seed, state) in &self.language_server_ids {
 3501            if seed.worktree_id == id_to_remove {
 3502                servers_to_remove.insert(state.id);
 3503            } else {
 3504                servers_to_preserve.insert(state.id);
 3505            }
 3506        }
 3507        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3508        self.language_server_ids
 3509            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3510        for server_id_to_remove in &servers_to_remove {
 3511            self.language_server_watched_paths
 3512                .remove(server_id_to_remove);
 3513            self.language_server_paths_watched_for_rename
 3514                .remove(server_id_to_remove);
 3515            self.last_workspace_edits_by_language_server
 3516                .remove(server_id_to_remove);
 3517            self.language_servers.remove(server_id_to_remove);
 3518            self.buffer_pull_diagnostics_result_ids
 3519                .remove(server_id_to_remove);
 3520            self.workspace_pull_diagnostics_result_ids
 3521                .remove(server_id_to_remove);
 3522            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3523                buffer_servers.remove(server_id_to_remove);
 3524            }
 3525            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3526        }
 3527        servers_to_remove.into_iter().collect()
 3528    }
 3529
 3530    fn build_watched_paths_registration(
 3531        &self,
 3532        language_server_id: LanguageServerId,
 3533        watchers: &[FileSystemWatcher],
 3534        cx: &mut Context<LspStore>,
 3535    ) -> WatchedPathsRegistration {
 3536        let worktrees = self
 3537            .worktree_store
 3538            .read(cx)
 3539            .worktrees()
 3540            .filter_map(|worktree| {
 3541                self.language_servers_for_worktree(worktree.read(cx).id())
 3542                    .find(|server| server.server_id() == language_server_id)
 3543                    .map(|_| worktree)
 3544            })
 3545            .collect::<Vec<_>>();
 3546
 3547        let mut worktree_globs = HashMap::default();
 3548        let mut abs_globs = HashMap::default();
 3549        log::trace!(
 3550            "Processing new watcher paths for language server with id {}",
 3551            language_server_id
 3552        );
 3553
 3554        for watcher in watchers {
 3555            if let Some((worktree, literal_prefix, pattern)) =
 3556                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3557            {
 3558                worktree.update(cx, |worktree, _| {
 3559                    if let Some((tree, glob)) =
 3560                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3561                    {
 3562                        tree.add_path_prefix_to_scan(literal_prefix);
 3563                        worktree_globs
 3564                            .entry(tree.id())
 3565                            .or_insert_with(GlobSetBuilder::new)
 3566                            .add(glob);
 3567                    }
 3568                });
 3569            } else {
 3570                let (path, pattern) = match &watcher.glob_pattern {
 3571                    lsp::GlobPattern::String(s) => {
 3572                        let watcher_path = SanitizedPath::new(s);
 3573                        let path = glob_literal_prefix(watcher_path.as_path());
 3574                        let pattern = watcher_path
 3575                            .as_path()
 3576                            .strip_prefix(&path)
 3577                            .map(|p| p.to_string_lossy().into_owned())
 3578                            .unwrap_or_else(|e| {
 3579                                debug_panic!(
 3580                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3581                                    s,
 3582                                    path.display(),
 3583                                    e
 3584                                );
 3585                                watcher_path.as_path().to_string_lossy().into_owned()
 3586                            });
 3587                        (path, pattern)
 3588                    }
 3589                    lsp::GlobPattern::Relative(rp) => {
 3590                        let Ok(mut base_uri) = match &rp.base_uri {
 3591                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3592                            lsp::OneOf::Right(base_uri) => base_uri,
 3593                        }
 3594                        .to_file_path() else {
 3595                            continue;
 3596                        };
 3597
 3598                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3599                        let pattern = Path::new(&rp.pattern)
 3600                            .strip_prefix(&path)
 3601                            .map(|p| p.to_string_lossy().into_owned())
 3602                            .unwrap_or_else(|e| {
 3603                                debug_panic!(
 3604                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3605                                    rp.pattern,
 3606                                    path.display(),
 3607                                    e
 3608                                );
 3609                                rp.pattern.clone()
 3610                            });
 3611                        base_uri.push(path);
 3612                        (base_uri, pattern)
 3613                    }
 3614                };
 3615
 3616                if let Some(glob) = Glob::new(&pattern).log_err() {
 3617                    if !path
 3618                        .components()
 3619                        .any(|c| matches!(c, path::Component::Normal(_)))
 3620                    {
 3621                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3622                        // rather than adding a new watcher for `/`.
 3623                        for worktree in &worktrees {
 3624                            worktree_globs
 3625                                .entry(worktree.read(cx).id())
 3626                                .or_insert_with(GlobSetBuilder::new)
 3627                                .add(glob.clone());
 3628                        }
 3629                    } else {
 3630                        abs_globs
 3631                            .entry(path.into())
 3632                            .or_insert_with(GlobSetBuilder::new)
 3633                            .add(glob);
 3634                    }
 3635                }
 3636            }
 3637        }
 3638
 3639        let worktree_globs = worktree_globs
 3640            .into_iter()
 3641            .filter_map(|(worktree_id, builder)| builder.build().ok().map(|gs| (worktree_id, gs)))
 3642            .collect();
 3643
 3644        let lsp_store = self.weak.clone();
 3645        let fs = self.fs.clone();
 3646        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
 3647
 3648        let abs_path_watchers = abs_globs
 3649            .into_iter()
 3650            .filter_map(|(abs_path, builder): (Arc<Path>, _)| {
 3651                let globset = builder.build().ok()?;
 3652                let task = cx.spawn({
 3653                    let fs = fs.clone();
 3654                    let lsp_store = lsp_store.clone();
 3655                    async move |_, cx| {
 3656                        maybe!(async move {
 3657                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
 3658                            while let Some(update) = push_updates.0.next().await {
 3659                                let matching_entries: Vec<_> = update
 3660                                    .into_iter()
 3661                                    .filter(|event| globset.is_match(&event.path))
 3662                                    .collect();
 3663                                if matching_entries.is_empty() {
 3664                                    continue;
 3665                                }
 3666                                lsp_store
 3667                                    .update(cx, |this, _| {
 3668                                        this.lsp_notify_abs_paths_changed(
 3669                                            language_server_id,
 3670                                            matching_entries,
 3671                                        );
 3672                                    })
 3673                                    .ok()?;
 3674                            }
 3675                            Some(())
 3676                        })
 3677                        .await;
 3678                    }
 3679                });
 3680                Some(task)
 3681            })
 3682            .collect();
 3683
 3684        WatchedPathsRegistration {
 3685            worktree_globs,
 3686            _abs_path_watchers: abs_path_watchers,
 3687        }
 3688    }
 3689
 3690    fn worktree_and_path_for_file_watcher(
 3691        worktrees: &[Entity<Worktree>],
 3692        watcher: &FileSystemWatcher,
 3693        cx: &App,
 3694    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3695        worktrees.iter().find_map(|worktree| {
 3696            let tree = worktree.read(cx);
 3697            let worktree_root_path = tree.abs_path();
 3698            let path_style = tree.path_style();
 3699            match &watcher.glob_pattern {
 3700                lsp::GlobPattern::String(s) => {
 3701                    let watcher_path = SanitizedPath::new(s);
 3702                    let relative = watcher_path
 3703                        .as_path()
 3704                        .strip_prefix(&worktree_root_path)
 3705                        .ok()?;
 3706                    let literal_prefix = glob_literal_prefix(relative);
 3707                    Some((
 3708                        worktree.clone(),
 3709                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3710                        relative.to_string_lossy().into_owned(),
 3711                    ))
 3712                }
 3713                lsp::GlobPattern::Relative(rp) => {
 3714                    let base_uri = match &rp.base_uri {
 3715                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3716                        lsp::OneOf::Right(base_uri) => base_uri,
 3717                    }
 3718                    .to_file_path()
 3719                    .ok()?;
 3720                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3721                    let mut literal_prefix = relative.to_owned();
 3722                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3723                    Some((
 3724                        worktree.clone(),
 3725                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3726                        rp.pattern.clone(),
 3727                    ))
 3728                }
 3729            }
 3730        })
 3731    }
 3732
 3733    fn on_lsp_did_change_watched_files(
 3734        &mut self,
 3735        language_server_id: LanguageServerId,
 3736        registration_id: &str,
 3737        params: DidChangeWatchedFilesRegistrationOptions,
 3738        cx: &mut Context<LspStore>,
 3739    ) {
 3740        let registration =
 3741            self.build_watched_paths_registration(language_server_id, &params.watchers, cx);
 3742
 3743        self.language_server_dynamic_registrations
 3744            .entry(language_server_id)
 3745            .or_default()
 3746            .did_change_watched_files
 3747            .insert(registration_id.to_string(), params.watchers);
 3748
 3749        self.language_server_watched_paths
 3750            .entry(language_server_id)
 3751            .or_default()
 3752            .registrations
 3753            .insert(registration_id.to_string(), registration);
 3754
 3755        cx.notify();
 3756    }
 3757
 3758    fn on_lsp_unregister_did_change_watched_files(
 3759        &mut self,
 3760        language_server_id: LanguageServerId,
 3761        registration_id: &str,
 3762        cx: &mut Context<LspStore>,
 3763    ) {
 3764        let registrations = self
 3765            .language_server_dynamic_registrations
 3766            .entry(language_server_id)
 3767            .or_default();
 3768
 3769        if registrations
 3770            .did_change_watched_files
 3771            .remove(registration_id)
 3772            .is_some()
 3773        {
 3774            log::info!(
 3775                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3776                language_server_id,
 3777                registration_id
 3778            );
 3779        } else {
 3780            log::warn!(
 3781                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3782                language_server_id,
 3783                registration_id
 3784            );
 3785        }
 3786
 3787        if let Some(watched_paths) = self
 3788            .language_server_watched_paths
 3789            .get_mut(&language_server_id)
 3790        {
 3791            watched_paths.registrations.remove(registration_id);
 3792        }
 3793
 3794        cx.notify();
 3795    }
 3796
 3797    async fn initialization_options_for_adapter(
 3798        adapter: Arc<dyn LspAdapter>,
 3799        delegate: &Arc<dyn LspAdapterDelegate>,
 3800    ) -> Result<Option<serde_json::Value>> {
 3801        let Some(mut initialization_config) =
 3802            adapter.clone().initialization_options(delegate).await?
 3803        else {
 3804            return Ok(None);
 3805        };
 3806
 3807        for other_adapter in delegate.registered_lsp_adapters() {
 3808            if other_adapter.name() == adapter.name() {
 3809                continue;
 3810            }
 3811            if let Ok(Some(target_config)) = other_adapter
 3812                .clone()
 3813                .additional_initialization_options(adapter.name(), delegate)
 3814                .await
 3815            {
 3816                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3817            }
 3818        }
 3819
 3820        Ok(Some(initialization_config))
 3821    }
 3822
 3823    async fn workspace_configuration_for_adapter(
 3824        adapter: Arc<dyn LspAdapter>,
 3825        delegate: &Arc<dyn LspAdapterDelegate>,
 3826        toolchain: Option<Toolchain>,
 3827        requested_uri: Option<Uri>,
 3828        cx: &mut AsyncApp,
 3829    ) -> Result<serde_json::Value> {
 3830        let mut workspace_config = adapter
 3831            .clone()
 3832            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3833            .await?;
 3834
 3835        for other_adapter in delegate.registered_lsp_adapters() {
 3836            if other_adapter.name() == adapter.name() {
 3837                continue;
 3838            }
 3839            if let Ok(Some(target_config)) = other_adapter
 3840                .clone()
 3841                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3842                .await
 3843            {
 3844                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3845            }
 3846        }
 3847
 3848        Ok(workspace_config)
 3849    }
 3850
 3851    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3852        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3853            Some(server.clone())
 3854        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3855            Some(Arc::clone(server))
 3856        } else {
 3857            None
 3858        }
 3859    }
 3860}
 3861
 3862fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3863    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3864        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3865            language_server_id: server.server_id(),
 3866            name: Some(server.name()),
 3867            message: proto::update_language_server::Variant::MetadataUpdated(
 3868                proto::ServerMetadataUpdated {
 3869                    capabilities: Some(capabilities),
 3870                    binary: Some(proto::LanguageServerBinaryInfo {
 3871                        path: server.binary().path.to_string_lossy().into_owned(),
 3872                        arguments: server
 3873                            .binary()
 3874                            .arguments
 3875                            .iter()
 3876                            .map(|arg| arg.to_string_lossy().into_owned())
 3877                            .collect(),
 3878                    }),
 3879                    configuration: serde_json::to_string(server.configuration()).ok(),
 3880                    workspace_folders: server
 3881                        .workspace_folders()
 3882                        .iter()
 3883                        .map(|uri| uri.to_string())
 3884                        .collect(),
 3885                },
 3886            ),
 3887        });
 3888    }
 3889}
 3890
 3891#[derive(Debug)]
 3892pub struct FormattableBuffer {
 3893    handle: Entity<Buffer>,
 3894    abs_path: Option<PathBuf>,
 3895    env: Option<HashMap<String, String>>,
 3896    ranges: Option<Vec<Range<Anchor>>>,
 3897}
 3898
 3899pub struct RemoteLspStore {
 3900    upstream_client: Option<AnyProtoClient>,
 3901    upstream_project_id: u64,
 3902}
 3903
 3904pub(crate) enum LspStoreMode {
 3905    Local(LocalLspStore),   // ssh host and collab host
 3906    Remote(RemoteLspStore), // collab guest
 3907}
 3908
 3909impl LspStoreMode {
 3910    fn is_local(&self) -> bool {
 3911        matches!(self, LspStoreMode::Local(_))
 3912    }
 3913}
 3914
 3915pub struct LspStore {
 3916    mode: LspStoreMode,
 3917    last_formatting_failure: Option<String>,
 3918    downstream_client: Option<(AnyProtoClient, u64)>,
 3919    nonce: u128,
 3920    buffer_store: Entity<BufferStore>,
 3921    worktree_store: Entity<WorktreeStore>,
 3922    pub languages: Arc<LanguageRegistry>,
 3923    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3924    active_entry: Option<ProjectEntryId>,
 3925    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3926    _maintain_buffer_languages: Task<()>,
 3927    diagnostic_summaries:
 3928        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3929    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3930    semantic_token_config: SemanticTokenConfig,
 3931    lsp_data: HashMap<BufferId, BufferLspData>,
 3932    next_hint_id: Arc<AtomicUsize>,
 3933}
 3934
 3935#[derive(Debug)]
 3936pub struct BufferLspData {
 3937    buffer_version: Global,
 3938    document_colors: Option<DocumentColorData>,
 3939    code_lens: Option<CodeLensData>,
 3940    semantic_tokens: Option<SemanticTokensData>,
 3941    folding_ranges: Option<FoldingRangeData>,
 3942    document_symbols: Option<DocumentSymbolsData>,
 3943    inlay_hints: BufferInlayHints,
 3944    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3945    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3946}
 3947
 3948#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3949struct LspKey {
 3950    request_type: TypeId,
 3951    server_queried: Option<LanguageServerId>,
 3952}
 3953
 3954impl BufferLspData {
 3955    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3956        Self {
 3957            buffer_version: buffer.read(cx).version(),
 3958            document_colors: None,
 3959            code_lens: None,
 3960            semantic_tokens: None,
 3961            folding_ranges: None,
 3962            document_symbols: None,
 3963            inlay_hints: BufferInlayHints::new(buffer, cx),
 3964            lsp_requests: HashMap::default(),
 3965            chunk_lsp_requests: HashMap::default(),
 3966        }
 3967    }
 3968
 3969    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3970        if let Some(document_colors) = &mut self.document_colors {
 3971            document_colors.remove_server_data(for_server);
 3972        }
 3973
 3974        if let Some(code_lens) = &mut self.code_lens {
 3975            code_lens.remove_server_data(for_server);
 3976        }
 3977
 3978        self.inlay_hints.remove_server_data(for_server);
 3979
 3980        if let Some(semantic_tokens) = &mut self.semantic_tokens {
 3981            semantic_tokens.raw_tokens.servers.remove(&for_server);
 3982            semantic_tokens
 3983                .latest_invalidation_requests
 3984                .remove(&for_server);
 3985        }
 3986
 3987        if let Some(folding_ranges) = &mut self.folding_ranges {
 3988            folding_ranges.ranges.remove(&for_server);
 3989        }
 3990
 3991        if let Some(document_symbols) = &mut self.document_symbols {
 3992            document_symbols.remove_server_data(for_server);
 3993        }
 3994    }
 3995
 3996    #[cfg(any(test, feature = "test-support"))]
 3997    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3998        &self.inlay_hints
 3999    }
 4000}
 4001
 4002#[derive(Debug)]
 4003pub enum LspStoreEvent {
 4004    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 4005    LanguageServerRemoved(LanguageServerId),
 4006    LanguageServerUpdate {
 4007        language_server_id: LanguageServerId,
 4008        name: Option<LanguageServerName>,
 4009        message: proto::update_language_server::Variant,
 4010    },
 4011    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 4012    LanguageServerPrompt(LanguageServerPromptRequest),
 4013    LanguageDetected {
 4014        buffer: Entity<Buffer>,
 4015        new_language: Option<Arc<Language>>,
 4016    },
 4017    Notification(String),
 4018    RefreshInlayHints {
 4019        server_id: LanguageServerId,
 4020        request_id: Option<usize>,
 4021    },
 4022    RefreshSemanticTokens {
 4023        server_id: LanguageServerId,
 4024        request_id: Option<usize>,
 4025    },
 4026    RefreshCodeLens,
 4027    DiagnosticsUpdated {
 4028        server_id: LanguageServerId,
 4029        paths: Vec<ProjectPath>,
 4030    },
 4031    DiskBasedDiagnosticsStarted {
 4032        language_server_id: LanguageServerId,
 4033    },
 4034    DiskBasedDiagnosticsFinished {
 4035        language_server_id: LanguageServerId,
 4036    },
 4037    SnippetEdit {
 4038        buffer_id: BufferId,
 4039        edits: Vec<(lsp::Range, Snippet)>,
 4040        most_recent_edit: clock::Lamport,
 4041    },
 4042    WorkspaceEditApplied(ProjectTransaction),
 4043}
 4044
 4045#[derive(Clone, Debug, Serialize)]
 4046pub struct LanguageServerStatus {
 4047    pub name: LanguageServerName,
 4048    pub server_version: Option<SharedString>,
 4049    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 4050    pub has_pending_diagnostic_updates: bool,
 4051    pub progress_tokens: HashSet<ProgressToken>,
 4052    pub worktree: Option<WorktreeId>,
 4053    pub binary: Option<LanguageServerBinary>,
 4054    pub configuration: Option<Value>,
 4055    pub workspace_folders: BTreeSet<Uri>,
 4056    pub process_id: Option<u32>,
 4057}
 4058
 4059#[derive(Clone, Debug)]
 4060struct CoreSymbol {
 4061    pub language_server_name: LanguageServerName,
 4062    pub source_worktree_id: WorktreeId,
 4063    pub source_language_server_id: LanguageServerId,
 4064    pub path: SymbolLocation,
 4065    pub name: String,
 4066    pub kind: lsp::SymbolKind,
 4067    pub range: Range<Unclipped<PointUtf16>>,
 4068    pub container_name: Option<String>,
 4069}
 4070
 4071#[derive(Clone, Debug, PartialEq, Eq)]
 4072pub enum SymbolLocation {
 4073    InProject(ProjectPath),
 4074    OutsideProject {
 4075        abs_path: Arc<Path>,
 4076        signature: [u8; 32],
 4077    },
 4078}
 4079
 4080impl SymbolLocation {
 4081    fn file_name(&self) -> Option<&str> {
 4082        match self {
 4083            Self::InProject(path) => path.path.file_name(),
 4084            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 4085        }
 4086    }
 4087}
 4088
 4089impl LspStore {
 4090    pub fn init(client: &AnyProtoClient) {
 4091        client.add_entity_request_handler(Self::handle_lsp_query);
 4092        client.add_entity_message_handler(Self::handle_lsp_query_response);
 4093        client.add_entity_request_handler(Self::handle_restart_language_servers);
 4094        client.add_entity_request_handler(Self::handle_stop_language_servers);
 4095        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 4096        client.add_entity_message_handler(Self::handle_start_language_server);
 4097        client.add_entity_message_handler(Self::handle_update_language_server);
 4098        client.add_entity_message_handler(Self::handle_language_server_log);
 4099        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 4100        client.add_entity_request_handler(Self::handle_format_buffers);
 4101        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 4102        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 4103        client.add_entity_request_handler(Self::handle_apply_code_action);
 4104        client.add_entity_request_handler(Self::handle_get_project_symbols);
 4105        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 4106        client.add_entity_request_handler(Self::handle_get_color_presentation);
 4107        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 4108        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 4109        client.add_entity_request_handler(Self::handle_refresh_semantic_tokens);
 4110        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 4111        client.add_entity_request_handler(Self::handle_on_type_formatting);
 4112        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 4113        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 4114        client.add_entity_request_handler(Self::handle_rename_project_entry);
 4115        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 4116        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 4117        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 4118        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 4119        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 4120        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 4121        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 4122
 4123        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 4124        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 4125        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 4126        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 4127        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 4128        client.add_entity_request_handler(
 4129            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 4130        );
 4131        client.add_entity_request_handler(
 4132            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 4133        );
 4134        client.add_entity_request_handler(
 4135            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 4136        );
 4137    }
 4138
 4139    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 4140        match &self.mode {
 4141            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 4142            _ => None,
 4143        }
 4144    }
 4145
 4146    pub fn as_local(&self) -> Option<&LocalLspStore> {
 4147        match &self.mode {
 4148            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4149            _ => None,
 4150        }
 4151    }
 4152
 4153    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 4154        match &mut self.mode {
 4155            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4156            _ => None,
 4157        }
 4158    }
 4159
 4160    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4161        match &self.mode {
 4162            LspStoreMode::Remote(RemoteLspStore {
 4163                upstream_client: Some(upstream_client),
 4164                upstream_project_id,
 4165                ..
 4166            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4167
 4168            LspStoreMode::Remote(RemoteLspStore {
 4169                upstream_client: None,
 4170                ..
 4171            }) => None,
 4172            LspStoreMode::Local(_) => None,
 4173        }
 4174    }
 4175
 4176    pub fn new_local(
 4177        buffer_store: Entity<BufferStore>,
 4178        worktree_store: Entity<WorktreeStore>,
 4179        prettier_store: Entity<PrettierStore>,
 4180        toolchain_store: Entity<LocalToolchainStore>,
 4181        environment: Entity<ProjectEnvironment>,
 4182        manifest_tree: Entity<ManifestTree>,
 4183        languages: Arc<LanguageRegistry>,
 4184        http_client: Arc<dyn HttpClient>,
 4185        fs: Arc<dyn Fs>,
 4186        cx: &mut Context<Self>,
 4187    ) -> Self {
 4188        let yarn = YarnPathStore::new(fs.clone(), cx);
 4189        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4190            .detach();
 4191        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4192            .detach();
 4193        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4194            .detach();
 4195        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4196            .detach();
 4197        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4198            .detach();
 4199        subscribe_to_binary_statuses(&languages, cx).detach();
 4200
 4201        let _maintain_workspace_config = {
 4202            let (sender, receiver) = watch::channel();
 4203            (Self::maintain_workspace_config(receiver, cx), sender)
 4204        };
 4205
 4206        Self {
 4207            mode: LspStoreMode::Local(LocalLspStore {
 4208                weak: cx.weak_entity(),
 4209                worktree_store: worktree_store.clone(),
 4210
 4211                supplementary_language_servers: Default::default(),
 4212                languages: languages.clone(),
 4213                language_server_ids: Default::default(),
 4214                language_servers: Default::default(),
 4215                last_workspace_edits_by_language_server: Default::default(),
 4216                language_server_watched_paths: Default::default(),
 4217                language_server_paths_watched_for_rename: Default::default(),
 4218                language_server_dynamic_registrations: Default::default(),
 4219                buffers_being_formatted: Default::default(),
 4220                buffers_to_refresh_hash_set: HashSet::default(),
 4221                buffers_to_refresh_queue: VecDeque::new(),
 4222                _background_diagnostics_worker: Task::ready(()).shared(),
 4223                buffer_snapshots: Default::default(),
 4224                prettier_store,
 4225                environment,
 4226                http_client,
 4227                fs,
 4228                yarn,
 4229                next_diagnostic_group_id: Default::default(),
 4230                diagnostics: Default::default(),
 4231                _subscription: cx.on_app_quit(|this, _| {
 4232                    this.as_local_mut()
 4233                        .unwrap()
 4234                        .shutdown_language_servers_on_quit()
 4235                }),
 4236                lsp_tree: LanguageServerTree::new(
 4237                    manifest_tree,
 4238                    languages.clone(),
 4239                    toolchain_store.clone(),
 4240                ),
 4241                toolchain_store,
 4242                registered_buffers: HashMap::default(),
 4243                buffers_opened_in_servers: HashMap::default(),
 4244                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4245                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4246                restricted_worktrees_tasks: HashMap::default(),
 4247                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4248                    .manifest_file_names(),
 4249            }),
 4250            last_formatting_failure: None,
 4251            downstream_client: None,
 4252            buffer_store,
 4253            worktree_store,
 4254            languages: languages.clone(),
 4255            language_server_statuses: Default::default(),
 4256            nonce: StdRng::from_os_rng().random(),
 4257            diagnostic_summaries: HashMap::default(),
 4258            lsp_server_capabilities: HashMap::default(),
 4259            semantic_token_config: SemanticTokenConfig::new(cx),
 4260            lsp_data: HashMap::default(),
 4261            next_hint_id: Arc::default(),
 4262            active_entry: None,
 4263            _maintain_workspace_config,
 4264            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4265        }
 4266    }
 4267
 4268    fn send_lsp_proto_request<R: LspCommand>(
 4269        &self,
 4270        buffer: Entity<Buffer>,
 4271        client: AnyProtoClient,
 4272        upstream_project_id: u64,
 4273        request: R,
 4274        cx: &mut Context<LspStore>,
 4275    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4276        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4277            return Task::ready(Ok(R::Response::default()));
 4278        }
 4279        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4280        cx.spawn(async move |this, cx| {
 4281            let response = client.request(message).await?;
 4282            let this = this.upgrade().context("project dropped")?;
 4283            request
 4284                .response_from_proto(response, this, buffer, cx.clone())
 4285                .await
 4286        })
 4287    }
 4288
 4289    pub(super) fn new_remote(
 4290        buffer_store: Entity<BufferStore>,
 4291        worktree_store: Entity<WorktreeStore>,
 4292        languages: Arc<LanguageRegistry>,
 4293        upstream_client: AnyProtoClient,
 4294        project_id: u64,
 4295        cx: &mut Context<Self>,
 4296    ) -> Self {
 4297        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4298            .detach();
 4299        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4300            .detach();
 4301        subscribe_to_binary_statuses(&languages, cx).detach();
 4302        let _maintain_workspace_config = {
 4303            let (sender, receiver) = watch::channel();
 4304            (Self::maintain_workspace_config(receiver, cx), sender)
 4305        };
 4306        Self {
 4307            mode: LspStoreMode::Remote(RemoteLspStore {
 4308                upstream_client: Some(upstream_client),
 4309                upstream_project_id: project_id,
 4310            }),
 4311            downstream_client: None,
 4312            last_formatting_failure: None,
 4313            buffer_store,
 4314            worktree_store,
 4315            languages: languages.clone(),
 4316            language_server_statuses: Default::default(),
 4317            nonce: StdRng::from_os_rng().random(),
 4318            diagnostic_summaries: HashMap::default(),
 4319            lsp_server_capabilities: HashMap::default(),
 4320            semantic_token_config: SemanticTokenConfig::new(cx),
 4321            next_hint_id: Arc::default(),
 4322            lsp_data: HashMap::default(),
 4323            active_entry: None,
 4324
 4325            _maintain_workspace_config,
 4326            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4327        }
 4328    }
 4329
 4330    fn on_buffer_store_event(
 4331        &mut self,
 4332        _: Entity<BufferStore>,
 4333        event: &BufferStoreEvent,
 4334        cx: &mut Context<Self>,
 4335    ) {
 4336        match event {
 4337            BufferStoreEvent::BufferAdded(buffer) => {
 4338                self.on_buffer_added(buffer, cx).log_err();
 4339            }
 4340            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4341                let buffer_id = buffer.read(cx).remote_id();
 4342                if let Some(local) = self.as_local_mut()
 4343                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4344                {
 4345                    local.reset_buffer(buffer, old_file, cx);
 4346
 4347                    if local.registered_buffers.contains_key(&buffer_id) {
 4348                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4349                    }
 4350                }
 4351
 4352                self.detect_language_for_buffer(buffer, cx);
 4353                if let Some(local) = self.as_local_mut() {
 4354                    local.initialize_buffer(buffer, cx);
 4355                    if local.registered_buffers.contains_key(&buffer_id) {
 4356                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4357                    }
 4358                }
 4359            }
 4360            _ => {}
 4361        }
 4362    }
 4363
 4364    fn on_worktree_store_event(
 4365        &mut self,
 4366        _: Entity<WorktreeStore>,
 4367        event: &WorktreeStoreEvent,
 4368        cx: &mut Context<Self>,
 4369    ) {
 4370        match event {
 4371            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4372                if !worktree.read(cx).is_local() {
 4373                    return;
 4374                }
 4375                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4376                    worktree::Event::UpdatedEntries(changes) => {
 4377                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4378                    }
 4379                    worktree::Event::UpdatedGitRepositories(_)
 4380                    | worktree::Event::DeletedEntry(_) => {}
 4381                })
 4382                .detach()
 4383            }
 4384            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4385            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4386                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4387            }
 4388            WorktreeStoreEvent::WorktreeReleased(..)
 4389            | WorktreeStoreEvent::WorktreeOrderChanged
 4390            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4391            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4392            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4393        }
 4394    }
 4395
 4396    fn on_prettier_store_event(
 4397        &mut self,
 4398        _: Entity<PrettierStore>,
 4399        event: &PrettierStoreEvent,
 4400        cx: &mut Context<Self>,
 4401    ) {
 4402        match event {
 4403            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4404                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4405            }
 4406            PrettierStoreEvent::LanguageServerAdded {
 4407                new_server_id,
 4408                name,
 4409                prettier_server,
 4410            } => {
 4411                self.register_supplementary_language_server(
 4412                    *new_server_id,
 4413                    name.clone(),
 4414                    prettier_server.clone(),
 4415                    cx,
 4416                );
 4417            }
 4418        }
 4419    }
 4420
 4421    fn on_toolchain_store_event(
 4422        &mut self,
 4423        _: Entity<LocalToolchainStore>,
 4424        event: &ToolchainStoreEvent,
 4425        _: &mut Context<Self>,
 4426    ) {
 4427        if let ToolchainStoreEvent::ToolchainActivated = event {
 4428            self.request_workspace_config_refresh()
 4429        }
 4430    }
 4431
 4432    fn request_workspace_config_refresh(&mut self) {
 4433        *self._maintain_workspace_config.1.borrow_mut() = ();
 4434    }
 4435
 4436    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4437        self.as_local().map(|local| local.prettier_store.clone())
 4438    }
 4439
 4440    fn on_buffer_event(
 4441        &mut self,
 4442        buffer: Entity<Buffer>,
 4443        event: &language::BufferEvent,
 4444        cx: &mut Context<Self>,
 4445    ) {
 4446        match event {
 4447            language::BufferEvent::Edited => {
 4448                self.on_buffer_edited(buffer, cx);
 4449            }
 4450
 4451            language::BufferEvent::Saved => {
 4452                self.on_buffer_saved(buffer, cx);
 4453            }
 4454
 4455            _ => {}
 4456        }
 4457    }
 4458
 4459    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4460        buffer
 4461            .read(cx)
 4462            .set_language_registry(self.languages.clone());
 4463
 4464        cx.subscribe(buffer, |this, buffer, event, cx| {
 4465            this.on_buffer_event(buffer, event, cx);
 4466        })
 4467        .detach();
 4468
 4469        self.detect_language_for_buffer(buffer, cx);
 4470        if let Some(local) = self.as_local_mut() {
 4471            local.initialize_buffer(buffer, cx);
 4472        }
 4473
 4474        Ok(())
 4475    }
 4476
 4477    pub fn refresh_background_diagnostics_for_buffers(
 4478        &mut self,
 4479        buffers: HashSet<BufferId>,
 4480        cx: &mut Context<Self>,
 4481    ) -> Shared<Task<()>> {
 4482        let Some(local) = self.as_local_mut() else {
 4483            return Task::ready(()).shared();
 4484        };
 4485        for buffer in buffers {
 4486            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4487                local.buffers_to_refresh_queue.push_back(buffer);
 4488                if local.buffers_to_refresh_queue.len() == 1 {
 4489                    local._background_diagnostics_worker =
 4490                        Self::background_diagnostics_worker(cx).shared();
 4491                }
 4492            }
 4493        }
 4494
 4495        local._background_diagnostics_worker.clone()
 4496    }
 4497
 4498    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4499        let buffer_store = self.buffer_store.clone();
 4500        let local = self.as_local_mut()?;
 4501        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4502            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4503            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4504                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4505            }
 4506        }
 4507        None
 4508    }
 4509
 4510    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4511        cx.spawn(async move |this, cx| {
 4512            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4513                task.await.log_err();
 4514            }
 4515        })
 4516    }
 4517
 4518    pub(crate) fn register_buffer_with_language_servers(
 4519        &mut self,
 4520        buffer: &Entity<Buffer>,
 4521        only_register_servers: HashSet<LanguageServerSelector>,
 4522        ignore_refcounts: bool,
 4523        cx: &mut Context<Self>,
 4524    ) -> OpenLspBufferHandle {
 4525        let buffer_id = buffer.read(cx).remote_id();
 4526        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4527        if let Some(local) = self.as_local_mut() {
 4528            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4529            if !ignore_refcounts {
 4530                *refcount += 1;
 4531            }
 4532
 4533            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4534            // 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
 4535            // 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
 4536            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4537            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4538                return handle;
 4539            };
 4540            if !file.is_local() {
 4541                return handle;
 4542            }
 4543
 4544            if ignore_refcounts || *refcount == 1 {
 4545                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4546            }
 4547            if !ignore_refcounts {
 4548                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4549                    let refcount = {
 4550                        let local = lsp_store.as_local_mut().unwrap();
 4551                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4552                            debug_panic!("bad refcounting");
 4553                            return;
 4554                        };
 4555
 4556                        *refcount -= 1;
 4557                        *refcount
 4558                    };
 4559                    if refcount == 0 {
 4560                        lsp_store.lsp_data.remove(&buffer_id);
 4561                        let local = lsp_store.as_local_mut().unwrap();
 4562                        local.registered_buffers.remove(&buffer_id);
 4563
 4564                        local.buffers_opened_in_servers.remove(&buffer_id);
 4565                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4566                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4567
 4568                            let buffer_abs_path = file.abs_path(cx);
 4569                            for (_, buffer_pull_diagnostics_result_ids) in
 4570                                &mut local.buffer_pull_diagnostics_result_ids
 4571                            {
 4572                                buffer_pull_diagnostics_result_ids.retain(
 4573                                    |_, buffer_result_ids| {
 4574                                        buffer_result_ids.remove(&buffer_abs_path);
 4575                                        !buffer_result_ids.is_empty()
 4576                                    },
 4577                                );
 4578                            }
 4579
 4580                            let diagnostic_updates = local
 4581                                .language_servers
 4582                                .keys()
 4583                                .cloned()
 4584                                .map(|server_id| DocumentDiagnosticsUpdate {
 4585                                    diagnostics: DocumentDiagnostics {
 4586                                        document_abs_path: buffer_abs_path.clone(),
 4587                                        version: None,
 4588                                        diagnostics: Vec::new(),
 4589                                    },
 4590                                    result_id: None,
 4591                                    registration_id: None,
 4592                                    server_id,
 4593                                    disk_based_sources: Cow::Borrowed(&[]),
 4594                                })
 4595                                .collect::<Vec<_>>();
 4596
 4597                            lsp_store
 4598                                .merge_diagnostic_entries(
 4599                                    diagnostic_updates,
 4600                                    |_, diagnostic, _| {
 4601                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4602                                    },
 4603                                    cx,
 4604                                )
 4605                                .context("Clearing diagnostics for the closed buffer")
 4606                                .log_err();
 4607                        }
 4608                    }
 4609                })
 4610                .detach();
 4611            }
 4612        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4613            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4614            cx.background_spawn(async move {
 4615                upstream_client
 4616                    .request(proto::RegisterBufferWithLanguageServers {
 4617                        project_id: upstream_project_id,
 4618                        buffer_id,
 4619                        only_servers: only_register_servers
 4620                            .into_iter()
 4621                            .map(|selector| {
 4622                                let selector = match selector {
 4623                                    LanguageServerSelector::Id(language_server_id) => {
 4624                                        proto::language_server_selector::Selector::ServerId(
 4625                                            language_server_id.to_proto(),
 4626                                        )
 4627                                    }
 4628                                    LanguageServerSelector::Name(language_server_name) => {
 4629                                        proto::language_server_selector::Selector::Name(
 4630                                            language_server_name.to_string(),
 4631                                        )
 4632                                    }
 4633                                };
 4634                                proto::LanguageServerSelector {
 4635                                    selector: Some(selector),
 4636                                }
 4637                            })
 4638                            .collect(),
 4639                    })
 4640                    .await
 4641            })
 4642            .detach();
 4643        } else {
 4644            // Our remote connection got closed
 4645        }
 4646        handle
 4647    }
 4648
 4649    fn maintain_buffer_languages(
 4650        languages: Arc<LanguageRegistry>,
 4651        cx: &mut Context<Self>,
 4652    ) -> Task<()> {
 4653        let mut subscription = languages.subscribe();
 4654        let mut prev_reload_count = languages.reload_count();
 4655        cx.spawn(async move |this, cx| {
 4656            while let Some(()) = subscription.next().await {
 4657                if let Some(this) = this.upgrade() {
 4658                    // If the language registry has been reloaded, then remove and
 4659                    // re-assign the languages on all open buffers.
 4660                    let reload_count = languages.reload_count();
 4661                    if reload_count > prev_reload_count {
 4662                        prev_reload_count = reload_count;
 4663                        this.update(cx, |this, cx| {
 4664                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4665                                for buffer in buffer_store.buffers() {
 4666                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4667                                    {
 4668                                        buffer.update(cx, |buffer, cx| {
 4669                                            buffer.set_language_async(None, cx)
 4670                                        });
 4671                                        if let Some(local) = this.as_local_mut() {
 4672                                            local.reset_buffer(&buffer, &f, cx);
 4673
 4674                                            if local
 4675                                                .registered_buffers
 4676                                                .contains_key(&buffer.read(cx).remote_id())
 4677                                                && let Some(file_url) =
 4678                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4679                                            {
 4680                                                local.unregister_buffer_from_language_servers(
 4681                                                    &buffer, &file_url, cx,
 4682                                                );
 4683                                            }
 4684                                        }
 4685                                    }
 4686                                }
 4687                            });
 4688                        });
 4689                    }
 4690
 4691                    this.update(cx, |this, cx| {
 4692                        let mut plain_text_buffers = Vec::new();
 4693                        let mut buffers_with_unknown_injections = Vec::new();
 4694                        for handle in this.buffer_store.read(cx).buffers() {
 4695                            let buffer = handle.read(cx);
 4696                            if buffer.language().is_none()
 4697                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4698                            {
 4699                                plain_text_buffers.push(handle);
 4700                            } else if buffer.contains_unknown_injections() {
 4701                                buffers_with_unknown_injections.push(handle);
 4702                            }
 4703                        }
 4704
 4705                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4706                        // and reused later in the invisible worktrees.
 4707                        plain_text_buffers.sort_by_key(|buffer| {
 4708                            Reverse(
 4709                                File::from_dyn(buffer.read(cx).file())
 4710                                    .map(|file| file.worktree.read(cx).is_visible()),
 4711                            )
 4712                        });
 4713
 4714                        for buffer in plain_text_buffers {
 4715                            this.detect_language_for_buffer(&buffer, cx);
 4716                            if let Some(local) = this.as_local_mut() {
 4717                                local.initialize_buffer(&buffer, cx);
 4718                                if local
 4719                                    .registered_buffers
 4720                                    .contains_key(&buffer.read(cx).remote_id())
 4721                                {
 4722                                    local.register_buffer_with_language_servers(
 4723                                        &buffer,
 4724                                        HashSet::default(),
 4725                                        cx,
 4726                                    );
 4727                                }
 4728                            }
 4729                        }
 4730
 4731                        for buffer in buffers_with_unknown_injections {
 4732                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4733                        }
 4734                    });
 4735                }
 4736            }
 4737        })
 4738    }
 4739
 4740    fn detect_language_for_buffer(
 4741        &mut self,
 4742        buffer_handle: &Entity<Buffer>,
 4743        cx: &mut Context<Self>,
 4744    ) -> Option<language::AvailableLanguage> {
 4745        // If the buffer has a language, set it and start the language server if we haven't already.
 4746        let buffer = buffer_handle.read(cx);
 4747        let file = buffer.file()?;
 4748
 4749        let content = buffer.as_rope();
 4750        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4751        if let Some(available_language) = &available_language {
 4752            if let Some(Ok(Ok(new_language))) = self
 4753                .languages
 4754                .load_language(available_language)
 4755                .now_or_never()
 4756            {
 4757                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4758            }
 4759        } else {
 4760            cx.emit(LspStoreEvent::LanguageDetected {
 4761                buffer: buffer_handle.clone(),
 4762                new_language: None,
 4763            });
 4764        }
 4765
 4766        available_language
 4767    }
 4768
 4769    pub(crate) fn set_language_for_buffer(
 4770        &mut self,
 4771        buffer_entity: &Entity<Buffer>,
 4772        new_language: Arc<Language>,
 4773        cx: &mut Context<Self>,
 4774    ) {
 4775        let buffer = buffer_entity.read(cx);
 4776        let buffer_file = buffer.file().cloned();
 4777        let buffer_id = buffer.remote_id();
 4778        if let Some(local_store) = self.as_local_mut()
 4779            && local_store.registered_buffers.contains_key(&buffer_id)
 4780            && let Some(abs_path) =
 4781                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4782            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4783        {
 4784            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4785        }
 4786        buffer_entity.update(cx, |buffer, cx| {
 4787            if buffer
 4788                .language()
 4789                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4790            {
 4791                buffer.set_language_async(Some(new_language.clone()), cx);
 4792            }
 4793        });
 4794
 4795        let settings =
 4796            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4797        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4798
 4799        let worktree_id = if let Some(file) = buffer_file {
 4800            let worktree = file.worktree.clone();
 4801
 4802            if let Some(local) = self.as_local_mut()
 4803                && local.registered_buffers.contains_key(&buffer_id)
 4804            {
 4805                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4806            }
 4807            Some(worktree.read(cx).id())
 4808        } else {
 4809            None
 4810        };
 4811
 4812        if settings.prettier.allowed
 4813            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4814        {
 4815            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4816            if let Some(prettier_store) = prettier_store {
 4817                prettier_store.update(cx, |prettier_store, cx| {
 4818                    prettier_store.install_default_prettier(
 4819                        worktree_id,
 4820                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4821                        cx,
 4822                    )
 4823                })
 4824            }
 4825        }
 4826
 4827        cx.emit(LspStoreEvent::LanguageDetected {
 4828            buffer: buffer_entity.clone(),
 4829            new_language: Some(new_language),
 4830        })
 4831    }
 4832
 4833    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4834        self.buffer_store.clone()
 4835    }
 4836
 4837    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4838        self.active_entry = active_entry;
 4839    }
 4840
 4841    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4842        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4843            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4844        {
 4845            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4846                summaries
 4847                    .iter()
 4848                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4849            });
 4850            if let Some(summary) = summaries.next() {
 4851                client
 4852                    .send(proto::UpdateDiagnosticSummary {
 4853                        project_id: downstream_project_id,
 4854                        worktree_id: worktree.id().to_proto(),
 4855                        summary: Some(summary),
 4856                        more_summaries: summaries.collect(),
 4857                    })
 4858                    .log_err();
 4859            }
 4860        }
 4861    }
 4862
 4863    fn is_capable_for_proto_request<R>(
 4864        &self,
 4865        buffer: &Entity<Buffer>,
 4866        request: &R,
 4867        cx: &App,
 4868    ) -> bool
 4869    where
 4870        R: LspCommand,
 4871    {
 4872        self.check_if_capable_for_proto_request(
 4873            buffer,
 4874            |capabilities| {
 4875                request.check_capabilities(AdapterServerCapabilities {
 4876                    server_capabilities: capabilities.clone(),
 4877                    code_action_kinds: None,
 4878                })
 4879            },
 4880            cx,
 4881        )
 4882    }
 4883
 4884    fn check_if_capable_for_proto_request<F>(
 4885        &self,
 4886        buffer: &Entity<Buffer>,
 4887        check: F,
 4888        cx: &App,
 4889    ) -> bool
 4890    where
 4891        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4892    {
 4893        let Some(language) = buffer.read(cx).language().cloned() else {
 4894            return false;
 4895        };
 4896        let registered_language_servers = self
 4897            .languages
 4898            .lsp_adapters(&language.name())
 4899            .into_iter()
 4900            .map(|lsp_adapter| lsp_adapter.name())
 4901            .collect::<HashSet<_>>();
 4902        self.language_server_statuses
 4903            .iter()
 4904            .filter_map(|(server_id, server_status)| {
 4905                // Include servers that are either registered for this language OR
 4906                // available to be loaded (for SSH remote mode where adapters like
 4907                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4908                // but only loaded on the server side)
 4909                let is_relevant = registered_language_servers.contains(&server_status.name)
 4910                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4911                is_relevant.then_some(server_id)
 4912            })
 4913            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4914            .any(check)
 4915    }
 4916
 4917    fn all_capable_for_proto_request<F>(
 4918        &self,
 4919        buffer: &Entity<Buffer>,
 4920        mut check: F,
 4921        cx: &App,
 4922    ) -> Vec<lsp::LanguageServerId>
 4923    where
 4924        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4925    {
 4926        let Some(language) = buffer.read(cx).language().cloned() else {
 4927            return Vec::default();
 4928        };
 4929        let registered_language_servers = self
 4930            .languages
 4931            .lsp_adapters(&language.name())
 4932            .into_iter()
 4933            .map(|lsp_adapter| lsp_adapter.name())
 4934            .collect::<HashSet<_>>();
 4935        self.language_server_statuses
 4936            .iter()
 4937            .filter_map(|(server_id, server_status)| {
 4938                // Include servers that are either registered for this language OR
 4939                // available to be loaded (for SSH remote mode where adapters like
 4940                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4941                // but only loaded on the server side)
 4942                let is_relevant = registered_language_servers.contains(&server_status.name)
 4943                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4944                is_relevant.then_some((server_id, &server_status.name))
 4945            })
 4946            .filter_map(|(server_id, server_name)| {
 4947                self.lsp_server_capabilities
 4948                    .get(server_id)
 4949                    .map(|c| (server_id, server_name, c))
 4950            })
 4951            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4952            .map(|(server_id, _, _)| *server_id)
 4953            .collect()
 4954    }
 4955
 4956    pub fn request_lsp<R>(
 4957        &mut self,
 4958        buffer: Entity<Buffer>,
 4959        server: LanguageServerToQuery,
 4960        request: R,
 4961        cx: &mut Context<Self>,
 4962    ) -> Task<Result<R::Response>>
 4963    where
 4964        R: LspCommand,
 4965        <R::LspRequest as lsp::request::Request>::Result: Send,
 4966        <R::LspRequest as lsp::request::Request>::Params: Send,
 4967    {
 4968        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4969            return self.send_lsp_proto_request(
 4970                buffer,
 4971                upstream_client,
 4972                upstream_project_id,
 4973                request,
 4974                cx,
 4975            );
 4976        }
 4977
 4978        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4979            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4980                local
 4981                    .language_servers_for_buffer(buffer, cx)
 4982                    .find(|(_, server)| {
 4983                        request.check_capabilities(server.adapter_server_capabilities())
 4984                    })
 4985                    .map(|(_, server)| server.clone())
 4986            }),
 4987            LanguageServerToQuery::Other(id) => self
 4988                .language_server_for_local_buffer(buffer, id, cx)
 4989                .and_then(|(_, server)| {
 4990                    request
 4991                        .check_capabilities(server.adapter_server_capabilities())
 4992                        .then(|| Arc::clone(server))
 4993                }),
 4994        }) else {
 4995            return Task::ready(Ok(Default::default()));
 4996        };
 4997
 4998        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4999
 5000        let Some(file) = file else {
 5001            return Task::ready(Ok(Default::default()));
 5002        };
 5003
 5004        let lsp_params = match request.to_lsp_params_or_response(
 5005            &file.abs_path(cx),
 5006            buffer.read(cx),
 5007            &language_server,
 5008            cx,
 5009        ) {
 5010            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 5011            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 5012            Err(err) => {
 5013                let message = format!(
 5014                    "{} via {} failed: {}",
 5015                    request.display_name(),
 5016                    language_server.name(),
 5017                    err
 5018                );
 5019                // rust-analyzer likes to error with this when its still loading up
 5020                if !message.ends_with("content modified") {
 5021                    log::warn!("{message}");
 5022                }
 5023                return Task::ready(Err(anyhow!(message)));
 5024            }
 5025        };
 5026
 5027        let status = request.status();
 5028        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 5029            return Task::ready(Ok(Default::default()));
 5030        }
 5031
 5032        let request_timeout = ProjectSettings::get_global(cx)
 5033            .global_lsp_settings
 5034            .get_request_timeout();
 5035
 5036        cx.spawn(async move |this, cx| {
 5037            let lsp_request = language_server.request::<R::LspRequest>(lsp_params, request_timeout);
 5038
 5039            let id = lsp_request.id();
 5040            let _cleanup = if status.is_some() {
 5041                cx.update(|cx| {
 5042                    this.update(cx, |this, cx| {
 5043                        this.on_lsp_work_start(
 5044                            language_server.server_id(),
 5045                            ProgressToken::Number(id),
 5046                            LanguageServerProgress {
 5047                                is_disk_based_diagnostics_progress: false,
 5048                                is_cancellable: false,
 5049                                title: None,
 5050                                message: status.clone(),
 5051                                percentage: None,
 5052                                last_update_at: cx.background_executor().now(),
 5053                            },
 5054                            cx,
 5055                        );
 5056                    })
 5057                })
 5058                .log_err();
 5059
 5060                Some(defer(|| {
 5061                    cx.update(|cx| {
 5062                        this.update(cx, |this, cx| {
 5063                            this.on_lsp_work_end(
 5064                                language_server.server_id(),
 5065                                ProgressToken::Number(id),
 5066                                cx,
 5067                            );
 5068                        })
 5069                    })
 5070                    .log_err();
 5071                }))
 5072            } else {
 5073                None
 5074            };
 5075
 5076            let result = lsp_request.await.into_response();
 5077
 5078            let response = result.map_err(|err| {
 5079                let message = format!(
 5080                    "{} via {} failed: {}",
 5081                    request.display_name(),
 5082                    language_server.name(),
 5083                    err
 5084                );
 5085                // rust-analyzer likes to error with this when its still loading up
 5086                if !message.ends_with("content modified") {
 5087                    log::warn!("{message}");
 5088                }
 5089                anyhow::anyhow!(message)
 5090            })?;
 5091
 5092            request
 5093                .response_from_lsp(
 5094                    response,
 5095                    this.upgrade().context("no app context")?,
 5096                    buffer,
 5097                    language_server.server_id(),
 5098                    cx.clone(),
 5099                )
 5100                .await
 5101        })
 5102    }
 5103
 5104    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 5105        let mut language_formatters_to_check = Vec::new();
 5106        for buffer in self.buffer_store.read(cx).buffers() {
 5107            let buffer = buffer.read(cx);
 5108            let buffer_file = File::from_dyn(buffer.file());
 5109            let buffer_language = buffer.language();
 5110            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 5111            if buffer_language.is_some() {
 5112                language_formatters_to_check.push((
 5113                    buffer_file.map(|f| f.worktree_id(cx)),
 5114                    settings.into_owned(),
 5115                ));
 5116            }
 5117        }
 5118
 5119        self.request_workspace_config_refresh();
 5120
 5121        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 5122            prettier_store.update(cx, |prettier_store, cx| {
 5123                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 5124            })
 5125        }
 5126
 5127        let new_semantic_token_rules = crate::project_settings::ProjectSettings::get_global(cx)
 5128            .global_lsp_settings
 5129            .semantic_token_rules
 5130            .clone();
 5131        self.semantic_token_config
 5132            .update_rules(new_semantic_token_rules);
 5133
 5134        let new_global_semantic_tokens_mode =
 5135            all_language_settings(None, cx).defaults.semantic_tokens;
 5136        if self
 5137            .semantic_token_config
 5138            .update_global_mode(new_global_semantic_tokens_mode)
 5139        {
 5140            self.restart_all_language_servers(cx);
 5141        }
 5142
 5143        cx.notify();
 5144    }
 5145
 5146    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 5147        let buffer_store = self.buffer_store.clone();
 5148        let Some(local) = self.as_local_mut() else {
 5149            return;
 5150        };
 5151        let mut adapters = BTreeMap::default();
 5152        let get_adapter = {
 5153            let languages = local.languages.clone();
 5154            let environment = local.environment.clone();
 5155            let weak = local.weak.clone();
 5156            let worktree_store = local.worktree_store.clone();
 5157            let http_client = local.http_client.clone();
 5158            let fs = local.fs.clone();
 5159            move |worktree_id, cx: &mut App| {
 5160                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 5161                Some(LocalLspAdapterDelegate::new(
 5162                    languages.clone(),
 5163                    &environment,
 5164                    weak.clone(),
 5165                    &worktree,
 5166                    http_client.clone(),
 5167                    fs.clone(),
 5168                    cx,
 5169                ))
 5170            }
 5171        };
 5172
 5173        let mut messages_to_report = Vec::new();
 5174        let (new_tree, to_stop) = {
 5175            let mut rebase = local.lsp_tree.rebase();
 5176            let buffers = buffer_store
 5177                .read(cx)
 5178                .buffers()
 5179                .filter_map(|buffer| {
 5180                    let raw_buffer = buffer.read(cx);
 5181                    if !local
 5182                        .registered_buffers
 5183                        .contains_key(&raw_buffer.remote_id())
 5184                    {
 5185                        return None;
 5186                    }
 5187                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5188                    let language = raw_buffer.language().cloned()?;
 5189                    Some((file, language, raw_buffer.remote_id()))
 5190                })
 5191                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5192            for (file, language, buffer_id) in buffers {
 5193                let worktree_id = file.worktree_id(cx);
 5194                let Some(worktree) = local
 5195                    .worktree_store
 5196                    .read(cx)
 5197                    .worktree_for_id(worktree_id, cx)
 5198                else {
 5199                    continue;
 5200                };
 5201
 5202                if let Some((_, apply)) = local.reuse_existing_language_server(
 5203                    rebase.server_tree(),
 5204                    &worktree,
 5205                    &language.name(),
 5206                    cx,
 5207                ) {
 5208                    (apply)(rebase.server_tree());
 5209                } else if let Some(lsp_delegate) = adapters
 5210                    .entry(worktree_id)
 5211                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5212                    .clone()
 5213                {
 5214                    let delegate =
 5215                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5216                    let path = file
 5217                        .path()
 5218                        .parent()
 5219                        .map(Arc::from)
 5220                        .unwrap_or_else(|| file.path().clone());
 5221                    let worktree_path = ProjectPath { worktree_id, path };
 5222                    let abs_path = file.abs_path(cx);
 5223                    let nodes = rebase
 5224                        .walk(
 5225                            worktree_path,
 5226                            language.name(),
 5227                            language.manifest(),
 5228                            delegate.clone(),
 5229                            cx,
 5230                        )
 5231                        .collect::<Vec<_>>();
 5232                    for node in nodes {
 5233                        let server_id = node.server_id_or_init(|disposition| {
 5234                            let path = &disposition.path;
 5235                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5236                            let key = LanguageServerSeed {
 5237                                worktree_id,
 5238                                name: disposition.server_name.clone(),
 5239                                settings: LanguageServerSeedSettings {
 5240                                    binary: disposition.settings.binary.clone(),
 5241                                    initialization_options: disposition
 5242                                        .settings
 5243                                        .initialization_options
 5244                                        .clone(),
 5245                                },
 5246                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5247                                    path.worktree_id,
 5248                                    &path.path,
 5249                                    language.name(),
 5250                                ),
 5251                            };
 5252                            local.language_server_ids.remove(&key);
 5253
 5254                            let server_id = local.get_or_insert_language_server(
 5255                                &worktree,
 5256                                lsp_delegate.clone(),
 5257                                disposition,
 5258                                &language.name(),
 5259                                cx,
 5260                            );
 5261                            if let Some(state) = local.language_servers.get(&server_id)
 5262                                && let Ok(uri) = uri
 5263                            {
 5264                                state.add_workspace_folder(uri);
 5265                            };
 5266                            server_id
 5267                        });
 5268
 5269                        if let Some(language_server_id) = server_id {
 5270                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5271                                language_server_id,
 5272                                name: node.name(),
 5273                                message:
 5274                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5275                                        proto::RegisteredForBuffer {
 5276                                            buffer_abs_path: abs_path
 5277                                                .to_string_lossy()
 5278                                                .into_owned(),
 5279                                            buffer_id: buffer_id.to_proto(),
 5280                                        },
 5281                                    ),
 5282                            });
 5283                        }
 5284                    }
 5285                } else {
 5286                    continue;
 5287                }
 5288            }
 5289            rebase.finish()
 5290        };
 5291        for message in messages_to_report {
 5292            cx.emit(message);
 5293        }
 5294        local.lsp_tree = new_tree;
 5295        for (id, _) in to_stop {
 5296            self.stop_local_language_server(id, cx).detach();
 5297        }
 5298    }
 5299
 5300    pub fn apply_code_action(
 5301        &self,
 5302        buffer_handle: Entity<Buffer>,
 5303        mut action: CodeAction,
 5304        push_to_history: bool,
 5305        cx: &mut Context<Self>,
 5306    ) -> Task<Result<ProjectTransaction>> {
 5307        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5308            let request = proto::ApplyCodeAction {
 5309                project_id,
 5310                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5311                action: Some(Self::serialize_code_action(&action)),
 5312            };
 5313            let buffer_store = self.buffer_store();
 5314            cx.spawn(async move |_, cx| {
 5315                let response = upstream_client
 5316                    .request(request)
 5317                    .await?
 5318                    .transaction
 5319                    .context("missing transaction")?;
 5320
 5321                buffer_store
 5322                    .update(cx, |buffer_store, cx| {
 5323                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5324                    })
 5325                    .await
 5326            })
 5327        } else if self.mode.is_local() {
 5328            let Some((_, lang_server, request_timeout)) = buffer_handle.update(cx, |buffer, cx| {
 5329                let request_timeout = ProjectSettings::get_global(cx)
 5330                    .global_lsp_settings
 5331                    .get_request_timeout();
 5332                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5333                    .map(|(adapter, server)| (adapter.clone(), server.clone(), request_timeout))
 5334            }) else {
 5335                return Task::ready(Ok(ProjectTransaction::default()));
 5336            };
 5337
 5338            cx.spawn(async move |this, cx| {
 5339                LocalLspStore::try_resolve_code_action(&lang_server, &mut action, request_timeout)
 5340                    .await
 5341                    .context("resolving a code action")?;
 5342                if let Some(edit) = action.lsp_action.edit()
 5343                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5344                        return LocalLspStore::deserialize_workspace_edit(
 5345                            this.upgrade().context("no app present")?,
 5346                            edit.clone(),
 5347                            push_to_history,
 5348
 5349                            lang_server.clone(),
 5350                            cx,
 5351                        )
 5352                        .await;
 5353                    }
 5354
 5355                let Some(command) = action.lsp_action.command() else {
 5356                    return Ok(ProjectTransaction::default())
 5357                };
 5358
 5359                let server_capabilities = lang_server.capabilities();
 5360                let available_commands = server_capabilities
 5361                    .execute_command_provider
 5362                    .as_ref()
 5363                    .map(|options| options.commands.as_slice())
 5364                    .unwrap_or_default();
 5365
 5366                if !available_commands.contains(&command.command) {
 5367                    log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5368                    return Ok(ProjectTransaction::default())
 5369                }
 5370
 5371                let request_timeout = cx.update(|app|
 5372                    ProjectSettings::get_global(app)
 5373                    .global_lsp_settings
 5374                    .get_request_timeout()
 5375                );
 5376
 5377                this.update(cx, |this, _| {
 5378                    this.as_local_mut()
 5379                        .unwrap()
 5380                        .last_workspace_edits_by_language_server
 5381                        .remove(&lang_server.server_id());
 5382                })?;
 5383
 5384                let _result = lang_server
 5385                    .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5386                        command: command.command.clone(),
 5387                        arguments: command.arguments.clone().unwrap_or_default(),
 5388                        ..lsp::ExecuteCommandParams::default()
 5389                    }, request_timeout)
 5390                    .await.into_response()
 5391                    .context("execute command")?;
 5392
 5393                return this.update(cx, |this, _| {
 5394                    this.as_local_mut()
 5395                        .unwrap()
 5396                        .last_workspace_edits_by_language_server
 5397                        .remove(&lang_server.server_id())
 5398                        .unwrap_or_default()
 5399                });
 5400            })
 5401        } else {
 5402            Task::ready(Err(anyhow!("no upstream client and not local")))
 5403        }
 5404    }
 5405
 5406    pub fn apply_code_action_kind(
 5407        &mut self,
 5408        buffers: HashSet<Entity<Buffer>>,
 5409        kind: CodeActionKind,
 5410        push_to_history: bool,
 5411        cx: &mut Context<Self>,
 5412    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5413        if self.as_local().is_some() {
 5414            cx.spawn(async move |lsp_store, cx| {
 5415                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5416                let result = LocalLspStore::execute_code_action_kind_locally(
 5417                    lsp_store.clone(),
 5418                    buffers,
 5419                    kind,
 5420                    push_to_history,
 5421                    cx,
 5422                )
 5423                .await;
 5424                lsp_store.update(cx, |lsp_store, _| {
 5425                    lsp_store.update_last_formatting_failure(&result);
 5426                })?;
 5427                result
 5428            })
 5429        } else if let Some((client, project_id)) = self.upstream_client() {
 5430            let buffer_store = self.buffer_store();
 5431            cx.spawn(async move |lsp_store, cx| {
 5432                let result = client
 5433                    .request(proto::ApplyCodeActionKind {
 5434                        project_id,
 5435                        kind: kind.as_str().to_owned(),
 5436                        buffer_ids: buffers
 5437                            .iter()
 5438                            .map(|buffer| {
 5439                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5440                            })
 5441                            .collect(),
 5442                    })
 5443                    .await
 5444                    .and_then(|result| result.transaction.context("missing transaction"));
 5445                lsp_store.update(cx, |lsp_store, _| {
 5446                    lsp_store.update_last_formatting_failure(&result);
 5447                })?;
 5448
 5449                let transaction_response = result?;
 5450                buffer_store
 5451                    .update(cx, |buffer_store, cx| {
 5452                        buffer_store.deserialize_project_transaction(
 5453                            transaction_response,
 5454                            push_to_history,
 5455                            cx,
 5456                        )
 5457                    })
 5458                    .await
 5459            })
 5460        } else {
 5461            Task::ready(Ok(ProjectTransaction::default()))
 5462        }
 5463    }
 5464
 5465    pub fn resolved_hint(
 5466        &mut self,
 5467        buffer_id: BufferId,
 5468        id: InlayId,
 5469        cx: &mut Context<Self>,
 5470    ) -> Option<ResolvedHint> {
 5471        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5472
 5473        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5474        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5475        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5476        let (server_id, resolve_data) = match &hint.resolve_state {
 5477            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5478            ResolveState::Resolving => {
 5479                return Some(ResolvedHint::Resolving(
 5480                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5481                ));
 5482            }
 5483            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5484        };
 5485
 5486        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5487        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5488        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5489            id,
 5490            cx.spawn(async move |lsp_store, cx| {
 5491                let resolved_hint = resolve_task.await;
 5492                lsp_store
 5493                    .update(cx, |lsp_store, _| {
 5494                        if let Some(old_inlay_hint) = lsp_store
 5495                            .lsp_data
 5496                            .get_mut(&buffer_id)
 5497                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5498                        {
 5499                            match resolved_hint {
 5500                                Ok(resolved_hint) => {
 5501                                    *old_inlay_hint = resolved_hint;
 5502                                }
 5503                                Err(e) => {
 5504                                    old_inlay_hint.resolve_state =
 5505                                        ResolveState::CanResolve(server_id, resolve_data);
 5506                                    log::error!("Inlay hint resolve failed: {e:#}");
 5507                                }
 5508                            }
 5509                        }
 5510                    })
 5511                    .ok();
 5512            })
 5513            .shared(),
 5514        );
 5515        debug_assert!(
 5516            previous_task.is_none(),
 5517            "Did not change hint's resolve state after spawning its resolve"
 5518        );
 5519        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5520        None
 5521    }
 5522
 5523    pub(crate) fn linked_edits(
 5524        &mut self,
 5525        buffer: &Entity<Buffer>,
 5526        position: Anchor,
 5527        cx: &mut Context<Self>,
 5528    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5529        let snapshot = buffer.read(cx).snapshot();
 5530        let scope = snapshot.language_scope_at(position);
 5531        let Some(server_id) = self
 5532            .as_local()
 5533            .and_then(|local| {
 5534                buffer.update(cx, |buffer, cx| {
 5535                    local
 5536                        .language_servers_for_buffer(buffer, cx)
 5537                        .filter(|(_, server)| {
 5538                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5539                        })
 5540                        .filter(|(adapter, _)| {
 5541                            scope
 5542                                .as_ref()
 5543                                .map(|scope| scope.language_allowed(&adapter.name))
 5544                                .unwrap_or(true)
 5545                        })
 5546                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5547                        .next()
 5548                })
 5549            })
 5550            .or_else(|| {
 5551                self.upstream_client()
 5552                    .is_some()
 5553                    .then_some(LanguageServerToQuery::FirstCapable)
 5554            })
 5555            .filter(|_| {
 5556                maybe!({
 5557                    let language = buffer.read(cx).language_at(position)?;
 5558                    Some(
 5559                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5560                            .linked_edits,
 5561                    )
 5562                }) == Some(true)
 5563            })
 5564        else {
 5565            return Task::ready(Ok(Vec::new()));
 5566        };
 5567
 5568        self.request_lsp(
 5569            buffer.clone(),
 5570            server_id,
 5571            LinkedEditingRange { position },
 5572            cx,
 5573        )
 5574    }
 5575
 5576    fn apply_on_type_formatting(
 5577        &mut self,
 5578        buffer: Entity<Buffer>,
 5579        position: Anchor,
 5580        trigger: String,
 5581        cx: &mut Context<Self>,
 5582    ) -> Task<Result<Option<Transaction>>> {
 5583        if let Some((client, project_id)) = self.upstream_client() {
 5584            if !self.check_if_capable_for_proto_request(
 5585                &buffer,
 5586                |capabilities| {
 5587                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5588                },
 5589                cx,
 5590            ) {
 5591                return Task::ready(Ok(None));
 5592            }
 5593            let request = proto::OnTypeFormatting {
 5594                project_id,
 5595                buffer_id: buffer.read(cx).remote_id().into(),
 5596                position: Some(serialize_anchor(&position)),
 5597                trigger,
 5598                version: serialize_version(&buffer.read(cx).version()),
 5599            };
 5600            cx.background_spawn(async move {
 5601                client
 5602                    .request(request)
 5603                    .await?
 5604                    .transaction
 5605                    .map(language::proto::deserialize_transaction)
 5606                    .transpose()
 5607            })
 5608        } else if let Some(local) = self.as_local_mut() {
 5609            let buffer_id = buffer.read(cx).remote_id();
 5610            local.buffers_being_formatted.insert(buffer_id);
 5611            cx.spawn(async move |this, cx| {
 5612                let _cleanup = defer({
 5613                    let this = this.clone();
 5614                    let mut cx = cx.clone();
 5615                    move || {
 5616                        this.update(&mut cx, |this, _| {
 5617                            if let Some(local) = this.as_local_mut() {
 5618                                local.buffers_being_formatted.remove(&buffer_id);
 5619                            }
 5620                        })
 5621                        .ok();
 5622                    }
 5623                });
 5624
 5625                buffer
 5626                    .update(cx, |buffer, _| {
 5627                        buffer.wait_for_edits(Some(position.timestamp()))
 5628                    })
 5629                    .await?;
 5630                this.update(cx, |this, cx| {
 5631                    let position = position.to_point_utf16(buffer.read(cx));
 5632                    this.on_type_format(buffer, position, trigger, false, cx)
 5633                })?
 5634                .await
 5635            })
 5636        } else {
 5637            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5638        }
 5639    }
 5640
 5641    pub fn on_type_format<T: ToPointUtf16>(
 5642        &mut self,
 5643        buffer: Entity<Buffer>,
 5644        position: T,
 5645        trigger: String,
 5646        push_to_history: bool,
 5647        cx: &mut Context<Self>,
 5648    ) -> Task<Result<Option<Transaction>>> {
 5649        let position = position.to_point_utf16(buffer.read(cx));
 5650        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5651    }
 5652
 5653    fn on_type_format_impl(
 5654        &mut self,
 5655        buffer: Entity<Buffer>,
 5656        position: PointUtf16,
 5657        trigger: String,
 5658        push_to_history: bool,
 5659        cx: &mut Context<Self>,
 5660    ) -> Task<Result<Option<Transaction>>> {
 5661        let options = buffer.update(cx, |buffer, cx| {
 5662            lsp_command::lsp_formatting_options(
 5663                language_settings(
 5664                    buffer.language_at(position).map(|l| l.name()),
 5665                    buffer.file(),
 5666                    cx,
 5667                )
 5668                .as_ref(),
 5669            )
 5670        });
 5671
 5672        cx.spawn(async move |this, cx| {
 5673            if let Some(waiter) =
 5674                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5675            {
 5676                waiter.await?;
 5677            }
 5678            cx.update(|cx| {
 5679                this.update(cx, |this, cx| {
 5680                    this.request_lsp(
 5681                        buffer.clone(),
 5682                        LanguageServerToQuery::FirstCapable,
 5683                        OnTypeFormatting {
 5684                            position,
 5685                            trigger,
 5686                            options,
 5687                            push_to_history,
 5688                        },
 5689                        cx,
 5690                    )
 5691                })
 5692            })?
 5693            .await
 5694        })
 5695    }
 5696
 5697    pub fn definitions(
 5698        &mut self,
 5699        buffer: &Entity<Buffer>,
 5700        position: PointUtf16,
 5701        cx: &mut Context<Self>,
 5702    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5703        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5704            let request = GetDefinitions { position };
 5705            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5706                return Task::ready(Ok(None));
 5707            }
 5708
 5709            let request_timeout = ProjectSettings::get_global(cx)
 5710                .global_lsp_settings
 5711                .get_request_timeout();
 5712
 5713            let request_task = upstream_client.request_lsp(
 5714                project_id,
 5715                None,
 5716                request_timeout,
 5717                cx.background_executor().clone(),
 5718                request.to_proto(project_id, buffer.read(cx)),
 5719            );
 5720            let buffer = buffer.clone();
 5721            cx.spawn(async move |weak_lsp_store, cx| {
 5722                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5723                    return Ok(None);
 5724                };
 5725                let Some(responses) = request_task.await? else {
 5726                    return Ok(None);
 5727                };
 5728                let actions = join_all(responses.payload.into_iter().map(|response| {
 5729                    GetDefinitions { position }.response_from_proto(
 5730                        response.response,
 5731                        lsp_store.clone(),
 5732                        buffer.clone(),
 5733                        cx.clone(),
 5734                    )
 5735                }))
 5736                .await;
 5737
 5738                Ok(Some(
 5739                    actions
 5740                        .into_iter()
 5741                        .collect::<Result<Vec<Vec<_>>>>()?
 5742                        .into_iter()
 5743                        .flatten()
 5744                        .dedup()
 5745                        .collect(),
 5746                ))
 5747            })
 5748        } else {
 5749            let definitions_task = self.request_multiple_lsp_locally(
 5750                buffer,
 5751                Some(position),
 5752                GetDefinitions { position },
 5753                cx,
 5754            );
 5755            cx.background_spawn(async move {
 5756                Ok(Some(
 5757                    definitions_task
 5758                        .await
 5759                        .into_iter()
 5760                        .flat_map(|(_, definitions)| definitions)
 5761                        .dedup()
 5762                        .collect(),
 5763                ))
 5764            })
 5765        }
 5766    }
 5767
 5768    pub fn declarations(
 5769        &mut self,
 5770        buffer: &Entity<Buffer>,
 5771        position: PointUtf16,
 5772        cx: &mut Context<Self>,
 5773    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5774        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5775            let request = GetDeclarations { position };
 5776            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5777                return Task::ready(Ok(None));
 5778            }
 5779            let request_timeout = ProjectSettings::get_global(cx)
 5780                .global_lsp_settings
 5781                .get_request_timeout();
 5782            let request_task = upstream_client.request_lsp(
 5783                project_id,
 5784                None,
 5785                request_timeout,
 5786                cx.background_executor().clone(),
 5787                request.to_proto(project_id, buffer.read(cx)),
 5788            );
 5789            let buffer = buffer.clone();
 5790            cx.spawn(async move |weak_lsp_store, cx| {
 5791                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5792                    return Ok(None);
 5793                };
 5794                let Some(responses) = request_task.await? else {
 5795                    return Ok(None);
 5796                };
 5797                let actions = join_all(responses.payload.into_iter().map(|response| {
 5798                    GetDeclarations { position }.response_from_proto(
 5799                        response.response,
 5800                        lsp_store.clone(),
 5801                        buffer.clone(),
 5802                        cx.clone(),
 5803                    )
 5804                }))
 5805                .await;
 5806
 5807                Ok(Some(
 5808                    actions
 5809                        .into_iter()
 5810                        .collect::<Result<Vec<Vec<_>>>>()?
 5811                        .into_iter()
 5812                        .flatten()
 5813                        .dedup()
 5814                        .collect(),
 5815                ))
 5816            })
 5817        } else {
 5818            let declarations_task = self.request_multiple_lsp_locally(
 5819                buffer,
 5820                Some(position),
 5821                GetDeclarations { position },
 5822                cx,
 5823            );
 5824            cx.background_spawn(async move {
 5825                Ok(Some(
 5826                    declarations_task
 5827                        .await
 5828                        .into_iter()
 5829                        .flat_map(|(_, declarations)| declarations)
 5830                        .dedup()
 5831                        .collect(),
 5832                ))
 5833            })
 5834        }
 5835    }
 5836
 5837    pub fn type_definitions(
 5838        &mut self,
 5839        buffer: &Entity<Buffer>,
 5840        position: PointUtf16,
 5841        cx: &mut Context<Self>,
 5842    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5843        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5844            let request = GetTypeDefinitions { position };
 5845            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5846                return Task::ready(Ok(None));
 5847            }
 5848            let request_timeout = ProjectSettings::get_global(cx)
 5849                .global_lsp_settings
 5850                .get_request_timeout();
 5851            let request_task = upstream_client.request_lsp(
 5852                project_id,
 5853                None,
 5854                request_timeout,
 5855                cx.background_executor().clone(),
 5856                request.to_proto(project_id, buffer.read(cx)),
 5857            );
 5858            let buffer = buffer.clone();
 5859            cx.spawn(async move |weak_lsp_store, cx| {
 5860                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5861                    return Ok(None);
 5862                };
 5863                let Some(responses) = request_task.await? else {
 5864                    return Ok(None);
 5865                };
 5866                let actions = join_all(responses.payload.into_iter().map(|response| {
 5867                    GetTypeDefinitions { position }.response_from_proto(
 5868                        response.response,
 5869                        lsp_store.clone(),
 5870                        buffer.clone(),
 5871                        cx.clone(),
 5872                    )
 5873                }))
 5874                .await;
 5875
 5876                Ok(Some(
 5877                    actions
 5878                        .into_iter()
 5879                        .collect::<Result<Vec<Vec<_>>>>()?
 5880                        .into_iter()
 5881                        .flatten()
 5882                        .dedup()
 5883                        .collect(),
 5884                ))
 5885            })
 5886        } else {
 5887            let type_definitions_task = self.request_multiple_lsp_locally(
 5888                buffer,
 5889                Some(position),
 5890                GetTypeDefinitions { position },
 5891                cx,
 5892            );
 5893            cx.background_spawn(async move {
 5894                Ok(Some(
 5895                    type_definitions_task
 5896                        .await
 5897                        .into_iter()
 5898                        .flat_map(|(_, type_definitions)| type_definitions)
 5899                        .dedup()
 5900                        .collect(),
 5901                ))
 5902            })
 5903        }
 5904    }
 5905
 5906    pub fn implementations(
 5907        &mut self,
 5908        buffer: &Entity<Buffer>,
 5909        position: PointUtf16,
 5910        cx: &mut Context<Self>,
 5911    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5912        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5913            let request = GetImplementations { position };
 5914            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5915                return Task::ready(Ok(None));
 5916            }
 5917
 5918            let request_timeout = ProjectSettings::get_global(cx)
 5919                .global_lsp_settings
 5920                .get_request_timeout();
 5921            let request_task = upstream_client.request_lsp(
 5922                project_id,
 5923                None,
 5924                request_timeout,
 5925                cx.background_executor().clone(),
 5926                request.to_proto(project_id, buffer.read(cx)),
 5927            );
 5928            let buffer = buffer.clone();
 5929            cx.spawn(async move |weak_lsp_store, cx| {
 5930                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5931                    return Ok(None);
 5932                };
 5933                let Some(responses) = request_task.await? else {
 5934                    return Ok(None);
 5935                };
 5936                let actions = join_all(responses.payload.into_iter().map(|response| {
 5937                    GetImplementations { position }.response_from_proto(
 5938                        response.response,
 5939                        lsp_store.clone(),
 5940                        buffer.clone(),
 5941                        cx.clone(),
 5942                    )
 5943                }))
 5944                .await;
 5945
 5946                Ok(Some(
 5947                    actions
 5948                        .into_iter()
 5949                        .collect::<Result<Vec<Vec<_>>>>()?
 5950                        .into_iter()
 5951                        .flatten()
 5952                        .dedup()
 5953                        .collect(),
 5954                ))
 5955            })
 5956        } else {
 5957            let implementations_task = self.request_multiple_lsp_locally(
 5958                buffer,
 5959                Some(position),
 5960                GetImplementations { position },
 5961                cx,
 5962            );
 5963            cx.background_spawn(async move {
 5964                Ok(Some(
 5965                    implementations_task
 5966                        .await
 5967                        .into_iter()
 5968                        .flat_map(|(_, implementations)| implementations)
 5969                        .dedup()
 5970                        .collect(),
 5971                ))
 5972            })
 5973        }
 5974    }
 5975
 5976    pub fn references(
 5977        &mut self,
 5978        buffer: &Entity<Buffer>,
 5979        position: PointUtf16,
 5980        cx: &mut Context<Self>,
 5981    ) -> Task<Result<Option<Vec<Location>>>> {
 5982        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5983            let request = GetReferences { position };
 5984            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5985                return Task::ready(Ok(None));
 5986            }
 5987
 5988            let request_timeout = ProjectSettings::get_global(cx)
 5989                .global_lsp_settings
 5990                .get_request_timeout();
 5991            let request_task = upstream_client.request_lsp(
 5992                project_id,
 5993                None,
 5994                request_timeout,
 5995                cx.background_executor().clone(),
 5996                request.to_proto(project_id, buffer.read(cx)),
 5997            );
 5998            let buffer = buffer.clone();
 5999            cx.spawn(async move |weak_lsp_store, cx| {
 6000                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6001                    return Ok(None);
 6002                };
 6003                let Some(responses) = request_task.await? else {
 6004                    return Ok(None);
 6005                };
 6006
 6007                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 6008                    GetReferences { position }.response_from_proto(
 6009                        lsp_response.response,
 6010                        lsp_store.clone(),
 6011                        buffer.clone(),
 6012                        cx.clone(),
 6013                    )
 6014                }))
 6015                .await
 6016                .into_iter()
 6017                .collect::<Result<Vec<Vec<_>>>>()?
 6018                .into_iter()
 6019                .flatten()
 6020                .dedup()
 6021                .collect();
 6022                Ok(Some(locations))
 6023            })
 6024        } else {
 6025            let references_task = self.request_multiple_lsp_locally(
 6026                buffer,
 6027                Some(position),
 6028                GetReferences { position },
 6029                cx,
 6030            );
 6031            cx.background_spawn(async move {
 6032                Ok(Some(
 6033                    references_task
 6034                        .await
 6035                        .into_iter()
 6036                        .flat_map(|(_, references)| references)
 6037                        .dedup()
 6038                        .collect(),
 6039                ))
 6040            })
 6041        }
 6042    }
 6043
 6044    pub fn code_actions(
 6045        &mut self,
 6046        buffer: &Entity<Buffer>,
 6047        range: Range<Anchor>,
 6048        kinds: Option<Vec<CodeActionKind>>,
 6049        cx: &mut Context<Self>,
 6050    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6051        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6052            let request = GetCodeActions {
 6053                range: range.clone(),
 6054                kinds: kinds.clone(),
 6055            };
 6056            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6057                return Task::ready(Ok(None));
 6058            }
 6059            let request_timeout = ProjectSettings::get_global(cx)
 6060                .global_lsp_settings
 6061                .get_request_timeout();
 6062            let request_task = upstream_client.request_lsp(
 6063                project_id,
 6064                None,
 6065                request_timeout,
 6066                cx.background_executor().clone(),
 6067                request.to_proto(project_id, buffer.read(cx)),
 6068            );
 6069            let buffer = buffer.clone();
 6070            cx.spawn(async move |weak_lsp_store, cx| {
 6071                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6072                    return Ok(None);
 6073                };
 6074                let Some(responses) = request_task.await? else {
 6075                    return Ok(None);
 6076                };
 6077                let actions = join_all(responses.payload.into_iter().map(|response| {
 6078                    GetCodeActions {
 6079                        range: range.clone(),
 6080                        kinds: kinds.clone(),
 6081                    }
 6082                    .response_from_proto(
 6083                        response.response,
 6084                        lsp_store.clone(),
 6085                        buffer.clone(),
 6086                        cx.clone(),
 6087                    )
 6088                }))
 6089                .await;
 6090
 6091                Ok(Some(
 6092                    actions
 6093                        .into_iter()
 6094                        .collect::<Result<Vec<Vec<_>>>>()?
 6095                        .into_iter()
 6096                        .flatten()
 6097                        .collect(),
 6098                ))
 6099            })
 6100        } else {
 6101            let all_actions_task = self.request_multiple_lsp_locally(
 6102                buffer,
 6103                Some(range.start),
 6104                GetCodeActions { range, kinds },
 6105                cx,
 6106            );
 6107            cx.background_spawn(async move {
 6108                Ok(Some(
 6109                    all_actions_task
 6110                        .await
 6111                        .into_iter()
 6112                        .flat_map(|(_, actions)| actions)
 6113                        .collect(),
 6114                ))
 6115            })
 6116        }
 6117    }
 6118
 6119    #[inline(never)]
 6120    pub fn completions(
 6121        &self,
 6122        buffer: &Entity<Buffer>,
 6123        position: PointUtf16,
 6124        context: CompletionContext,
 6125        cx: &mut Context<Self>,
 6126    ) -> Task<Result<Vec<CompletionResponse>>> {
 6127        let language_registry = self.languages.clone();
 6128
 6129        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6130            let snapshot = buffer.read(cx).snapshot();
 6131            let offset = position.to_offset(&snapshot);
 6132            let scope = snapshot.language_scope_at(offset);
 6133            let capable_lsps = self.all_capable_for_proto_request(
 6134                buffer,
 6135                |server_name, capabilities| {
 6136                    capabilities.completion_provider.is_some()
 6137                        && scope
 6138                            .as_ref()
 6139                            .map(|scope| scope.language_allowed(server_name))
 6140                            .unwrap_or(true)
 6141                },
 6142                cx,
 6143            );
 6144            if capable_lsps.is_empty() {
 6145                return Task::ready(Ok(Vec::new()));
 6146            }
 6147
 6148            let language = buffer.read(cx).language().cloned();
 6149
 6150            // In the future, we should provide project guests with the names of LSP adapters,
 6151            // so that they can use the correct LSP adapter when computing labels. For now,
 6152            // guests just use the first LSP adapter associated with the buffer's language.
 6153            let lsp_adapter = language.as_ref().and_then(|language| {
 6154                language_registry
 6155                    .lsp_adapters(&language.name())
 6156                    .first()
 6157                    .cloned()
 6158            });
 6159
 6160            let buffer = buffer.clone();
 6161
 6162            cx.spawn(async move |this, cx| {
 6163                let requests = join_all(
 6164                    capable_lsps
 6165                        .into_iter()
 6166                        .map(|id| {
 6167                            let request = GetCompletions {
 6168                                position,
 6169                                context: context.clone(),
 6170                                server_id: Some(id),
 6171                            };
 6172                            let buffer = buffer.clone();
 6173                            let language = language.clone();
 6174                            let lsp_adapter = lsp_adapter.clone();
 6175                            let upstream_client = upstream_client.clone();
 6176                            let response = this
 6177                                .update(cx, |this, cx| {
 6178                                    this.send_lsp_proto_request(
 6179                                        buffer,
 6180                                        upstream_client,
 6181                                        project_id,
 6182                                        request,
 6183                                        cx,
 6184                                    )
 6185                                })
 6186                                .log_err();
 6187                            async move {
 6188                                let response = response?.await.log_err()?;
 6189
 6190                                let completions = populate_labels_for_completions(
 6191                                    response.completions,
 6192                                    language,
 6193                                    lsp_adapter,
 6194                                )
 6195                                .await;
 6196
 6197                                Some(CompletionResponse {
 6198                                    completions,
 6199                                    display_options: CompletionDisplayOptions::default(),
 6200                                    is_incomplete: response.is_incomplete,
 6201                                })
 6202                            }
 6203                        })
 6204                        .collect::<Vec<_>>(),
 6205                );
 6206                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6207            })
 6208        } else if let Some(local) = self.as_local() {
 6209            let snapshot = buffer.read(cx).snapshot();
 6210            let offset = position.to_offset(&snapshot);
 6211            let scope = snapshot.language_scope_at(offset);
 6212            let language = snapshot.language().cloned();
 6213            let completion_settings = language_settings(
 6214                language.as_ref().map(|language| language.name()),
 6215                buffer.read(cx).file(),
 6216                cx,
 6217            )
 6218            .completions
 6219            .clone();
 6220            if !completion_settings.lsp {
 6221                return Task::ready(Ok(Vec::new()));
 6222            }
 6223
 6224            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6225                local
 6226                    .language_servers_for_buffer(buffer, cx)
 6227                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6228                    .filter(|(adapter, _)| {
 6229                        scope
 6230                            .as_ref()
 6231                            .map(|scope| scope.language_allowed(&adapter.name))
 6232                            .unwrap_or(true)
 6233                    })
 6234                    .map(|(_, server)| server.server_id())
 6235                    .collect()
 6236            });
 6237
 6238            let buffer = buffer.clone();
 6239            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6240            let lsp_timeout = if lsp_timeout > 0 {
 6241                Some(Duration::from_millis(lsp_timeout))
 6242            } else {
 6243                None
 6244            };
 6245            cx.spawn(async move |this,  cx| {
 6246                let mut tasks = Vec::with_capacity(server_ids.len());
 6247                this.update(cx, |lsp_store, cx| {
 6248                    for server_id in server_ids {
 6249                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6250                        let lsp_timeout = lsp_timeout
 6251                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6252                        let mut timeout = cx.background_spawn(async move {
 6253                            match lsp_timeout {
 6254                                Some(lsp_timeout) => {
 6255                                    lsp_timeout.await;
 6256                                    true
 6257                                },
 6258                                None => false,
 6259                            }
 6260                        }).fuse();
 6261                        let mut lsp_request = lsp_store.request_lsp(
 6262                            buffer.clone(),
 6263                            LanguageServerToQuery::Other(server_id),
 6264                            GetCompletions {
 6265                                position,
 6266                                context: context.clone(),
 6267                                server_id: Some(server_id),
 6268                            },
 6269                            cx,
 6270                        ).fuse();
 6271                        let new_task = cx.background_spawn(async move {
 6272                            select_biased! {
 6273                                response = lsp_request => anyhow::Ok(Some(response?)),
 6274                                timeout_happened = timeout => {
 6275                                    if timeout_happened {
 6276                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6277                                        Ok(None)
 6278                                    } else {
 6279                                        let completions = lsp_request.await?;
 6280                                        Ok(Some(completions))
 6281                                    }
 6282                                },
 6283                            }
 6284                        });
 6285                        tasks.push((lsp_adapter, new_task));
 6286                    }
 6287                })?;
 6288
 6289                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6290                    let completion_response = task.await.ok()??;
 6291                    let completions = populate_labels_for_completions(
 6292                            completion_response.completions,
 6293                            language.clone(),
 6294                            lsp_adapter,
 6295                        )
 6296                        .await;
 6297                    Some(CompletionResponse {
 6298                        completions,
 6299                        display_options: CompletionDisplayOptions::default(),
 6300                        is_incomplete: completion_response.is_incomplete,
 6301                    })
 6302                });
 6303
 6304                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6305
 6306                Ok(responses.into_iter().flatten().collect())
 6307            })
 6308        } else {
 6309            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6310        }
 6311    }
 6312
 6313    pub fn resolve_completions(
 6314        &self,
 6315        buffer: Entity<Buffer>,
 6316        completion_indices: Vec<usize>,
 6317        completions: Rc<RefCell<Box<[Completion]>>>,
 6318        cx: &mut Context<Self>,
 6319    ) -> Task<Result<bool>> {
 6320        let client = self.upstream_client();
 6321        let buffer_id = buffer.read(cx).remote_id();
 6322        let buffer_snapshot = buffer.read(cx).snapshot();
 6323
 6324        if !self.check_if_capable_for_proto_request(
 6325            &buffer,
 6326            GetCompletions::can_resolve_completions,
 6327            cx,
 6328        ) {
 6329            return Task::ready(Ok(false));
 6330        }
 6331        cx.spawn(async move |lsp_store, cx| {
 6332            let request_timeout = cx.update(|app| {
 6333                ProjectSettings::get_global(app)
 6334                    .global_lsp_settings
 6335                    .get_request_timeout()
 6336            });
 6337
 6338            let mut did_resolve = false;
 6339            if let Some((client, project_id)) = client {
 6340                for completion_index in completion_indices {
 6341                    let server_id = {
 6342                        let completion = &completions.borrow()[completion_index];
 6343                        completion.source.server_id()
 6344                    };
 6345                    if let Some(server_id) = server_id {
 6346                        if Self::resolve_completion_remote(
 6347                            project_id,
 6348                            server_id,
 6349                            buffer_id,
 6350                            completions.clone(),
 6351                            completion_index,
 6352                            client.clone(),
 6353                        )
 6354                        .await
 6355                        .log_err()
 6356                        .is_some()
 6357                        {
 6358                            did_resolve = true;
 6359                        }
 6360                    } else {
 6361                        resolve_word_completion(
 6362                            &buffer_snapshot,
 6363                            &mut completions.borrow_mut()[completion_index],
 6364                        );
 6365                    }
 6366                }
 6367            } else {
 6368                for completion_index in completion_indices {
 6369                    let server_id = {
 6370                        let completion = &completions.borrow()[completion_index];
 6371                        completion.source.server_id()
 6372                    };
 6373                    if let Some(server_id) = server_id {
 6374                        let server_and_adapter = lsp_store
 6375                            .read_with(cx, |lsp_store, _| {
 6376                                let server = lsp_store.language_server_for_id(server_id)?;
 6377                                let adapter =
 6378                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6379                                Some((server, adapter))
 6380                            })
 6381                            .ok()
 6382                            .flatten();
 6383                        let Some((server, adapter)) = server_and_adapter else {
 6384                            continue;
 6385                        };
 6386
 6387                        let resolved = Self::resolve_completion_local(
 6388                            server,
 6389                            completions.clone(),
 6390                            completion_index,
 6391                            request_timeout,
 6392                        )
 6393                        .await
 6394                        .log_err()
 6395                        .is_some();
 6396                        if resolved {
 6397                            Self::regenerate_completion_labels(
 6398                                adapter,
 6399                                &buffer_snapshot,
 6400                                completions.clone(),
 6401                                completion_index,
 6402                            )
 6403                            .await
 6404                            .log_err();
 6405                            did_resolve = true;
 6406                        }
 6407                    } else {
 6408                        resolve_word_completion(
 6409                            &buffer_snapshot,
 6410                            &mut completions.borrow_mut()[completion_index],
 6411                        );
 6412                    }
 6413                }
 6414            }
 6415
 6416            Ok(did_resolve)
 6417        })
 6418    }
 6419
 6420    async fn resolve_completion_local(
 6421        server: Arc<lsp::LanguageServer>,
 6422        completions: Rc<RefCell<Box<[Completion]>>>,
 6423        completion_index: usize,
 6424        request_timeout: Duration,
 6425    ) -> Result<()> {
 6426        let server_id = server.server_id();
 6427        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6428            return Ok(());
 6429        }
 6430
 6431        let request = {
 6432            let completion = &completions.borrow()[completion_index];
 6433            match &completion.source {
 6434                CompletionSource::Lsp {
 6435                    lsp_completion,
 6436                    resolved,
 6437                    server_id: completion_server_id,
 6438                    ..
 6439                } => {
 6440                    if *resolved {
 6441                        return Ok(());
 6442                    }
 6443                    anyhow::ensure!(
 6444                        server_id == *completion_server_id,
 6445                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6446                    );
 6447                    server.request::<lsp::request::ResolveCompletionItem>(
 6448                        *lsp_completion.clone(),
 6449                        request_timeout,
 6450                    )
 6451                }
 6452                CompletionSource::BufferWord { .. }
 6453                | CompletionSource::Dap { .. }
 6454                | CompletionSource::Custom => {
 6455                    return Ok(());
 6456                }
 6457            }
 6458        };
 6459        let resolved_completion = request
 6460            .await
 6461            .into_response()
 6462            .context("resolve completion")?;
 6463
 6464        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6465        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6466
 6467        let mut completions = completions.borrow_mut();
 6468        let completion = &mut completions[completion_index];
 6469        if let CompletionSource::Lsp {
 6470            lsp_completion,
 6471            resolved,
 6472            server_id: completion_server_id,
 6473            ..
 6474        } = &mut completion.source
 6475        {
 6476            if *resolved {
 6477                return Ok(());
 6478            }
 6479            anyhow::ensure!(
 6480                server_id == *completion_server_id,
 6481                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6482            );
 6483            **lsp_completion = resolved_completion;
 6484            *resolved = true;
 6485        }
 6486        Ok(())
 6487    }
 6488
 6489    async fn regenerate_completion_labels(
 6490        adapter: Arc<CachedLspAdapter>,
 6491        snapshot: &BufferSnapshot,
 6492        completions: Rc<RefCell<Box<[Completion]>>>,
 6493        completion_index: usize,
 6494    ) -> Result<()> {
 6495        let completion_item = completions.borrow()[completion_index]
 6496            .source
 6497            .lsp_completion(true)
 6498            .map(Cow::into_owned);
 6499        if let Some(lsp_documentation) = completion_item
 6500            .as_ref()
 6501            .and_then(|completion_item| completion_item.documentation.clone())
 6502        {
 6503            let mut completions = completions.borrow_mut();
 6504            let completion = &mut completions[completion_index];
 6505            completion.documentation = Some(lsp_documentation.into());
 6506        } else {
 6507            let mut completions = completions.borrow_mut();
 6508            let completion = &mut completions[completion_index];
 6509            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6510        }
 6511
 6512        let mut new_label = match completion_item {
 6513            Some(completion_item) => {
 6514                // Some language servers always return `detail` lazily via resolve, regardless of
 6515                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6516                // See: https://github.com/yioneko/vtsls/issues/213
 6517                let language = snapshot.language();
 6518                match language {
 6519                    Some(language) => {
 6520                        adapter
 6521                            .labels_for_completions(
 6522                                std::slice::from_ref(&completion_item),
 6523                                language,
 6524                            )
 6525                            .await?
 6526                    }
 6527                    None => Vec::new(),
 6528                }
 6529                .pop()
 6530                .flatten()
 6531                .unwrap_or_else(|| {
 6532                    CodeLabel::fallback_for_completion(
 6533                        &completion_item,
 6534                        language.map(|language| language.as_ref()),
 6535                    )
 6536                })
 6537            }
 6538            None => CodeLabel::plain(
 6539                completions.borrow()[completion_index].new_text.clone(),
 6540                None,
 6541            ),
 6542        };
 6543        ensure_uniform_list_compatible_label(&mut new_label);
 6544
 6545        let mut completions = completions.borrow_mut();
 6546        let completion = &mut completions[completion_index];
 6547        if completion.label.filter_text() == new_label.filter_text() {
 6548            completion.label = new_label;
 6549        } else {
 6550            log::error!(
 6551                "Resolved completion changed display label from {} to {}. \
 6552                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6553                completion.label.text(),
 6554                new_label.text(),
 6555                completion.label.filter_text(),
 6556                new_label.filter_text()
 6557            );
 6558        }
 6559
 6560        Ok(())
 6561    }
 6562
 6563    async fn resolve_completion_remote(
 6564        project_id: u64,
 6565        server_id: LanguageServerId,
 6566        buffer_id: BufferId,
 6567        completions: Rc<RefCell<Box<[Completion]>>>,
 6568        completion_index: usize,
 6569        client: AnyProtoClient,
 6570    ) -> Result<()> {
 6571        let lsp_completion = {
 6572            let completion = &completions.borrow()[completion_index];
 6573            match &completion.source {
 6574                CompletionSource::Lsp {
 6575                    lsp_completion,
 6576                    resolved,
 6577                    server_id: completion_server_id,
 6578                    ..
 6579                } => {
 6580                    anyhow::ensure!(
 6581                        server_id == *completion_server_id,
 6582                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6583                    );
 6584                    if *resolved {
 6585                        return Ok(());
 6586                    }
 6587                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6588                }
 6589                CompletionSource::Custom
 6590                | CompletionSource::Dap { .. }
 6591                | CompletionSource::BufferWord { .. } => {
 6592                    return Ok(());
 6593                }
 6594            }
 6595        };
 6596        let request = proto::ResolveCompletionDocumentation {
 6597            project_id,
 6598            language_server_id: server_id.0 as u64,
 6599            lsp_completion,
 6600            buffer_id: buffer_id.into(),
 6601        };
 6602
 6603        let response = client
 6604            .request(request)
 6605            .await
 6606            .context("completion documentation resolve proto request")?;
 6607        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6608
 6609        let documentation = if response.documentation.is_empty() {
 6610            CompletionDocumentation::Undocumented
 6611        } else if response.documentation_is_markdown {
 6612            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6613        } else if response.documentation.lines().count() <= 1 {
 6614            CompletionDocumentation::SingleLine(response.documentation.into())
 6615        } else {
 6616            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6617        };
 6618
 6619        let mut completions = completions.borrow_mut();
 6620        let completion = &mut completions[completion_index];
 6621        completion.documentation = Some(documentation);
 6622        if let CompletionSource::Lsp {
 6623            insert_range,
 6624            lsp_completion,
 6625            resolved,
 6626            server_id: completion_server_id,
 6627            lsp_defaults: _,
 6628        } = &mut completion.source
 6629        {
 6630            let completion_insert_range = response
 6631                .old_insert_start
 6632                .and_then(deserialize_anchor)
 6633                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6634            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6635
 6636            if *resolved {
 6637                return Ok(());
 6638            }
 6639            anyhow::ensure!(
 6640                server_id == *completion_server_id,
 6641                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6642            );
 6643            **lsp_completion = resolved_lsp_completion;
 6644            *resolved = true;
 6645        }
 6646
 6647        let replace_range = response
 6648            .old_replace_start
 6649            .and_then(deserialize_anchor)
 6650            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6651        if let Some((old_replace_start, old_replace_end)) = replace_range
 6652            && !response.new_text.is_empty()
 6653        {
 6654            completion.new_text = response.new_text;
 6655            completion.replace_range = old_replace_start..old_replace_end;
 6656        }
 6657
 6658        Ok(())
 6659    }
 6660
 6661    pub fn apply_additional_edits_for_completion(
 6662        &self,
 6663        buffer_handle: Entity<Buffer>,
 6664        completions: Rc<RefCell<Box<[Completion]>>>,
 6665        completion_index: usize,
 6666        push_to_history: bool,
 6667        cx: &mut Context<Self>,
 6668    ) -> Task<Result<Option<Transaction>>> {
 6669        if let Some((client, project_id)) = self.upstream_client() {
 6670            let buffer = buffer_handle.read(cx);
 6671            let buffer_id = buffer.remote_id();
 6672            cx.spawn(async move |_, cx| {
 6673                let request = {
 6674                    let completion = completions.borrow()[completion_index].clone();
 6675                    proto::ApplyCompletionAdditionalEdits {
 6676                        project_id,
 6677                        buffer_id: buffer_id.into(),
 6678                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6679                            replace_range: completion.replace_range,
 6680                            new_text: completion.new_text,
 6681                            source: completion.source,
 6682                        })),
 6683                    }
 6684                };
 6685
 6686                let Some(transaction) = client.request(request).await?.transaction else {
 6687                    return Ok(None);
 6688                };
 6689
 6690                let transaction = language::proto::deserialize_transaction(transaction)?;
 6691                buffer_handle
 6692                    .update(cx, |buffer, _| {
 6693                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6694                    })
 6695                    .await?;
 6696                if push_to_history {
 6697                    buffer_handle.update(cx, |buffer, _| {
 6698                        buffer.push_transaction(transaction.clone(), Instant::now());
 6699                        buffer.finalize_last_transaction();
 6700                    });
 6701                }
 6702                Ok(Some(transaction))
 6703            })
 6704        } else {
 6705            let request_timeout = ProjectSettings::get_global(cx)
 6706                .global_lsp_settings
 6707                .get_request_timeout();
 6708
 6709            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6710                let completion = &completions.borrow()[completion_index];
 6711                let server_id = completion.source.server_id()?;
 6712                Some(
 6713                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6714                        .1
 6715                        .clone(),
 6716                )
 6717            }) else {
 6718                return Task::ready(Ok(None));
 6719            };
 6720
 6721            cx.spawn(async move |this, cx| {
 6722                Self::resolve_completion_local(
 6723                    server.clone(),
 6724                    completions.clone(),
 6725                    completion_index,
 6726                    request_timeout,
 6727                )
 6728                .await
 6729                .context("resolving completion")?;
 6730                let completion = completions.borrow()[completion_index].clone();
 6731                let additional_text_edits = completion
 6732                    .source
 6733                    .lsp_completion(true)
 6734                    .as_ref()
 6735                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6736                if let Some(edits) = additional_text_edits {
 6737                    let edits = this
 6738                        .update(cx, |this, cx| {
 6739                            this.as_local_mut().unwrap().edits_from_lsp(
 6740                                &buffer_handle,
 6741                                edits,
 6742                                server.server_id(),
 6743                                None,
 6744                                cx,
 6745                            )
 6746                        })?
 6747                        .await?;
 6748
 6749                    buffer_handle.update(cx, |buffer, cx| {
 6750                        buffer.finalize_last_transaction();
 6751                        buffer.start_transaction();
 6752
 6753                        for (range, text) in edits {
 6754                            let primary = &completion.replace_range;
 6755
 6756                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6757                            // and the primary completion is just an insertion (empty range), then this is likely
 6758                            // an auto-import scenario and should not be considered overlapping
 6759                            // https://github.com/zed-industries/zed/issues/26136
 6760                            let is_file_start_auto_import = {
 6761                                let snapshot = buffer.snapshot();
 6762                                let primary_start_point = primary.start.to_point(&snapshot);
 6763                                let range_start_point = range.start.to_point(&snapshot);
 6764
 6765                                let result = primary_start_point.row == 0
 6766                                    && primary_start_point.column == 0
 6767                                    && range_start_point.row == 0
 6768                                    && range_start_point.column == 0;
 6769
 6770                                result
 6771                            };
 6772
 6773                            let has_overlap = if is_file_start_auto_import {
 6774                                false
 6775                            } else {
 6776                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6777                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6778                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6779                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6780                                let result = start_within || end_within;
 6781                                result
 6782                            };
 6783
 6784                            //Skip additional edits which overlap with the primary completion edit
 6785                            //https://github.com/zed-industries/zed/pull/1871
 6786                            if !has_overlap {
 6787                                buffer.edit([(range, text)], None, cx);
 6788                            }
 6789                        }
 6790
 6791                        let transaction = if buffer.end_transaction(cx).is_some() {
 6792                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6793                            if !push_to_history {
 6794                                buffer.forget_transaction(transaction.id);
 6795                            }
 6796                            Some(transaction)
 6797                        } else {
 6798                            None
 6799                        };
 6800                        Ok(transaction)
 6801                    })
 6802                } else {
 6803                    Ok(None)
 6804                }
 6805            })
 6806        }
 6807    }
 6808
 6809    pub fn pull_diagnostics(
 6810        &mut self,
 6811        buffer: Entity<Buffer>,
 6812        cx: &mut Context<Self>,
 6813    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6814        let buffer_id = buffer.read(cx).remote_id();
 6815
 6816        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6817            let mut suitable_capabilities = None;
 6818            // Are we capable for proto request?
 6819            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6820                &buffer,
 6821                |capabilities| {
 6822                    if let Some(caps) = &capabilities.diagnostic_provider {
 6823                        suitable_capabilities = Some(caps.clone());
 6824                        true
 6825                    } else {
 6826                        false
 6827                    }
 6828                },
 6829                cx,
 6830            );
 6831            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6832            let Some(dynamic_caps) = suitable_capabilities else {
 6833                return Task::ready(Ok(None));
 6834            };
 6835            assert!(any_server_has_diagnostics_provider);
 6836
 6837            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6838            let request = GetDocumentDiagnostics {
 6839                previous_result_id: None,
 6840                identifier,
 6841                registration_id: None,
 6842            };
 6843            let request_timeout = ProjectSettings::get_global(cx)
 6844                .global_lsp_settings
 6845                .get_request_timeout();
 6846            let request_task = client.request_lsp(
 6847                upstream_project_id,
 6848                None,
 6849                request_timeout,
 6850                cx.background_executor().clone(),
 6851                request.to_proto(upstream_project_id, buffer.read(cx)),
 6852            );
 6853            cx.background_spawn(async move {
 6854                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6855                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6856                // Do not attempt to further process the dummy responses here.
 6857                let _response = request_task.await?;
 6858                Ok(None)
 6859            })
 6860        } else {
 6861            let servers = buffer.update(cx, |buffer, cx| {
 6862                self.running_language_servers_for_local_buffer(buffer, cx)
 6863                    .map(|(_, server)| server.clone())
 6864                    .collect::<Vec<_>>()
 6865            });
 6866
 6867            let pull_diagnostics = servers
 6868                .into_iter()
 6869                .flat_map(|server| {
 6870                    let result = maybe!({
 6871                        let local = self.as_local()?;
 6872                        let server_id = server.server_id();
 6873                        let providers_with_identifiers = local
 6874                            .language_server_dynamic_registrations
 6875                            .get(&server_id)
 6876                            .into_iter()
 6877                            .flat_map(|registrations| registrations.diagnostics.clone())
 6878                            .collect::<Vec<_>>();
 6879                        Some(
 6880                            providers_with_identifiers
 6881                                .into_iter()
 6882                                .map(|(registration_id, dynamic_caps)| {
 6883                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6884                                    let registration_id = registration_id.map(SharedString::from);
 6885                                    let result_id = self.result_id_for_buffer_pull(
 6886                                        server_id,
 6887                                        buffer_id,
 6888                                        &registration_id,
 6889                                        cx,
 6890                                    );
 6891                                    self.request_lsp(
 6892                                        buffer.clone(),
 6893                                        LanguageServerToQuery::Other(server_id),
 6894                                        GetDocumentDiagnostics {
 6895                                            previous_result_id: result_id,
 6896                                            registration_id,
 6897                                            identifier,
 6898                                        },
 6899                                        cx,
 6900                                    )
 6901                                })
 6902                                .collect::<Vec<_>>(),
 6903                        )
 6904                    });
 6905
 6906                    result.unwrap_or_default()
 6907                })
 6908                .collect::<Vec<_>>();
 6909
 6910            cx.background_spawn(async move {
 6911                let mut responses = Vec::new();
 6912                for diagnostics in join_all(pull_diagnostics).await {
 6913                    responses.extend(diagnostics?);
 6914                }
 6915                Ok(Some(responses))
 6916            })
 6917        }
 6918    }
 6919
 6920    pub fn applicable_inlay_chunks(
 6921        &mut self,
 6922        buffer: &Entity<Buffer>,
 6923        ranges: &[Range<text::Anchor>],
 6924        cx: &mut Context<Self>,
 6925    ) -> Vec<Range<BufferRow>> {
 6926        let buffer_snapshot = buffer.read(cx).snapshot();
 6927        let ranges = ranges
 6928            .iter()
 6929            .map(|range| range.to_point(&buffer_snapshot))
 6930            .collect::<Vec<_>>();
 6931
 6932        self.latest_lsp_data(buffer, cx)
 6933            .inlay_hints
 6934            .applicable_chunks(ranges.as_slice())
 6935            .map(|chunk| chunk.row_range())
 6936            .collect()
 6937    }
 6938
 6939    pub fn invalidate_inlay_hints<'a>(
 6940        &'a mut self,
 6941        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6942    ) {
 6943        for buffer_id in for_buffers {
 6944            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6945                lsp_data.inlay_hints.clear();
 6946            }
 6947        }
 6948    }
 6949
 6950    pub fn inlay_hints(
 6951        &mut self,
 6952        invalidate: InvalidationStrategy,
 6953        buffer: Entity<Buffer>,
 6954        ranges: Vec<Range<text::Anchor>>,
 6955        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6956        cx: &mut Context<Self>,
 6957    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6958        let next_hint_id = self.next_hint_id.clone();
 6959        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6960        let query_version = lsp_data.buffer_version.clone();
 6961        let mut lsp_refresh_requested = false;
 6962        let for_server = if let InvalidationStrategy::RefreshRequested {
 6963            server_id,
 6964            request_id,
 6965        } = invalidate
 6966        {
 6967            let invalidated = lsp_data
 6968                .inlay_hints
 6969                .invalidate_for_server_refresh(server_id, request_id);
 6970            lsp_refresh_requested = invalidated;
 6971            Some(server_id)
 6972        } else {
 6973            None
 6974        };
 6975        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6976        let known_chunks = known_chunks
 6977            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6978            .map(|(_, known_chunks)| known_chunks)
 6979            .unwrap_or_default();
 6980
 6981        let buffer_snapshot = buffer.read(cx).snapshot();
 6982        let ranges = ranges
 6983            .iter()
 6984            .map(|range| range.to_point(&buffer_snapshot))
 6985            .collect::<Vec<_>>();
 6986
 6987        let mut hint_fetch_tasks = Vec::new();
 6988        let mut cached_inlay_hints = None;
 6989        let mut ranges_to_query = None;
 6990        let applicable_chunks = existing_inlay_hints
 6991            .applicable_chunks(ranges.as_slice())
 6992            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 6993            .collect::<Vec<_>>();
 6994        if applicable_chunks.is_empty() {
 6995            return HashMap::default();
 6996        }
 6997
 6998        for row_chunk in applicable_chunks {
 6999            match (
 7000                existing_inlay_hints
 7001                    .cached_hints(&row_chunk)
 7002                    .filter(|_| !lsp_refresh_requested)
 7003                    .cloned(),
 7004                existing_inlay_hints
 7005                    .fetched_hints(&row_chunk)
 7006                    .as_ref()
 7007                    .filter(|_| !lsp_refresh_requested)
 7008                    .cloned(),
 7009            ) {
 7010                (None, None) => {
 7011                    let chunk_range = row_chunk.anchor_range();
 7012                    ranges_to_query
 7013                        .get_or_insert_with(Vec::new)
 7014                        .push((row_chunk, chunk_range));
 7015                }
 7016                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7017                (Some(cached_hints), None) => {
 7018                    for (server_id, cached_hints) in cached_hints {
 7019                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7020                            cached_inlay_hints
 7021                                .get_or_insert_with(HashMap::default)
 7022                                .entry(row_chunk.row_range())
 7023                                .or_insert_with(HashMap::default)
 7024                                .entry(server_id)
 7025                                .or_insert_with(Vec::new)
 7026                                .extend(cached_hints);
 7027                        }
 7028                    }
 7029                }
 7030                (Some(cached_hints), Some(fetched_hints)) => {
 7031                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7032                    for (server_id, cached_hints) in cached_hints {
 7033                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7034                            cached_inlay_hints
 7035                                .get_or_insert_with(HashMap::default)
 7036                                .entry(row_chunk.row_range())
 7037                                .or_insert_with(HashMap::default)
 7038                                .entry(server_id)
 7039                                .or_insert_with(Vec::new)
 7040                                .extend(cached_hints);
 7041                        }
 7042                    }
 7043                }
 7044            }
 7045        }
 7046
 7047        if hint_fetch_tasks.is_empty()
 7048            && ranges_to_query
 7049                .as_ref()
 7050                .is_none_or(|ranges| ranges.is_empty())
 7051            && let Some(cached_inlay_hints) = cached_inlay_hints
 7052        {
 7053            cached_inlay_hints
 7054                .into_iter()
 7055                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7056                .collect()
 7057        } else {
 7058            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7059                let next_hint_id = next_hint_id.clone();
 7060                let buffer = buffer.clone();
 7061                let query_version = query_version.clone();
 7062                let new_inlay_hints = cx
 7063                    .spawn(async move |lsp_store, cx| {
 7064                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7065                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7066                        })?;
 7067                        new_fetch_task
 7068                            .await
 7069                            .and_then(|new_hints_by_server| {
 7070                                lsp_store.update(cx, |lsp_store, cx| {
 7071                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7072                                    let update_cache = lsp_data.buffer_version == query_version;
 7073                                    if new_hints_by_server.is_empty() {
 7074                                        if update_cache {
 7075                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7076                                        }
 7077                                        HashMap::default()
 7078                                    } else {
 7079                                        new_hints_by_server
 7080                                            .into_iter()
 7081                                            .map(|(server_id, new_hints)| {
 7082                                                let new_hints = new_hints
 7083                                                    .into_iter()
 7084                                                    .map(|new_hint| {
 7085                                                        (
 7086                                                            InlayId::Hint(next_hint_id.fetch_add(
 7087                                                                1,
 7088                                                                atomic::Ordering::AcqRel,
 7089                                                            )),
 7090                                                            new_hint,
 7091                                                        )
 7092                                                    })
 7093                                                    .collect::<Vec<_>>();
 7094                                                if update_cache {
 7095                                                    lsp_data.inlay_hints.insert_new_hints(
 7096                                                        chunk,
 7097                                                        server_id,
 7098                                                        new_hints.clone(),
 7099                                                    );
 7100                                                }
 7101                                                (server_id, new_hints)
 7102                                            })
 7103                                            .collect()
 7104                                    }
 7105                                })
 7106                            })
 7107                            .map_err(Arc::new)
 7108                    })
 7109                    .shared();
 7110
 7111                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7112                *fetch_task = Some(new_inlay_hints.clone());
 7113                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7114            }
 7115
 7116            cached_inlay_hints
 7117                .unwrap_or_default()
 7118                .into_iter()
 7119                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7120                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7121                    (
 7122                        chunk.row_range(),
 7123                        cx.spawn(async move |_, _| {
 7124                            hints_fetch.await.map_err(|e| {
 7125                                if e.error_code() != ErrorCode::Internal {
 7126                                    anyhow!(e.error_code())
 7127                                } else {
 7128                                    anyhow!("{e:#}")
 7129                                }
 7130                            })
 7131                        }),
 7132                    )
 7133                }))
 7134                .collect()
 7135        }
 7136    }
 7137
 7138    fn fetch_inlay_hints(
 7139        &mut self,
 7140        for_server: Option<LanguageServerId>,
 7141        buffer: &Entity<Buffer>,
 7142        range: Range<Anchor>,
 7143        cx: &mut Context<Self>,
 7144    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7145        let request = InlayHints {
 7146            range: range.clone(),
 7147        };
 7148        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7149            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7150                return Task::ready(Ok(HashMap::default()));
 7151            }
 7152            let request_timeout = ProjectSettings::get_global(cx)
 7153                .global_lsp_settings
 7154                .get_request_timeout();
 7155            let request_task = upstream_client.request_lsp(
 7156                project_id,
 7157                for_server.map(|id| id.to_proto()),
 7158                request_timeout,
 7159                cx.background_executor().clone(),
 7160                request.to_proto(project_id, buffer.read(cx)),
 7161            );
 7162            let buffer = buffer.clone();
 7163            cx.spawn(async move |weak_lsp_store, cx| {
 7164                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7165                    return Ok(HashMap::default());
 7166                };
 7167                let Some(responses) = request_task.await? else {
 7168                    return Ok(HashMap::default());
 7169                };
 7170
 7171                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7172                    let lsp_store = lsp_store.clone();
 7173                    let buffer = buffer.clone();
 7174                    let cx = cx.clone();
 7175                    let request = request.clone();
 7176                    async move {
 7177                        (
 7178                            LanguageServerId::from_proto(response.server_id),
 7179                            request
 7180                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7181                                .await,
 7182                        )
 7183                    }
 7184                }))
 7185                .await;
 7186
 7187                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7188                let mut has_errors = false;
 7189                let inlay_hints = inlay_hints
 7190                    .into_iter()
 7191                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7192                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7193                        Err(e) => {
 7194                            has_errors = true;
 7195                            log::error!("{e:#}");
 7196                            None
 7197                        }
 7198                    })
 7199                    .map(|(server_id, mut new_hints)| {
 7200                        new_hints.retain(|hint| {
 7201                            hint.position.is_valid(&buffer_snapshot)
 7202                                && range.start.is_valid(&buffer_snapshot)
 7203                                && range.end.is_valid(&buffer_snapshot)
 7204                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7205                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7206                        });
 7207                        (server_id, new_hints)
 7208                    })
 7209                    .collect::<HashMap<_, _>>();
 7210                anyhow::ensure!(
 7211                    !has_errors || !inlay_hints.is_empty(),
 7212                    "Failed to fetch inlay hints"
 7213                );
 7214                Ok(inlay_hints)
 7215            })
 7216        } else {
 7217            let inlay_hints_task = match for_server {
 7218                Some(server_id) => {
 7219                    let server_task = self.request_lsp(
 7220                        buffer.clone(),
 7221                        LanguageServerToQuery::Other(server_id),
 7222                        request,
 7223                        cx,
 7224                    );
 7225                    cx.background_spawn(async move {
 7226                        let mut responses = Vec::new();
 7227                        match server_task.await {
 7228                            Ok(response) => responses.push((server_id, response)),
 7229                            // rust-analyzer likes to error with this when its still loading up
 7230                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7231                            Err(e) => log::error!(
 7232                                "Error handling response for inlay hints request: {e:#}"
 7233                            ),
 7234                        }
 7235                        responses
 7236                    })
 7237                }
 7238                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7239            };
 7240            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7241            cx.background_spawn(async move {
 7242                Ok(inlay_hints_task
 7243                    .await
 7244                    .into_iter()
 7245                    .map(|(server_id, mut new_hints)| {
 7246                        new_hints.retain(|hint| {
 7247                            hint.position.is_valid(&buffer_snapshot)
 7248                                && range.start.is_valid(&buffer_snapshot)
 7249                                && range.end.is_valid(&buffer_snapshot)
 7250                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7251                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7252                        });
 7253                        (server_id, new_hints)
 7254                    })
 7255                    .collect())
 7256            })
 7257        }
 7258    }
 7259
 7260    fn diagnostic_registration_exists(
 7261        &self,
 7262        server_id: LanguageServerId,
 7263        registration_id: &Option<SharedString>,
 7264    ) -> bool {
 7265        let Some(local) = self.as_local() else {
 7266            return false;
 7267        };
 7268        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7269        else {
 7270            return false;
 7271        };
 7272        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7273        registrations.diagnostics.contains_key(&registration_key)
 7274    }
 7275
 7276    pub fn pull_diagnostics_for_buffer(
 7277        &mut self,
 7278        buffer: Entity<Buffer>,
 7279        cx: &mut Context<Self>,
 7280    ) -> Task<anyhow::Result<()>> {
 7281        let diagnostics = self.pull_diagnostics(buffer, cx);
 7282        cx.spawn(async move |lsp_store, cx| {
 7283            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7284                return Ok(());
 7285            };
 7286            lsp_store.update(cx, |lsp_store, cx| {
 7287                if lsp_store.as_local().is_none() {
 7288                    return;
 7289                }
 7290
 7291                let mut unchanged_buffers = HashMap::default();
 7292                let server_diagnostics_updates = diagnostics
 7293                    .into_iter()
 7294                    .filter_map(|diagnostics_set| match diagnostics_set {
 7295                        LspPullDiagnostics::Response {
 7296                            server_id,
 7297                            uri,
 7298                            diagnostics,
 7299                            registration_id,
 7300                        } => Some((server_id, uri, diagnostics, registration_id)),
 7301                        LspPullDiagnostics::Default => None,
 7302                    })
 7303                    .filter(|(server_id, _, _, registration_id)| {
 7304                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7305                    })
 7306                    .fold(
 7307                        HashMap::default(),
 7308                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7309                            let (result_id, diagnostics) = match diagnostics {
 7310                                PulledDiagnostics::Unchanged { result_id } => {
 7311                                    unchanged_buffers
 7312                                        .entry(new_registration_id.clone())
 7313                                        .or_insert_with(HashSet::default)
 7314                                        .insert(uri.clone());
 7315                                    (Some(result_id), Vec::new())
 7316                                }
 7317                                PulledDiagnostics::Changed {
 7318                                    result_id,
 7319                                    diagnostics,
 7320                                } => (result_id, diagnostics),
 7321                            };
 7322                            let disk_based_sources = Cow::Owned(
 7323                                lsp_store
 7324                                    .language_server_adapter_for_id(server_id)
 7325                                    .as_ref()
 7326                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7327                                    .unwrap_or(&[])
 7328                                    .to_vec(),
 7329                            );
 7330                            acc.entry(server_id)
 7331                                .or_insert_with(HashMap::default)
 7332                                .entry(new_registration_id.clone())
 7333                                .or_insert_with(Vec::new)
 7334                                .push(DocumentDiagnosticsUpdate {
 7335                                    server_id,
 7336                                    diagnostics: lsp::PublishDiagnosticsParams {
 7337                                        uri,
 7338                                        diagnostics,
 7339                                        version: None,
 7340                                    },
 7341                                    result_id: result_id.map(SharedString::new),
 7342                                    disk_based_sources,
 7343                                    registration_id: new_registration_id,
 7344                                });
 7345                            acc
 7346                        },
 7347                    );
 7348
 7349                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7350                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7351                        lsp_store
 7352                            .merge_lsp_diagnostics(
 7353                                DiagnosticSourceKind::Pulled,
 7354                                diagnostic_updates,
 7355                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7356                                    DiagnosticSourceKind::Pulled => {
 7357                                        old_diagnostic.registration_id != registration_id
 7358                                            || unchanged_buffers
 7359                                                .get(&old_diagnostic.registration_id)
 7360                                                .is_some_and(|unchanged_buffers| {
 7361                                                    unchanged_buffers.contains(&document_uri)
 7362                                                })
 7363                                    }
 7364                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7365                                        true
 7366                                    }
 7367                                },
 7368                                cx,
 7369                            )
 7370                            .log_err();
 7371                    }
 7372                }
 7373            })
 7374        })
 7375    }
 7376
 7377    pub fn signature_help<T: ToPointUtf16>(
 7378        &mut self,
 7379        buffer: &Entity<Buffer>,
 7380        position: T,
 7381        cx: &mut Context<Self>,
 7382    ) -> Task<Option<Vec<SignatureHelp>>> {
 7383        let position = position.to_point_utf16(buffer.read(cx));
 7384
 7385        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7386            let request = GetSignatureHelp { position };
 7387            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7388                return Task::ready(None);
 7389            }
 7390            let request_timeout = ProjectSettings::get_global(cx)
 7391                .global_lsp_settings
 7392                .get_request_timeout();
 7393            let request_task = client.request_lsp(
 7394                upstream_project_id,
 7395                None,
 7396                request_timeout,
 7397                cx.background_executor().clone(),
 7398                request.to_proto(upstream_project_id, buffer.read(cx)),
 7399            );
 7400            let buffer = buffer.clone();
 7401            cx.spawn(async move |weak_lsp_store, cx| {
 7402                let lsp_store = weak_lsp_store.upgrade()?;
 7403                let signatures = join_all(
 7404                    request_task
 7405                        .await
 7406                        .log_err()
 7407                        .flatten()
 7408                        .map(|response| response.payload)
 7409                        .unwrap_or_default()
 7410                        .into_iter()
 7411                        .map(|response| {
 7412                            let response = GetSignatureHelp { position }.response_from_proto(
 7413                                response.response,
 7414                                lsp_store.clone(),
 7415                                buffer.clone(),
 7416                                cx.clone(),
 7417                            );
 7418                            async move { response.await.log_err().flatten() }
 7419                        }),
 7420                )
 7421                .await
 7422                .into_iter()
 7423                .flatten()
 7424                .collect();
 7425                Some(signatures)
 7426            })
 7427        } else {
 7428            let all_actions_task = self.request_multiple_lsp_locally(
 7429                buffer,
 7430                Some(position),
 7431                GetSignatureHelp { position },
 7432                cx,
 7433            );
 7434            cx.background_spawn(async move {
 7435                Some(
 7436                    all_actions_task
 7437                        .await
 7438                        .into_iter()
 7439                        .flat_map(|(_, actions)| actions)
 7440                        .collect::<Vec<_>>(),
 7441                )
 7442            })
 7443        }
 7444    }
 7445
 7446    pub fn hover(
 7447        &mut self,
 7448        buffer: &Entity<Buffer>,
 7449        position: PointUtf16,
 7450        cx: &mut Context<Self>,
 7451    ) -> Task<Option<Vec<Hover>>> {
 7452        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7453            let request = GetHover { position };
 7454            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7455                return Task::ready(None);
 7456            }
 7457            let request_timeout = ProjectSettings::get_global(cx)
 7458                .global_lsp_settings
 7459                .get_request_timeout();
 7460            let request_task = client.request_lsp(
 7461                upstream_project_id,
 7462                None,
 7463                request_timeout,
 7464                cx.background_executor().clone(),
 7465                request.to_proto(upstream_project_id, buffer.read(cx)),
 7466            );
 7467            let buffer = buffer.clone();
 7468            cx.spawn(async move |weak_lsp_store, cx| {
 7469                let lsp_store = weak_lsp_store.upgrade()?;
 7470                let hovers = join_all(
 7471                    request_task
 7472                        .await
 7473                        .log_err()
 7474                        .flatten()
 7475                        .map(|response| response.payload)
 7476                        .unwrap_or_default()
 7477                        .into_iter()
 7478                        .map(|response| {
 7479                            let response = GetHover { position }.response_from_proto(
 7480                                response.response,
 7481                                lsp_store.clone(),
 7482                                buffer.clone(),
 7483                                cx.clone(),
 7484                            );
 7485                            async move {
 7486                                response
 7487                                    .await
 7488                                    .log_err()
 7489                                    .flatten()
 7490                                    .and_then(remove_empty_hover_blocks)
 7491                            }
 7492                        }),
 7493                )
 7494                .await
 7495                .into_iter()
 7496                .flatten()
 7497                .collect();
 7498                Some(hovers)
 7499            })
 7500        } else {
 7501            let all_actions_task = self.request_multiple_lsp_locally(
 7502                buffer,
 7503                Some(position),
 7504                GetHover { position },
 7505                cx,
 7506            );
 7507            cx.background_spawn(async move {
 7508                Some(
 7509                    all_actions_task
 7510                        .await
 7511                        .into_iter()
 7512                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7513                        .collect::<Vec<Hover>>(),
 7514                )
 7515            })
 7516        }
 7517    }
 7518
 7519    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7520        let language_registry = self.languages.clone();
 7521
 7522        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7523            let request = upstream_client.request(proto::GetProjectSymbols {
 7524                project_id: *project_id,
 7525                query: query.to_string(),
 7526            });
 7527            cx.foreground_executor().spawn(async move {
 7528                let response = request.await?;
 7529                let mut symbols = Vec::new();
 7530                let core_symbols = response
 7531                    .symbols
 7532                    .into_iter()
 7533                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7534                    .collect::<Vec<_>>();
 7535                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7536                    .await;
 7537                Ok(symbols)
 7538            })
 7539        } else if let Some(local) = self.as_local() {
 7540            struct WorkspaceSymbolsResult {
 7541                server_id: LanguageServerId,
 7542                lsp_adapter: Arc<CachedLspAdapter>,
 7543                worktree: WeakEntity<Worktree>,
 7544                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7545            }
 7546
 7547            let mut requests = Vec::new();
 7548            let mut requested_servers = BTreeSet::new();
 7549            let request_timeout = ProjectSettings::get_global(cx)
 7550                .global_lsp_settings
 7551                .get_request_timeout();
 7552
 7553            for (seed, state) in local.language_server_ids.iter() {
 7554                let Some(worktree_handle) = self
 7555                    .worktree_store
 7556                    .read(cx)
 7557                    .worktree_for_id(seed.worktree_id, cx)
 7558                else {
 7559                    continue;
 7560                };
 7561
 7562                let worktree = worktree_handle.read(cx);
 7563                if !worktree.is_visible() {
 7564                    continue;
 7565                }
 7566
 7567                if !requested_servers.insert(state.id) {
 7568                    continue;
 7569                }
 7570
 7571                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7572                    Some(LanguageServerState::Running {
 7573                        adapter, server, ..
 7574                    }) => (adapter.clone(), server),
 7575
 7576                    _ => continue,
 7577                };
 7578
 7579                let supports_workspace_symbol_request =
 7580                    match server.capabilities().workspace_symbol_provider {
 7581                        Some(OneOf::Left(supported)) => supported,
 7582                        Some(OneOf::Right(_)) => true,
 7583                        None => false,
 7584                    };
 7585
 7586                if !supports_workspace_symbol_request {
 7587                    continue;
 7588                }
 7589
 7590                let worktree_handle = worktree_handle.clone();
 7591                let server_id = server.server_id();
 7592                requests.push(
 7593                    server
 7594                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7595                            lsp::WorkspaceSymbolParams {
 7596                                query: query.to_string(),
 7597                                ..Default::default()
 7598                            },
 7599                            request_timeout,
 7600                        )
 7601                        .map(move |response| {
 7602                            let lsp_symbols = response
 7603                                .into_response()
 7604                                .context("workspace symbols request")
 7605                                .log_err()
 7606                                .flatten()
 7607                                .map(|symbol_response| match symbol_response {
 7608                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7609                                        flat_responses
 7610                                            .into_iter()
 7611                                            .map(|lsp_symbol| {
 7612                                                (
 7613                                                    lsp_symbol.name,
 7614                                                    lsp_symbol.kind,
 7615                                                    lsp_symbol.location,
 7616                                                    lsp_symbol.container_name,
 7617                                                )
 7618                                            })
 7619                                            .collect::<Vec<_>>()
 7620                                    }
 7621                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7622                                        nested_responses
 7623                                            .into_iter()
 7624                                            .filter_map(|lsp_symbol| {
 7625                                                let location = match lsp_symbol.location {
 7626                                                    OneOf::Left(location) => location,
 7627                                                    OneOf::Right(_) => {
 7628                                                        log::error!(
 7629                                                            "Unexpected: client capabilities \
 7630                                                            forbid symbol resolutions in \
 7631                                                            workspace.symbol.resolveSupport"
 7632                                                        );
 7633                                                        return None;
 7634                                                    }
 7635                                                };
 7636                                                Some((
 7637                                                    lsp_symbol.name,
 7638                                                    lsp_symbol.kind,
 7639                                                    location,
 7640                                                    lsp_symbol.container_name,
 7641                                                ))
 7642                                            })
 7643                                            .collect::<Vec<_>>()
 7644                                    }
 7645                                })
 7646                                .unwrap_or_default();
 7647
 7648                            WorkspaceSymbolsResult {
 7649                                server_id,
 7650                                lsp_adapter,
 7651                                worktree: worktree_handle.downgrade(),
 7652                                lsp_symbols,
 7653                            }
 7654                        }),
 7655                );
 7656            }
 7657
 7658            cx.spawn(async move |this, cx| {
 7659                let responses = futures::future::join_all(requests).await;
 7660                let this = match this.upgrade() {
 7661                    Some(this) => this,
 7662                    None => return Ok(Vec::new()),
 7663                };
 7664
 7665                let mut symbols = Vec::new();
 7666                for result in responses {
 7667                    let core_symbols = this.update(cx, |this, cx| {
 7668                        result
 7669                            .lsp_symbols
 7670                            .into_iter()
 7671                            .filter_map(
 7672                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7673                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7674                                    let source_worktree = result.worktree.upgrade()?;
 7675                                    let source_worktree_id = source_worktree.read(cx).id();
 7676
 7677                                    let path = if let Some((tree, rel_path)) =
 7678                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7679                                    {
 7680                                        let worktree_id = tree.read(cx).id();
 7681                                        SymbolLocation::InProject(ProjectPath {
 7682                                            worktree_id,
 7683                                            path: rel_path,
 7684                                        })
 7685                                    } else {
 7686                                        SymbolLocation::OutsideProject {
 7687                                            signature: this.symbol_signature(&abs_path),
 7688                                            abs_path: abs_path.into(),
 7689                                        }
 7690                                    };
 7691
 7692                                    Some(CoreSymbol {
 7693                                        source_language_server_id: result.server_id,
 7694                                        language_server_name: result.lsp_adapter.name.clone(),
 7695                                        source_worktree_id,
 7696                                        path,
 7697                                        kind: symbol_kind,
 7698                                        name: collapse_newlines(&symbol_name, ""),
 7699                                        range: range_from_lsp(symbol_location.range),
 7700                                        container_name: container_name
 7701                                            .map(|c| collapse_newlines(&c, "")),
 7702                                    })
 7703                                },
 7704                            )
 7705                            .collect::<Vec<_>>()
 7706                    });
 7707
 7708                    populate_labels_for_symbols(
 7709                        core_symbols,
 7710                        &language_registry,
 7711                        Some(result.lsp_adapter),
 7712                        &mut symbols,
 7713                    )
 7714                    .await;
 7715                }
 7716
 7717                Ok(symbols)
 7718            })
 7719        } else {
 7720            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7721        }
 7722    }
 7723
 7724    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7725        let mut summary = DiagnosticSummary::default();
 7726        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7727            summary.error_count += path_summary.error_count;
 7728            summary.warning_count += path_summary.warning_count;
 7729        }
 7730        summary
 7731    }
 7732
 7733    /// Returns the diagnostic summary for a specific project path.
 7734    pub fn diagnostic_summary_for_path(
 7735        &self,
 7736        project_path: &ProjectPath,
 7737        _: &App,
 7738    ) -> DiagnosticSummary {
 7739        if let Some(summaries) = self
 7740            .diagnostic_summaries
 7741            .get(&project_path.worktree_id)
 7742            .and_then(|map| map.get(&project_path.path))
 7743        {
 7744            let (error_count, warning_count) = summaries.iter().fold(
 7745                (0, 0),
 7746                |(error_count, warning_count), (_language_server_id, summary)| {
 7747                    (
 7748                        error_count + summary.error_count,
 7749                        warning_count + summary.warning_count,
 7750                    )
 7751                },
 7752            );
 7753
 7754            DiagnosticSummary {
 7755                error_count,
 7756                warning_count,
 7757            }
 7758        } else {
 7759            DiagnosticSummary::default()
 7760        }
 7761    }
 7762
 7763    pub fn diagnostic_summaries<'a>(
 7764        &'a self,
 7765        include_ignored: bool,
 7766        cx: &'a App,
 7767    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7768        self.worktree_store
 7769            .read(cx)
 7770            .visible_worktrees(cx)
 7771            .filter_map(|worktree| {
 7772                let worktree = worktree.read(cx);
 7773                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7774            })
 7775            .flat_map(move |(worktree, summaries)| {
 7776                let worktree_id = worktree.id();
 7777                summaries
 7778                    .iter()
 7779                    .filter(move |(path, _)| {
 7780                        include_ignored
 7781                            || worktree
 7782                                .entry_for_path(path.as_ref())
 7783                                .is_some_and(|entry| !entry.is_ignored)
 7784                    })
 7785                    .flat_map(move |(path, summaries)| {
 7786                        summaries.iter().map(move |(server_id, summary)| {
 7787                            (
 7788                                ProjectPath {
 7789                                    worktree_id,
 7790                                    path: path.clone(),
 7791                                },
 7792                                *server_id,
 7793                                *summary,
 7794                            )
 7795                        })
 7796                    })
 7797            })
 7798    }
 7799
 7800    pub fn on_buffer_edited(
 7801        &mut self,
 7802        buffer: Entity<Buffer>,
 7803        cx: &mut Context<Self>,
 7804    ) -> Option<()> {
 7805        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7806            Some(
 7807                self.as_local()?
 7808                    .language_servers_for_buffer(buffer, cx)
 7809                    .map(|i| i.1.clone())
 7810                    .collect(),
 7811            )
 7812        })?;
 7813
 7814        let buffer = buffer.read(cx);
 7815        let file = File::from_dyn(buffer.file())?;
 7816        let abs_path = file.as_local()?.abs_path(cx);
 7817        let uri = lsp::Uri::from_file_path(&abs_path)
 7818            .ok()
 7819            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7820            .log_err()?;
 7821        let next_snapshot = buffer.text_snapshot();
 7822        for language_server in language_servers {
 7823            let language_server = language_server.clone();
 7824
 7825            let buffer_snapshots = self
 7826                .as_local_mut()?
 7827                .buffer_snapshots
 7828                .get_mut(&buffer.remote_id())
 7829                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7830            let previous_snapshot = buffer_snapshots.last()?;
 7831
 7832            let build_incremental_change = || {
 7833                buffer
 7834                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7835                        previous_snapshot.snapshot.version(),
 7836                    )
 7837                    .map(|edit| {
 7838                        let edit_start = edit.new.start.0;
 7839                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7840                        let new_text = next_snapshot
 7841                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7842                            .collect();
 7843                        lsp::TextDocumentContentChangeEvent {
 7844                            range: Some(lsp::Range::new(
 7845                                point_to_lsp(edit_start),
 7846                                point_to_lsp(edit_end),
 7847                            )),
 7848                            range_length: None,
 7849                            text: new_text,
 7850                        }
 7851                    })
 7852                    .collect()
 7853            };
 7854
 7855            let document_sync_kind = language_server
 7856                .capabilities()
 7857                .text_document_sync
 7858                .as_ref()
 7859                .and_then(|sync| match sync {
 7860                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7861                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7862                });
 7863
 7864            let content_changes: Vec<_> = match document_sync_kind {
 7865                Some(lsp::TextDocumentSyncKind::FULL) => {
 7866                    vec![lsp::TextDocumentContentChangeEvent {
 7867                        range: None,
 7868                        range_length: None,
 7869                        text: next_snapshot.text(),
 7870                    }]
 7871                }
 7872                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7873                _ => {
 7874                    #[cfg(any(test, feature = "test-support"))]
 7875                    {
 7876                        build_incremental_change()
 7877                    }
 7878
 7879                    #[cfg(not(any(test, feature = "test-support")))]
 7880                    {
 7881                        continue;
 7882                    }
 7883                }
 7884            };
 7885
 7886            let next_version = previous_snapshot.version + 1;
 7887            buffer_snapshots.push(LspBufferSnapshot {
 7888                version: next_version,
 7889                snapshot: next_snapshot.clone(),
 7890            });
 7891
 7892            language_server
 7893                .notify::<lsp::notification::DidChangeTextDocument>(
 7894                    lsp::DidChangeTextDocumentParams {
 7895                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7896                            uri.clone(),
 7897                            next_version,
 7898                        ),
 7899                        content_changes,
 7900                    },
 7901                )
 7902                .ok();
 7903            self.pull_workspace_diagnostics(language_server.server_id());
 7904        }
 7905
 7906        None
 7907    }
 7908
 7909    pub fn on_buffer_saved(
 7910        &mut self,
 7911        buffer: Entity<Buffer>,
 7912        cx: &mut Context<Self>,
 7913    ) -> Option<()> {
 7914        let file = File::from_dyn(buffer.read(cx).file())?;
 7915        let worktree_id = file.worktree_id(cx);
 7916        let abs_path = file.as_local()?.abs_path(cx);
 7917        let text_document = lsp::TextDocumentIdentifier {
 7918            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7919        };
 7920        let local = self.as_local()?;
 7921
 7922        for server in local.language_servers_for_worktree(worktree_id) {
 7923            if let Some(include_text) = include_text(server.as_ref()) {
 7924                let text = if include_text {
 7925                    Some(buffer.read(cx).text())
 7926                } else {
 7927                    None
 7928                };
 7929                server
 7930                    .notify::<lsp::notification::DidSaveTextDocument>(
 7931                        lsp::DidSaveTextDocumentParams {
 7932                            text_document: text_document.clone(),
 7933                            text,
 7934                        },
 7935                    )
 7936                    .ok();
 7937            }
 7938        }
 7939
 7940        let language_servers = buffer.update(cx, |buffer, cx| {
 7941            local.language_server_ids_for_buffer(buffer, cx)
 7942        });
 7943        for language_server_id in language_servers {
 7944            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7945        }
 7946
 7947        None
 7948    }
 7949
 7950    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7951        maybe!(async move {
 7952            let mut refreshed_servers = HashSet::default();
 7953            let servers = lsp_store
 7954                .update(cx, |lsp_store, cx| {
 7955                    let local = lsp_store.as_local()?;
 7956
 7957                    let servers = local
 7958                        .language_server_ids
 7959                        .iter()
 7960                        .filter_map(|(seed, state)| {
 7961                            let worktree = lsp_store
 7962                                .worktree_store
 7963                                .read(cx)
 7964                                .worktree_for_id(seed.worktree_id, cx);
 7965                            let delegate: Arc<dyn LspAdapterDelegate> =
 7966                                worktree.map(|worktree| {
 7967                                    LocalLspAdapterDelegate::new(
 7968                                        local.languages.clone(),
 7969                                        &local.environment,
 7970                                        cx.weak_entity(),
 7971                                        &worktree,
 7972                                        local.http_client.clone(),
 7973                                        local.fs.clone(),
 7974                                        cx,
 7975                                    )
 7976                                })?;
 7977                            let server_id = state.id;
 7978
 7979                            let states = local.language_servers.get(&server_id)?;
 7980
 7981                            match states {
 7982                                LanguageServerState::Starting { .. } => None,
 7983                                LanguageServerState::Running {
 7984                                    adapter, server, ..
 7985                                } => {
 7986                                    let adapter = adapter.clone();
 7987                                    let server = server.clone();
 7988                                    refreshed_servers.insert(server.name());
 7989                                    let toolchain = seed.toolchain.clone();
 7990                                    Some(cx.spawn(async move |_, cx| {
 7991                                        let settings =
 7992                                            LocalLspStore::workspace_configuration_for_adapter(
 7993                                                adapter.adapter.clone(),
 7994                                                &delegate,
 7995                                                toolchain,
 7996                                                None,
 7997                                                cx,
 7998                                            )
 7999                                            .await
 8000                                            .ok()?;
 8001                                        server
 8002                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8003                                                lsp::DidChangeConfigurationParams { settings },
 8004                                            )
 8005                                            .ok()?;
 8006                                        Some(())
 8007                                    }))
 8008                                }
 8009                            }
 8010                        })
 8011                        .collect::<Vec<_>>();
 8012
 8013                    Some(servers)
 8014                })
 8015                .ok()
 8016                .flatten()?;
 8017
 8018            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8019            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8020            // to stop and unregister its language server wrapper.
 8021            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8022            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8023            let _: Vec<Option<()>> = join_all(servers).await;
 8024
 8025            Some(())
 8026        })
 8027        .await;
 8028    }
 8029
 8030    fn maintain_workspace_config(
 8031        external_refresh_requests: watch::Receiver<()>,
 8032        cx: &mut Context<Self>,
 8033    ) -> Task<Result<()>> {
 8034        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8035        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8036
 8037        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8038            *settings_changed_tx.borrow_mut() = ();
 8039        });
 8040
 8041        let mut joint_future =
 8042            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8043        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8044        // - 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).
 8045        // - 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.
 8046        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8047        // - 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,
 8048        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8049        cx.spawn(async move |this, cx| {
 8050            while let Some(()) = joint_future.next().await {
 8051                this.update(cx, |this, cx| {
 8052                    this.refresh_server_tree(cx);
 8053                })
 8054                .ok();
 8055
 8056                Self::refresh_workspace_configurations(&this, cx).await;
 8057            }
 8058
 8059            drop(settings_observation);
 8060            anyhow::Ok(())
 8061        })
 8062    }
 8063
 8064    pub fn running_language_servers_for_local_buffer<'a>(
 8065        &'a self,
 8066        buffer: &Buffer,
 8067        cx: &mut App,
 8068    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8069        let local = self.as_local();
 8070        let language_server_ids = local
 8071            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8072            .unwrap_or_default();
 8073
 8074        language_server_ids
 8075            .into_iter()
 8076            .filter_map(
 8077                move |server_id| match local?.language_servers.get(&server_id)? {
 8078                    LanguageServerState::Running {
 8079                        adapter, server, ..
 8080                    } => Some((adapter, server)),
 8081                    _ => None,
 8082                },
 8083            )
 8084    }
 8085
 8086    pub fn language_servers_for_local_buffer(
 8087        &self,
 8088        buffer: &Buffer,
 8089        cx: &mut App,
 8090    ) -> Vec<LanguageServerId> {
 8091        let local = self.as_local();
 8092        local
 8093            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8094            .unwrap_or_default()
 8095    }
 8096
 8097    pub fn language_server_for_local_buffer<'a>(
 8098        &'a self,
 8099        buffer: &'a Buffer,
 8100        server_id: LanguageServerId,
 8101        cx: &'a mut App,
 8102    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8103        self.as_local()?
 8104            .language_servers_for_buffer(buffer, cx)
 8105            .find(|(_, s)| s.server_id() == server_id)
 8106    }
 8107
 8108    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8109        self.diagnostic_summaries.remove(&id_to_remove);
 8110        if let Some(local) = self.as_local_mut() {
 8111            let to_remove = local.remove_worktree(id_to_remove, cx);
 8112            for server in to_remove {
 8113                self.language_server_statuses.remove(&server);
 8114            }
 8115        }
 8116    }
 8117
 8118    pub fn shared(
 8119        &mut self,
 8120        project_id: u64,
 8121        downstream_client: AnyProtoClient,
 8122        _: &mut Context<Self>,
 8123    ) {
 8124        self.downstream_client = Some((downstream_client.clone(), project_id));
 8125
 8126        for (server_id, status) in &self.language_server_statuses {
 8127            if let Some(server) = self.language_server_for_id(*server_id) {
 8128                downstream_client
 8129                    .send(proto::StartLanguageServer {
 8130                        project_id,
 8131                        server: Some(proto::LanguageServer {
 8132                            id: server_id.to_proto(),
 8133                            name: status.name.to_string(),
 8134                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8135                        }),
 8136                        capabilities: serde_json::to_string(&server.capabilities())
 8137                            .expect("serializing server LSP capabilities"),
 8138                    })
 8139                    .log_err();
 8140            }
 8141        }
 8142    }
 8143
 8144    pub fn disconnected_from_host(&mut self) {
 8145        self.downstream_client.take();
 8146    }
 8147
 8148    pub fn disconnected_from_ssh_remote(&mut self) {
 8149        if let LspStoreMode::Remote(RemoteLspStore {
 8150            upstream_client, ..
 8151        }) = &mut self.mode
 8152        {
 8153            upstream_client.take();
 8154        }
 8155    }
 8156
 8157    pub(crate) fn set_language_server_statuses_from_proto(
 8158        &mut self,
 8159        project: WeakEntity<Project>,
 8160        language_servers: Vec<proto::LanguageServer>,
 8161        server_capabilities: Vec<String>,
 8162        cx: &mut Context<Self>,
 8163    ) {
 8164        let lsp_logs = cx
 8165            .try_global::<GlobalLogStore>()
 8166            .map(|lsp_store| lsp_store.0.clone());
 8167
 8168        self.language_server_statuses = language_servers
 8169            .into_iter()
 8170            .zip(server_capabilities)
 8171            .map(|(server, server_capabilities)| {
 8172                let server_id = LanguageServerId(server.id as usize);
 8173                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8174                    self.lsp_server_capabilities
 8175                        .insert(server_id, server_capabilities);
 8176                }
 8177
 8178                let name = LanguageServerName::from_proto(server.name);
 8179                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8180
 8181                if let Some(lsp_logs) = &lsp_logs {
 8182                    lsp_logs.update(cx, |lsp_logs, cx| {
 8183                        lsp_logs.add_language_server(
 8184                            // Only remote clients get their language servers set from proto
 8185                            LanguageServerKind::Remote {
 8186                                project: project.clone(),
 8187                            },
 8188                            server_id,
 8189                            Some(name.clone()),
 8190                            worktree,
 8191                            None,
 8192                            cx,
 8193                        );
 8194                    });
 8195                }
 8196
 8197                (
 8198                    server_id,
 8199                    LanguageServerStatus {
 8200                        name,
 8201                        server_version: None,
 8202                        pending_work: Default::default(),
 8203                        has_pending_diagnostic_updates: false,
 8204                        progress_tokens: Default::default(),
 8205                        worktree,
 8206                        binary: None,
 8207                        configuration: None,
 8208                        workspace_folders: BTreeSet::new(),
 8209                        process_id: None,
 8210                    },
 8211                )
 8212            })
 8213            .collect();
 8214    }
 8215
 8216    #[cfg(feature = "test-support")]
 8217    pub fn update_diagnostic_entries(
 8218        &mut self,
 8219        server_id: LanguageServerId,
 8220        abs_path: PathBuf,
 8221        result_id: Option<SharedString>,
 8222        version: Option<i32>,
 8223        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8224        cx: &mut Context<Self>,
 8225    ) -> anyhow::Result<()> {
 8226        self.merge_diagnostic_entries(
 8227            vec![DocumentDiagnosticsUpdate {
 8228                diagnostics: DocumentDiagnostics {
 8229                    diagnostics,
 8230                    document_abs_path: abs_path,
 8231                    version,
 8232                },
 8233                result_id,
 8234                server_id,
 8235                disk_based_sources: Cow::Borrowed(&[]),
 8236                registration_id: None,
 8237            }],
 8238            |_, _, _| false,
 8239            cx,
 8240        )?;
 8241        Ok(())
 8242    }
 8243
 8244    pub fn merge_diagnostic_entries<'a>(
 8245        &mut self,
 8246        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8247        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8248        cx: &mut Context<Self>,
 8249    ) -> anyhow::Result<()> {
 8250        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8251        let mut updated_diagnostics_paths = HashMap::default();
 8252        for mut update in diagnostic_updates {
 8253            let abs_path = &update.diagnostics.document_abs_path;
 8254            let server_id = update.server_id;
 8255            let Some((worktree, relative_path)) =
 8256                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8257            else {
 8258                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8259                return Ok(());
 8260            };
 8261
 8262            let worktree_id = worktree.read(cx).id();
 8263            let project_path = ProjectPath {
 8264                worktree_id,
 8265                path: relative_path,
 8266            };
 8267
 8268            let document_uri = lsp::Uri::from_file_path(abs_path)
 8269                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8270            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8271                let snapshot = buffer_handle.read(cx).snapshot();
 8272                let buffer = buffer_handle.read(cx);
 8273                let reused_diagnostics = buffer
 8274                    .buffer_diagnostics(Some(server_id))
 8275                    .iter()
 8276                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8277                    .map(|v| {
 8278                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8279                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8280                        DiagnosticEntry {
 8281                            range: start..end,
 8282                            diagnostic: v.diagnostic.clone(),
 8283                        }
 8284                    })
 8285                    .collect::<Vec<_>>();
 8286
 8287                self.as_local_mut()
 8288                    .context("cannot merge diagnostics on a remote LspStore")?
 8289                    .update_buffer_diagnostics(
 8290                        &buffer_handle,
 8291                        server_id,
 8292                        Some(update.registration_id),
 8293                        update.result_id,
 8294                        update.diagnostics.version,
 8295                        update.diagnostics.diagnostics.clone(),
 8296                        reused_diagnostics.clone(),
 8297                        cx,
 8298                    )?;
 8299
 8300                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8301            } else if let Some(local) = self.as_local() {
 8302                let reused_diagnostics = local
 8303                    .diagnostics
 8304                    .get(&worktree_id)
 8305                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8306                    .and_then(|diagnostics_by_server_id| {
 8307                        diagnostics_by_server_id
 8308                            .binary_search_by_key(&server_id, |e| e.0)
 8309                            .ok()
 8310                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8311                    })
 8312                    .into_iter()
 8313                    .flatten()
 8314                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8315
 8316                update
 8317                    .diagnostics
 8318                    .diagnostics
 8319                    .extend(reused_diagnostics.cloned());
 8320            }
 8321
 8322            let updated = worktree.update(cx, |worktree, cx| {
 8323                self.update_worktree_diagnostics(
 8324                    worktree.id(),
 8325                    server_id,
 8326                    project_path.path.clone(),
 8327                    update.diagnostics.diagnostics,
 8328                    cx,
 8329                )
 8330            })?;
 8331            match updated {
 8332                ControlFlow::Continue(new_summary) => {
 8333                    if let Some((project_id, new_summary)) = new_summary {
 8334                        match &mut diagnostics_summary {
 8335                            Some(diagnostics_summary) => {
 8336                                diagnostics_summary
 8337                                    .more_summaries
 8338                                    .push(proto::DiagnosticSummary {
 8339                                        path: project_path.path.as_ref().to_proto(),
 8340                                        language_server_id: server_id.0 as u64,
 8341                                        error_count: new_summary.error_count,
 8342                                        warning_count: new_summary.warning_count,
 8343                                    })
 8344                            }
 8345                            None => {
 8346                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8347                                    project_id,
 8348                                    worktree_id: worktree_id.to_proto(),
 8349                                    summary: Some(proto::DiagnosticSummary {
 8350                                        path: project_path.path.as_ref().to_proto(),
 8351                                        language_server_id: server_id.0 as u64,
 8352                                        error_count: new_summary.error_count,
 8353                                        warning_count: new_summary.warning_count,
 8354                                    }),
 8355                                    more_summaries: Vec::new(),
 8356                                })
 8357                            }
 8358                        }
 8359                    }
 8360                    updated_diagnostics_paths
 8361                        .entry(server_id)
 8362                        .or_insert_with(Vec::new)
 8363                        .push(project_path);
 8364                }
 8365                ControlFlow::Break(()) => {}
 8366            }
 8367        }
 8368
 8369        if let Some((diagnostics_summary, (downstream_client, _))) =
 8370            diagnostics_summary.zip(self.downstream_client.as_ref())
 8371        {
 8372            downstream_client.send(diagnostics_summary).log_err();
 8373        }
 8374        for (server_id, paths) in updated_diagnostics_paths {
 8375            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8376        }
 8377        Ok(())
 8378    }
 8379
 8380    fn update_worktree_diagnostics(
 8381        &mut self,
 8382        worktree_id: WorktreeId,
 8383        server_id: LanguageServerId,
 8384        path_in_worktree: Arc<RelPath>,
 8385        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8386        _: &mut Context<Worktree>,
 8387    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8388        let local = match &mut self.mode {
 8389            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8390            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8391        };
 8392
 8393        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8394        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8395        let summaries_by_server_id = summaries_for_tree
 8396            .entry(path_in_worktree.clone())
 8397            .or_default();
 8398
 8399        let old_summary = summaries_by_server_id
 8400            .remove(&server_id)
 8401            .unwrap_or_default();
 8402
 8403        let new_summary = DiagnosticSummary::new(&diagnostics);
 8404        if diagnostics.is_empty() {
 8405            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8406            {
 8407                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8408                    diagnostics_by_server_id.remove(ix);
 8409                }
 8410                if diagnostics_by_server_id.is_empty() {
 8411                    diagnostics_for_tree.remove(&path_in_worktree);
 8412                }
 8413            }
 8414        } else {
 8415            summaries_by_server_id.insert(server_id, new_summary);
 8416            let diagnostics_by_server_id = diagnostics_for_tree
 8417                .entry(path_in_worktree.clone())
 8418                .or_default();
 8419            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8420                Ok(ix) => {
 8421                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8422                }
 8423                Err(ix) => {
 8424                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8425                }
 8426            }
 8427        }
 8428
 8429        if !old_summary.is_empty() || !new_summary.is_empty() {
 8430            if let Some((_, project_id)) = &self.downstream_client {
 8431                Ok(ControlFlow::Continue(Some((
 8432                    *project_id,
 8433                    proto::DiagnosticSummary {
 8434                        path: path_in_worktree.to_proto(),
 8435                        language_server_id: server_id.0 as u64,
 8436                        error_count: new_summary.error_count as u32,
 8437                        warning_count: new_summary.warning_count as u32,
 8438                    },
 8439                ))))
 8440            } else {
 8441                Ok(ControlFlow::Continue(None))
 8442            }
 8443        } else {
 8444            Ok(ControlFlow::Break(()))
 8445        }
 8446    }
 8447
 8448    pub fn open_buffer_for_symbol(
 8449        &mut self,
 8450        symbol: &Symbol,
 8451        cx: &mut Context<Self>,
 8452    ) -> Task<Result<Entity<Buffer>>> {
 8453        if let Some((client, project_id)) = self.upstream_client() {
 8454            let request = client.request(proto::OpenBufferForSymbol {
 8455                project_id,
 8456                symbol: Some(Self::serialize_symbol(symbol)),
 8457            });
 8458            cx.spawn(async move |this, cx| {
 8459                let response = request.await?;
 8460                let buffer_id = BufferId::new(response.buffer_id)?;
 8461                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8462                    .await
 8463            })
 8464        } else if let Some(local) = self.as_local() {
 8465            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8466                seed.worktree_id == symbol.source_worktree_id
 8467                    && state.id == symbol.source_language_server_id
 8468                    && symbol.language_server_name == seed.name
 8469            });
 8470            if !is_valid {
 8471                return Task::ready(Err(anyhow!(
 8472                    "language server for worktree and language not found"
 8473                )));
 8474            };
 8475
 8476            let symbol_abs_path = match &symbol.path {
 8477                SymbolLocation::InProject(project_path) => self
 8478                    .worktree_store
 8479                    .read(cx)
 8480                    .absolutize(&project_path, cx)
 8481                    .context("no such worktree"),
 8482                SymbolLocation::OutsideProject {
 8483                    abs_path,
 8484                    signature: _,
 8485                } => Ok(abs_path.to_path_buf()),
 8486            };
 8487            let symbol_abs_path = match symbol_abs_path {
 8488                Ok(abs_path) => abs_path,
 8489                Err(err) => return Task::ready(Err(err)),
 8490            };
 8491            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8492                uri
 8493            } else {
 8494                return Task::ready(Err(anyhow!("invalid symbol path")));
 8495            };
 8496
 8497            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8498        } else {
 8499            Task::ready(Err(anyhow!("no upstream client or local store")))
 8500        }
 8501    }
 8502
 8503    pub(crate) fn open_local_buffer_via_lsp(
 8504        &mut self,
 8505        abs_path: lsp::Uri,
 8506        language_server_id: LanguageServerId,
 8507        cx: &mut Context<Self>,
 8508    ) -> Task<Result<Entity<Buffer>>> {
 8509        let path_style = self.worktree_store.read(cx).path_style();
 8510        cx.spawn(async move |lsp_store, cx| {
 8511            // Escape percent-encoded string.
 8512            let current_scheme = abs_path.scheme().to_owned();
 8513            // Uri is immutable, so we can't modify the scheme
 8514
 8515            let abs_path = abs_path
 8516                .to_file_path_ext(path_style)
 8517                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8518            let p = abs_path.clone();
 8519            let yarn_worktree = lsp_store
 8520                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8521                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8522                        cx.spawn(async move |this, cx| {
 8523                            let t = this
 8524                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8525                                .ok()?;
 8526                            t.await
 8527                        })
 8528                    }),
 8529                    None => Task::ready(None),
 8530                })?
 8531                .await;
 8532            let (worktree_root_target, known_relative_path) =
 8533                if let Some((zip_root, relative_path)) = yarn_worktree {
 8534                    (zip_root, Some(relative_path))
 8535                } else {
 8536                    (Arc::<Path>::from(abs_path.as_path()), None)
 8537                };
 8538            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8539                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8540                    worktree_store.find_worktree(&worktree_root_target, cx)
 8541                })
 8542            })?;
 8543            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8544                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8545                (result.0, relative_path, None)
 8546            } else {
 8547                let worktree = lsp_store
 8548                    .update(cx, |lsp_store, cx| {
 8549                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8550                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8551                        })
 8552                    })?
 8553                    .await?;
 8554                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8555                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8556                    lsp_store
 8557                        .update(cx, |lsp_store, cx| {
 8558                            if let Some(local) = lsp_store.as_local_mut() {
 8559                                local.register_language_server_for_invisible_worktree(
 8560                                    &worktree,
 8561                                    language_server_id,
 8562                                    cx,
 8563                                )
 8564                            }
 8565                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8566                                Some(status) => status.worktree,
 8567                                None => None,
 8568                            }
 8569                        })
 8570                        .ok()
 8571                        .flatten()
 8572                        .zip(Some(worktree_root.clone()))
 8573                } else {
 8574                    None
 8575                };
 8576                let relative_path = if let Some(known_path) = known_relative_path {
 8577                    known_path
 8578                } else {
 8579                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8580                        .into_arc()
 8581                };
 8582                (worktree, relative_path, source_ws)
 8583            };
 8584            let project_path = ProjectPath {
 8585                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8586                path: relative_path,
 8587            };
 8588            let buffer = lsp_store
 8589                .update(cx, |lsp_store, cx| {
 8590                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8591                        buffer_store.open_buffer(project_path, cx)
 8592                    })
 8593                })?
 8594                .await?;
 8595            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8596            if let Some((source_ws, worktree_root)) = source_ws {
 8597                buffer.update(cx, |buffer, cx| {
 8598                    let settings = WorktreeSettings::get(
 8599                        Some(
 8600                            (&ProjectPath {
 8601                                worktree_id: source_ws,
 8602                                path: Arc::from(RelPath::empty()),
 8603                            })
 8604                                .into(),
 8605                        ),
 8606                        cx,
 8607                    );
 8608                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8609                    if is_read_only {
 8610                        buffer.set_capability(Capability::ReadOnly, cx);
 8611                    }
 8612                });
 8613            }
 8614            Ok(buffer)
 8615        })
 8616    }
 8617
 8618    fn local_lsp_servers_for_buffer(
 8619        &self,
 8620        buffer: &Entity<Buffer>,
 8621        cx: &mut Context<Self>,
 8622    ) -> Vec<LanguageServerId> {
 8623        let Some(local) = self.as_local() else {
 8624            return Vec::new();
 8625        };
 8626
 8627        let snapshot = buffer.read(cx).snapshot();
 8628
 8629        buffer.update(cx, |buffer, cx| {
 8630            local
 8631                .language_servers_for_buffer(buffer, cx)
 8632                .map(|(_, server)| server.server_id())
 8633                .filter(|server_id| {
 8634                    self.as_local().is_none_or(|local| {
 8635                        local
 8636                            .buffers_opened_in_servers
 8637                            .get(&snapshot.remote_id())
 8638                            .is_some_and(|servers| servers.contains(server_id))
 8639                    })
 8640                })
 8641                .collect()
 8642        })
 8643    }
 8644
 8645    fn request_multiple_lsp_locally<P, R>(
 8646        &mut self,
 8647        buffer: &Entity<Buffer>,
 8648        position: Option<P>,
 8649        request: R,
 8650        cx: &mut Context<Self>,
 8651    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8652    where
 8653        P: ToOffset,
 8654        R: LspCommand + Clone,
 8655        <R::LspRequest as lsp::request::Request>::Result: Send,
 8656        <R::LspRequest as lsp::request::Request>::Params: Send,
 8657    {
 8658        let Some(local) = self.as_local() else {
 8659            return Task::ready(Vec::new());
 8660        };
 8661
 8662        let snapshot = buffer.read(cx).snapshot();
 8663        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8664
 8665        let server_ids = buffer.update(cx, |buffer, cx| {
 8666            local
 8667                .language_servers_for_buffer(buffer, cx)
 8668                .filter(|(adapter, _)| {
 8669                    scope
 8670                        .as_ref()
 8671                        .map(|scope| scope.language_allowed(&adapter.name))
 8672                        .unwrap_or(true)
 8673                })
 8674                .map(|(_, server)| server.server_id())
 8675                .filter(|server_id| {
 8676                    self.as_local().is_none_or(|local| {
 8677                        local
 8678                            .buffers_opened_in_servers
 8679                            .get(&snapshot.remote_id())
 8680                            .is_some_and(|servers| servers.contains(server_id))
 8681                    })
 8682                })
 8683                .collect::<Vec<_>>()
 8684        });
 8685
 8686        let mut response_results = server_ids
 8687            .into_iter()
 8688            .map(|server_id| {
 8689                let task = self.request_lsp(
 8690                    buffer.clone(),
 8691                    LanguageServerToQuery::Other(server_id),
 8692                    request.clone(),
 8693                    cx,
 8694                );
 8695                async move { (server_id, task.await) }
 8696            })
 8697            .collect::<FuturesUnordered<_>>();
 8698
 8699        cx.background_spawn(async move {
 8700            let mut responses = Vec::with_capacity(response_results.len());
 8701            while let Some((server_id, response_result)) = response_results.next().await {
 8702                match response_result {
 8703                    Ok(response) => responses.push((server_id, response)),
 8704                    // rust-analyzer likes to error with this when its still loading up
 8705                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8706                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8707                }
 8708            }
 8709            responses
 8710        })
 8711    }
 8712
 8713    async fn handle_lsp_get_completions(
 8714        this: Entity<Self>,
 8715        envelope: TypedEnvelope<proto::GetCompletions>,
 8716        mut cx: AsyncApp,
 8717    ) -> Result<proto::GetCompletionsResponse> {
 8718        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8719
 8720        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8721        let buffer_handle = this.update(&mut cx, |this, cx| {
 8722            this.buffer_store.read(cx).get_existing(buffer_id)
 8723        })?;
 8724        let request = GetCompletions::from_proto(
 8725            envelope.payload,
 8726            this.clone(),
 8727            buffer_handle.clone(),
 8728            cx.clone(),
 8729        )
 8730        .await?;
 8731
 8732        let server_to_query = match request.server_id {
 8733            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8734            None => LanguageServerToQuery::FirstCapable,
 8735        };
 8736
 8737        let response = this
 8738            .update(&mut cx, |this, cx| {
 8739                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8740            })
 8741            .await?;
 8742        this.update(&mut cx, |this, cx| {
 8743            Ok(GetCompletions::response_to_proto(
 8744                response,
 8745                this,
 8746                sender_id,
 8747                &buffer_handle.read(cx).version(),
 8748                cx,
 8749            ))
 8750        })
 8751    }
 8752
 8753    async fn handle_lsp_command<T: LspCommand>(
 8754        this: Entity<Self>,
 8755        envelope: TypedEnvelope<T::ProtoRequest>,
 8756        mut cx: AsyncApp,
 8757    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8758    where
 8759        <T::LspRequest as lsp::request::Request>::Params: Send,
 8760        <T::LspRequest as lsp::request::Request>::Result: Send,
 8761    {
 8762        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8763        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8764        let buffer_handle = this.update(&mut cx, |this, cx| {
 8765            this.buffer_store.read(cx).get_existing(buffer_id)
 8766        })?;
 8767        let request = T::from_proto(
 8768            envelope.payload,
 8769            this.clone(),
 8770            buffer_handle.clone(),
 8771            cx.clone(),
 8772        )
 8773        .await?;
 8774        let response = this
 8775            .update(&mut cx, |this, cx| {
 8776                this.request_lsp(
 8777                    buffer_handle.clone(),
 8778                    LanguageServerToQuery::FirstCapable,
 8779                    request,
 8780                    cx,
 8781                )
 8782            })
 8783            .await?;
 8784        this.update(&mut cx, |this, cx| {
 8785            Ok(T::response_to_proto(
 8786                response,
 8787                this,
 8788                sender_id,
 8789                &buffer_handle.read(cx).version(),
 8790                cx,
 8791            ))
 8792        })
 8793    }
 8794
 8795    async fn handle_lsp_query(
 8796        lsp_store: Entity<Self>,
 8797        envelope: TypedEnvelope<proto::LspQuery>,
 8798        mut cx: AsyncApp,
 8799    ) -> Result<proto::Ack> {
 8800        use proto::lsp_query::Request;
 8801        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8802        let lsp_query = envelope.payload;
 8803        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8804        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8805        match lsp_query.request.context("invalid LSP query request")? {
 8806            Request::GetReferences(get_references) => {
 8807                let position = get_references.position.clone().and_then(deserialize_anchor);
 8808                Self::query_lsp_locally::<GetReferences>(
 8809                    lsp_store,
 8810                    server_id,
 8811                    sender_id,
 8812                    lsp_request_id,
 8813                    get_references,
 8814                    position,
 8815                    &mut cx,
 8816                )
 8817                .await?;
 8818            }
 8819            Request::GetDocumentColor(get_document_color) => {
 8820                Self::query_lsp_locally::<GetDocumentColor>(
 8821                    lsp_store,
 8822                    server_id,
 8823                    sender_id,
 8824                    lsp_request_id,
 8825                    get_document_color,
 8826                    None,
 8827                    &mut cx,
 8828                )
 8829                .await?;
 8830            }
 8831            Request::GetFoldingRanges(get_folding_ranges) => {
 8832                Self::query_lsp_locally::<GetFoldingRanges>(
 8833                    lsp_store,
 8834                    server_id,
 8835                    sender_id,
 8836                    lsp_request_id,
 8837                    get_folding_ranges,
 8838                    None,
 8839                    &mut cx,
 8840                )
 8841                .await?;
 8842            }
 8843            Request::GetDocumentSymbols(get_document_symbols) => {
 8844                Self::query_lsp_locally::<GetDocumentSymbols>(
 8845                    lsp_store,
 8846                    server_id,
 8847                    sender_id,
 8848                    lsp_request_id,
 8849                    get_document_symbols,
 8850                    None,
 8851                    &mut cx,
 8852                )
 8853                .await?;
 8854            }
 8855            Request::GetHover(get_hover) => {
 8856                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8857                Self::query_lsp_locally::<GetHover>(
 8858                    lsp_store,
 8859                    server_id,
 8860                    sender_id,
 8861                    lsp_request_id,
 8862                    get_hover,
 8863                    position,
 8864                    &mut cx,
 8865                )
 8866                .await?;
 8867            }
 8868            Request::GetCodeActions(get_code_actions) => {
 8869                Self::query_lsp_locally::<GetCodeActions>(
 8870                    lsp_store,
 8871                    server_id,
 8872                    sender_id,
 8873                    lsp_request_id,
 8874                    get_code_actions,
 8875                    None,
 8876                    &mut cx,
 8877                )
 8878                .await?;
 8879            }
 8880            Request::GetSignatureHelp(get_signature_help) => {
 8881                let position = get_signature_help
 8882                    .position
 8883                    .clone()
 8884                    .and_then(deserialize_anchor);
 8885                Self::query_lsp_locally::<GetSignatureHelp>(
 8886                    lsp_store,
 8887                    server_id,
 8888                    sender_id,
 8889                    lsp_request_id,
 8890                    get_signature_help,
 8891                    position,
 8892                    &mut cx,
 8893                )
 8894                .await?;
 8895            }
 8896            Request::GetCodeLens(get_code_lens) => {
 8897                Self::query_lsp_locally::<GetCodeLens>(
 8898                    lsp_store,
 8899                    server_id,
 8900                    sender_id,
 8901                    lsp_request_id,
 8902                    get_code_lens,
 8903                    None,
 8904                    &mut cx,
 8905                )
 8906                .await?;
 8907            }
 8908            Request::GetDefinition(get_definition) => {
 8909                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8910                Self::query_lsp_locally::<GetDefinitions>(
 8911                    lsp_store,
 8912                    server_id,
 8913                    sender_id,
 8914                    lsp_request_id,
 8915                    get_definition,
 8916                    position,
 8917                    &mut cx,
 8918                )
 8919                .await?;
 8920            }
 8921            Request::GetDeclaration(get_declaration) => {
 8922                let position = get_declaration
 8923                    .position
 8924                    .clone()
 8925                    .and_then(deserialize_anchor);
 8926                Self::query_lsp_locally::<GetDeclarations>(
 8927                    lsp_store,
 8928                    server_id,
 8929                    sender_id,
 8930                    lsp_request_id,
 8931                    get_declaration,
 8932                    position,
 8933                    &mut cx,
 8934                )
 8935                .await?;
 8936            }
 8937            Request::GetTypeDefinition(get_type_definition) => {
 8938                let position = get_type_definition
 8939                    .position
 8940                    .clone()
 8941                    .and_then(deserialize_anchor);
 8942                Self::query_lsp_locally::<GetTypeDefinitions>(
 8943                    lsp_store,
 8944                    server_id,
 8945                    sender_id,
 8946                    lsp_request_id,
 8947                    get_type_definition,
 8948                    position,
 8949                    &mut cx,
 8950                )
 8951                .await?;
 8952            }
 8953            Request::GetImplementation(get_implementation) => {
 8954                let position = get_implementation
 8955                    .position
 8956                    .clone()
 8957                    .and_then(deserialize_anchor);
 8958                Self::query_lsp_locally::<GetImplementations>(
 8959                    lsp_store,
 8960                    server_id,
 8961                    sender_id,
 8962                    lsp_request_id,
 8963                    get_implementation,
 8964                    position,
 8965                    &mut cx,
 8966                )
 8967                .await?;
 8968            }
 8969            Request::InlayHints(inlay_hints) => {
 8970                let query_start = inlay_hints
 8971                    .start
 8972                    .clone()
 8973                    .and_then(deserialize_anchor)
 8974                    .context("invalid inlay hints range start")?;
 8975                let query_end = inlay_hints
 8976                    .end
 8977                    .clone()
 8978                    .and_then(deserialize_anchor)
 8979                    .context("invalid inlay hints range end")?;
 8980                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 8981                    &lsp_store,
 8982                    server_id,
 8983                    lsp_request_id,
 8984                    &inlay_hints,
 8985                    query_start..query_end,
 8986                    &mut cx,
 8987                )
 8988                .await
 8989                .context("preparing inlay hints request")?;
 8990                Self::query_lsp_locally::<InlayHints>(
 8991                    lsp_store,
 8992                    server_id,
 8993                    sender_id,
 8994                    lsp_request_id,
 8995                    inlay_hints,
 8996                    None,
 8997                    &mut cx,
 8998                )
 8999                .await
 9000                .context("querying for inlay hints")?
 9001            }
 9002            //////////////////////////////
 9003            // Below are LSP queries that need to fetch more data,
 9004            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 9005            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9006                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 9007                    &lsp_store,
 9008                    &get_document_diagnostics,
 9009                    &mut cx,
 9010                )
 9011                .await?;
 9012                lsp_store.update(&mut cx, |lsp_store, cx| {
 9013                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9014                    let key = LspKey {
 9015                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9016                        server_queried: server_id,
 9017                    };
 9018                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9019                    ) {
 9020                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9021                            lsp_requests.clear();
 9022                        };
 9023                    }
 9024
 9025                    lsp_data.lsp_requests.entry(key).or_default().insert(
 9026                        lsp_request_id,
 9027                        cx.spawn(async move |lsp_store, cx| {
 9028                            let diagnostics_pull = lsp_store
 9029                                .update(cx, |lsp_store, cx| {
 9030                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9031                                })
 9032                                .ok();
 9033                            if let Some(diagnostics_pull) = diagnostics_pull {
 9034                                match diagnostics_pull.await {
 9035                                    Ok(()) => {}
 9036                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9037                                };
 9038                            }
 9039                        }),
 9040                    );
 9041                });
 9042            }
 9043            Request::SemanticTokens(semantic_tokens) => {
 9044                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 9045                    &lsp_store,
 9046                    &semantic_tokens,
 9047                    &mut cx,
 9048                )
 9049                .await?;
 9050                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9051                lsp_store.update(&mut cx, |lsp_store, cx| {
 9052                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9053                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9054                        let key = LspKey {
 9055                            request_type: TypeId::of::<SemanticTokensFull>(),
 9056                            server_queried: server_id,
 9057                        };
 9058                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9059                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9060                                lsp_requests.clear();
 9061                            };
 9062                        }
 9063
 9064                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9065                            lsp_request_id,
 9066                            cx.spawn(async move |lsp_store, cx| {
 9067                                let tokens_fetch = lsp_store
 9068                                    .update(cx, |lsp_store, cx| {
 9069                                        lsp_store
 9070                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9071                                    })
 9072                                    .ok();
 9073                                if let Some(tokens_fetch) = tokens_fetch {
 9074                                    let new_tokens = tokens_fetch.await;
 9075                                    if let Some(new_tokens) = new_tokens {
 9076                                        lsp_store
 9077                                            .update(cx, |lsp_store, cx| {
 9078                                                let response = new_tokens
 9079                                                    .into_iter()
 9080                                                    .map(|(server_id, response)| {
 9081                                                        (
 9082                                                            server_id.to_proto(),
 9083                                                            SemanticTokensFull::response_to_proto(
 9084                                                                response,
 9085                                                                lsp_store,
 9086                                                                sender_id,
 9087                                                                &buffer_version,
 9088                                                                cx,
 9089                                                            ),
 9090                                                        )
 9091                                                    })
 9092                                                    .collect::<HashMap<_, _>>();
 9093                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9094                                                    project_id,
 9095                                                    lsp_request_id,
 9096                                                    response,
 9097                                                ) {
 9098                                                    Ok(()) => {}
 9099                                                    Err(e) => {
 9100                                                        log::error!(
 9101                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9102                                                        )
 9103                                                    }
 9104                                                }
 9105                                            })
 9106                                            .ok();
 9107                                    }
 9108                                }
 9109                            }),
 9110                        );
 9111                    }
 9112                });
 9113            }
 9114        }
 9115        Ok(proto::Ack {})
 9116    }
 9117
 9118    async fn handle_lsp_query_response(
 9119        lsp_store: Entity<Self>,
 9120        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9121        cx: AsyncApp,
 9122    ) -> Result<()> {
 9123        lsp_store.read_with(&cx, |lsp_store, _| {
 9124            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9125                upstream_client.handle_lsp_response(envelope.clone());
 9126            }
 9127        });
 9128        Ok(())
 9129    }
 9130
 9131    async fn handle_apply_code_action(
 9132        this: Entity<Self>,
 9133        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9134        mut cx: AsyncApp,
 9135    ) -> Result<proto::ApplyCodeActionResponse> {
 9136        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9137        let action =
 9138            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9139        let apply_code_action = this.update(&mut cx, |this, cx| {
 9140            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9141            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9142            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9143        })?;
 9144
 9145        let project_transaction = apply_code_action.await?;
 9146        let project_transaction = this.update(&mut cx, |this, cx| {
 9147            this.buffer_store.update(cx, |buffer_store, cx| {
 9148                buffer_store.serialize_project_transaction_for_peer(
 9149                    project_transaction,
 9150                    sender_id,
 9151                    cx,
 9152                )
 9153            })
 9154        });
 9155        Ok(proto::ApplyCodeActionResponse {
 9156            transaction: Some(project_transaction),
 9157        })
 9158    }
 9159
 9160    async fn handle_register_buffer_with_language_servers(
 9161        this: Entity<Self>,
 9162        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9163        mut cx: AsyncApp,
 9164    ) -> Result<proto::Ack> {
 9165        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9166        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9167        this.update(&mut cx, |this, cx| {
 9168            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9169                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9170                    project_id: upstream_project_id,
 9171                    buffer_id: buffer_id.to_proto(),
 9172                    only_servers: envelope.payload.only_servers,
 9173                });
 9174            }
 9175
 9176            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9177                anyhow::bail!("buffer is not open");
 9178            };
 9179
 9180            let handle = this.register_buffer_with_language_servers(
 9181                &buffer,
 9182                envelope
 9183                    .payload
 9184                    .only_servers
 9185                    .into_iter()
 9186                    .filter_map(|selector| {
 9187                        Some(match selector.selector? {
 9188                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9189                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9190                            }
 9191                            proto::language_server_selector::Selector::Name(name) => {
 9192                                LanguageServerSelector::Name(LanguageServerName(
 9193                                    SharedString::from(name),
 9194                                ))
 9195                            }
 9196                        })
 9197                    })
 9198                    .collect(),
 9199                false,
 9200                cx,
 9201            );
 9202            // Pull diagnostics for the buffer even if it was already registered.
 9203            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9204            // but it's unclear if we need it.
 9205            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9206                .detach();
 9207            this.buffer_store().update(cx, |buffer_store, _| {
 9208                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9209            });
 9210
 9211            Ok(())
 9212        })?;
 9213        Ok(proto::Ack {})
 9214    }
 9215
 9216    async fn handle_rename_project_entry(
 9217        this: Entity<Self>,
 9218        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9219        mut cx: AsyncApp,
 9220    ) -> Result<proto::ProjectEntryResponse> {
 9221        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9222        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9223        let new_path =
 9224            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9225
 9226        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9227            .update(&mut cx, |this, cx| {
 9228                let (worktree, entry) = this
 9229                    .worktree_store
 9230                    .read(cx)
 9231                    .worktree_and_entry_for_id(entry_id, cx)?;
 9232                let new_worktree = this
 9233                    .worktree_store
 9234                    .read(cx)
 9235                    .worktree_for_id(new_worktree_id, cx)?;
 9236                Some((
 9237                    this.worktree_store.clone(),
 9238                    worktree,
 9239                    new_worktree,
 9240                    entry.clone(),
 9241                ))
 9242            })
 9243            .context("worktree not found")?;
 9244        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9245            (worktree.absolutize(&old_entry.path), worktree.id())
 9246        });
 9247        let new_abs_path =
 9248            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9249
 9250        let _transaction = Self::will_rename_entry(
 9251            this.downgrade(),
 9252            old_worktree_id,
 9253            &old_abs_path,
 9254            &new_abs_path,
 9255            old_entry.is_dir(),
 9256            cx.clone(),
 9257        )
 9258        .await;
 9259        let response = WorktreeStore::handle_rename_project_entry(
 9260            worktree_store,
 9261            envelope.payload,
 9262            cx.clone(),
 9263        )
 9264        .await;
 9265        this.read_with(&cx, |this, _| {
 9266            this.did_rename_entry(
 9267                old_worktree_id,
 9268                &old_abs_path,
 9269                &new_abs_path,
 9270                old_entry.is_dir(),
 9271            );
 9272        });
 9273        response
 9274    }
 9275
 9276    async fn handle_update_diagnostic_summary(
 9277        this: Entity<Self>,
 9278        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9279        mut cx: AsyncApp,
 9280    ) -> Result<()> {
 9281        this.update(&mut cx, |lsp_store, cx| {
 9282            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9283            let mut updated_diagnostics_paths = HashMap::default();
 9284            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9285            for message_summary in envelope
 9286                .payload
 9287                .summary
 9288                .into_iter()
 9289                .chain(envelope.payload.more_summaries)
 9290            {
 9291                let project_path = ProjectPath {
 9292                    worktree_id,
 9293                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9294                };
 9295                let path = project_path.path.clone();
 9296                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9297                let summary = DiagnosticSummary {
 9298                    error_count: message_summary.error_count as usize,
 9299                    warning_count: message_summary.warning_count as usize,
 9300                };
 9301
 9302                if summary.is_empty() {
 9303                    if let Some(worktree_summaries) =
 9304                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9305                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9306                    {
 9307                        summaries.remove(&server_id);
 9308                        if summaries.is_empty() {
 9309                            worktree_summaries.remove(&path);
 9310                        }
 9311                    }
 9312                } else {
 9313                    lsp_store
 9314                        .diagnostic_summaries
 9315                        .entry(worktree_id)
 9316                        .or_default()
 9317                        .entry(path)
 9318                        .or_default()
 9319                        .insert(server_id, summary);
 9320                }
 9321
 9322                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9323                    match &mut diagnostics_summary {
 9324                        Some(diagnostics_summary) => {
 9325                            diagnostics_summary
 9326                                .more_summaries
 9327                                .push(proto::DiagnosticSummary {
 9328                                    path: project_path.path.as_ref().to_proto(),
 9329                                    language_server_id: server_id.0 as u64,
 9330                                    error_count: summary.error_count as u32,
 9331                                    warning_count: summary.warning_count as u32,
 9332                                })
 9333                        }
 9334                        None => {
 9335                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9336                                project_id: *project_id,
 9337                                worktree_id: worktree_id.to_proto(),
 9338                                summary: Some(proto::DiagnosticSummary {
 9339                                    path: project_path.path.as_ref().to_proto(),
 9340                                    language_server_id: server_id.0 as u64,
 9341                                    error_count: summary.error_count as u32,
 9342                                    warning_count: summary.warning_count as u32,
 9343                                }),
 9344                                more_summaries: Vec::new(),
 9345                            })
 9346                        }
 9347                    }
 9348                }
 9349                updated_diagnostics_paths
 9350                    .entry(server_id)
 9351                    .or_insert_with(Vec::new)
 9352                    .push(project_path);
 9353            }
 9354
 9355            if let Some((diagnostics_summary, (downstream_client, _))) =
 9356                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9357            {
 9358                downstream_client.send(diagnostics_summary).log_err();
 9359            }
 9360            for (server_id, paths) in updated_diagnostics_paths {
 9361                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9362            }
 9363            Ok(())
 9364        })
 9365    }
 9366
 9367    async fn handle_start_language_server(
 9368        lsp_store: Entity<Self>,
 9369        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9370        mut cx: AsyncApp,
 9371    ) -> Result<()> {
 9372        let server = envelope.payload.server.context("invalid server")?;
 9373        let server_capabilities =
 9374            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9375                .with_context(|| {
 9376                    format!(
 9377                        "incorrect server capabilities {}",
 9378                        envelope.payload.capabilities
 9379                    )
 9380                })?;
 9381        lsp_store.update(&mut cx, |lsp_store, cx| {
 9382            let server_id = LanguageServerId(server.id as usize);
 9383            let server_name = LanguageServerName::from_proto(server.name.clone());
 9384            lsp_store
 9385                .lsp_server_capabilities
 9386                .insert(server_id, server_capabilities);
 9387            lsp_store.language_server_statuses.insert(
 9388                server_id,
 9389                LanguageServerStatus {
 9390                    name: server_name.clone(),
 9391                    server_version: None,
 9392                    pending_work: Default::default(),
 9393                    has_pending_diagnostic_updates: false,
 9394                    progress_tokens: Default::default(),
 9395                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9396                    binary: None,
 9397                    configuration: None,
 9398                    workspace_folders: BTreeSet::new(),
 9399                    process_id: None,
 9400                },
 9401            );
 9402            cx.emit(LspStoreEvent::LanguageServerAdded(
 9403                server_id,
 9404                server_name,
 9405                server.worktree_id.map(WorktreeId::from_proto),
 9406            ));
 9407            cx.notify();
 9408        });
 9409        Ok(())
 9410    }
 9411
 9412    async fn handle_update_language_server(
 9413        lsp_store: Entity<Self>,
 9414        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9415        mut cx: AsyncApp,
 9416    ) -> Result<()> {
 9417        lsp_store.update(&mut cx, |lsp_store, cx| {
 9418            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9419
 9420            match envelope.payload.variant.context("invalid variant")? {
 9421                proto::update_language_server::Variant::WorkStart(payload) => {
 9422                    lsp_store.on_lsp_work_start(
 9423                        language_server_id,
 9424                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9425                            .context("invalid progress token value")?,
 9426                        LanguageServerProgress {
 9427                            title: payload.title,
 9428                            is_disk_based_diagnostics_progress: false,
 9429                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9430                            message: payload.message,
 9431                            percentage: payload.percentage.map(|p| p as usize),
 9432                            last_update_at: cx.background_executor().now(),
 9433                        },
 9434                        cx,
 9435                    );
 9436                }
 9437                proto::update_language_server::Variant::WorkProgress(payload) => {
 9438                    lsp_store.on_lsp_work_progress(
 9439                        language_server_id,
 9440                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9441                            .context("invalid progress token value")?,
 9442                        LanguageServerProgress {
 9443                            title: None,
 9444                            is_disk_based_diagnostics_progress: false,
 9445                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9446                            message: payload.message,
 9447                            percentage: payload.percentage.map(|p| p as usize),
 9448                            last_update_at: cx.background_executor().now(),
 9449                        },
 9450                        cx,
 9451                    );
 9452                }
 9453
 9454                proto::update_language_server::Variant::WorkEnd(payload) => {
 9455                    lsp_store.on_lsp_work_end(
 9456                        language_server_id,
 9457                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9458                            .context("invalid progress token value")?,
 9459                        cx,
 9460                    );
 9461                }
 9462
 9463                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9464                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9465                }
 9466
 9467                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9468                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9469                }
 9470
 9471                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9472                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9473                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9474                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9475                        language_server_id,
 9476                        name: envelope
 9477                            .payload
 9478                            .server_name
 9479                            .map(SharedString::new)
 9480                            .map(LanguageServerName),
 9481                        message: non_lsp,
 9482                    });
 9483                }
 9484            }
 9485
 9486            Ok(())
 9487        })
 9488    }
 9489
 9490    async fn handle_language_server_log(
 9491        this: Entity<Self>,
 9492        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9493        mut cx: AsyncApp,
 9494    ) -> Result<()> {
 9495        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9496        let log_type = envelope
 9497            .payload
 9498            .log_type
 9499            .map(LanguageServerLogType::from_proto)
 9500            .context("invalid language server log type")?;
 9501
 9502        let message = envelope.payload.message;
 9503
 9504        this.update(&mut cx, |_, cx| {
 9505            cx.emit(LspStoreEvent::LanguageServerLog(
 9506                language_server_id,
 9507                log_type,
 9508                message,
 9509            ));
 9510        });
 9511        Ok(())
 9512    }
 9513
 9514    async fn handle_lsp_ext_cancel_flycheck(
 9515        lsp_store: Entity<Self>,
 9516        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9517        cx: AsyncApp,
 9518    ) -> Result<proto::Ack> {
 9519        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9520        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9521            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9522                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9523            } else {
 9524                None
 9525            }
 9526        });
 9527        if let Some(task) = task {
 9528            task.context("handling lsp ext cancel flycheck")?;
 9529        }
 9530
 9531        Ok(proto::Ack {})
 9532    }
 9533
 9534    async fn handle_lsp_ext_run_flycheck(
 9535        lsp_store: Entity<Self>,
 9536        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9537        mut cx: AsyncApp,
 9538    ) -> Result<proto::Ack> {
 9539        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9540        lsp_store.update(&mut cx, |lsp_store, cx| {
 9541            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9542                let text_document = if envelope.payload.current_file_only {
 9543                    let buffer_id = envelope
 9544                        .payload
 9545                        .buffer_id
 9546                        .map(|id| BufferId::new(id))
 9547                        .transpose()?;
 9548                    buffer_id
 9549                        .and_then(|buffer_id| {
 9550                            lsp_store
 9551                                .buffer_store()
 9552                                .read(cx)
 9553                                .get(buffer_id)
 9554                                .and_then(|buffer| {
 9555                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9556                                })
 9557                                .map(|path| make_text_document_identifier(&path))
 9558                        })
 9559                        .transpose()?
 9560                } else {
 9561                    None
 9562                };
 9563                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9564                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9565                )?;
 9566            }
 9567            anyhow::Ok(())
 9568        })?;
 9569
 9570        Ok(proto::Ack {})
 9571    }
 9572
 9573    async fn handle_lsp_ext_clear_flycheck(
 9574        lsp_store: Entity<Self>,
 9575        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9576        cx: AsyncApp,
 9577    ) -> Result<proto::Ack> {
 9578        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9579        lsp_store.read_with(&cx, |lsp_store, _| {
 9580            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9581                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9582            } else {
 9583                None
 9584            }
 9585        });
 9586
 9587        Ok(proto::Ack {})
 9588    }
 9589
 9590    pub fn disk_based_diagnostics_started(
 9591        &mut self,
 9592        language_server_id: LanguageServerId,
 9593        cx: &mut Context<Self>,
 9594    ) {
 9595        if let Some(language_server_status) =
 9596            self.language_server_statuses.get_mut(&language_server_id)
 9597        {
 9598            language_server_status.has_pending_diagnostic_updates = true;
 9599        }
 9600
 9601        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9602        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9603            language_server_id,
 9604            name: self
 9605                .language_server_adapter_for_id(language_server_id)
 9606                .map(|adapter| adapter.name()),
 9607            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9608                Default::default(),
 9609            ),
 9610        })
 9611    }
 9612
 9613    pub fn disk_based_diagnostics_finished(
 9614        &mut self,
 9615        language_server_id: LanguageServerId,
 9616        cx: &mut Context<Self>,
 9617    ) {
 9618        if let Some(language_server_status) =
 9619            self.language_server_statuses.get_mut(&language_server_id)
 9620        {
 9621            language_server_status.has_pending_diagnostic_updates = false;
 9622        }
 9623
 9624        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9625        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9626            language_server_id,
 9627            name: self
 9628                .language_server_adapter_for_id(language_server_id)
 9629                .map(|adapter| adapter.name()),
 9630            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9631                Default::default(),
 9632            ),
 9633        })
 9634    }
 9635
 9636    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9637    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9638    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9639    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9640    // the language server might take some time to publish diagnostics.
 9641    fn simulate_disk_based_diagnostics_events_if_needed(
 9642        &mut self,
 9643        language_server_id: LanguageServerId,
 9644        cx: &mut Context<Self>,
 9645    ) {
 9646        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9647
 9648        let Some(LanguageServerState::Running {
 9649            simulate_disk_based_diagnostics_completion,
 9650            adapter,
 9651            ..
 9652        }) = self
 9653            .as_local_mut()
 9654            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9655        else {
 9656            return;
 9657        };
 9658
 9659        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9660            return;
 9661        }
 9662
 9663        let prev_task =
 9664            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9665                cx.background_executor()
 9666                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9667                    .await;
 9668
 9669                this.update(cx, |this, cx| {
 9670                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9671
 9672                    if let Some(LanguageServerState::Running {
 9673                        simulate_disk_based_diagnostics_completion,
 9674                        ..
 9675                    }) = this.as_local_mut().and_then(|local_store| {
 9676                        local_store.language_servers.get_mut(&language_server_id)
 9677                    }) {
 9678                        *simulate_disk_based_diagnostics_completion = None;
 9679                    }
 9680                })
 9681                .ok();
 9682            }));
 9683
 9684        if prev_task.is_none() {
 9685            self.disk_based_diagnostics_started(language_server_id, cx);
 9686        }
 9687    }
 9688
 9689    pub fn language_server_statuses(
 9690        &self,
 9691    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9692        self.language_server_statuses
 9693            .iter()
 9694            .map(|(key, value)| (*key, value))
 9695    }
 9696
 9697    pub(super) fn did_rename_entry(
 9698        &self,
 9699        worktree_id: WorktreeId,
 9700        old_path: &Path,
 9701        new_path: &Path,
 9702        is_dir: bool,
 9703    ) {
 9704        maybe!({
 9705            let local_store = self.as_local()?;
 9706
 9707            let old_uri = lsp::Uri::from_file_path(old_path)
 9708                .ok()
 9709                .map(|uri| uri.to_string())?;
 9710            let new_uri = lsp::Uri::from_file_path(new_path)
 9711                .ok()
 9712                .map(|uri| uri.to_string())?;
 9713
 9714            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9715                let Some(filter) = local_store
 9716                    .language_server_paths_watched_for_rename
 9717                    .get(&language_server.server_id())
 9718                else {
 9719                    continue;
 9720                };
 9721
 9722                if filter.should_send_did_rename(&old_uri, is_dir) {
 9723                    language_server
 9724                        .notify::<DidRenameFiles>(RenameFilesParams {
 9725                            files: vec![FileRename {
 9726                                old_uri: old_uri.clone(),
 9727                                new_uri: new_uri.clone(),
 9728                            }],
 9729                        })
 9730                        .ok();
 9731                }
 9732            }
 9733            Some(())
 9734        });
 9735    }
 9736
 9737    pub(super) fn will_rename_entry(
 9738        this: WeakEntity<Self>,
 9739        worktree_id: WorktreeId,
 9740        old_path: &Path,
 9741        new_path: &Path,
 9742        is_dir: bool,
 9743        cx: AsyncApp,
 9744    ) -> Task<ProjectTransaction> {
 9745        let old_uri = lsp::Uri::from_file_path(old_path)
 9746            .ok()
 9747            .map(|uri| uri.to_string());
 9748        let new_uri = lsp::Uri::from_file_path(new_path)
 9749            .ok()
 9750            .map(|uri| uri.to_string());
 9751        cx.spawn(async move |cx| {
 9752            let mut tasks = vec![];
 9753            this.update(cx, |this, cx| {
 9754                let local_store = this.as_local()?;
 9755                let old_uri = old_uri?;
 9756                let new_uri = new_uri?;
 9757                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9758                    let Some(filter) = local_store
 9759                        .language_server_paths_watched_for_rename
 9760                        .get(&language_server.server_id())
 9761                    else {
 9762                        continue;
 9763                    };
 9764
 9765                    if !filter.should_send_will_rename(&old_uri, is_dir) {
 9766                        continue;
 9767                    }
 9768                    let request_timeout = ProjectSettings::get_global(cx)
 9769                        .global_lsp_settings
 9770                        .get_request_timeout();
 9771
 9772                    let apply_edit = cx.spawn({
 9773                        let old_uri = old_uri.clone();
 9774                        let new_uri = new_uri.clone();
 9775                        let language_server = language_server.clone();
 9776                        async move |this, cx| {
 9777                            let edit = language_server
 9778                                .request::<WillRenameFiles>(
 9779                                    RenameFilesParams {
 9780                                        files: vec![FileRename { old_uri, new_uri }],
 9781                                    },
 9782                                    request_timeout,
 9783                                )
 9784                                .await
 9785                                .into_response()
 9786                                .context("will rename files")
 9787                                .log_err()
 9788                                .flatten()?;
 9789
 9790                            LocalLspStore::deserialize_workspace_edit(
 9791                                this.upgrade()?,
 9792                                edit,
 9793                                false,
 9794                                language_server.clone(),
 9795                                cx,
 9796                            )
 9797                            .await
 9798                            .ok()
 9799                        }
 9800                    });
 9801                    tasks.push(apply_edit);
 9802                }
 9803                Some(())
 9804            })
 9805            .ok()
 9806            .flatten();
 9807            let mut merged_transaction = ProjectTransaction::default();
 9808            for task in tasks {
 9809                // Await on tasks sequentially so that the order of application of edits is deterministic
 9810                // (at least with regards to the order of registration of language servers)
 9811                if let Some(transaction) = task.await {
 9812                    for (buffer, buffer_transaction) in transaction.0 {
 9813                        merged_transaction.0.insert(buffer, buffer_transaction);
 9814                    }
 9815                }
 9816            }
 9817            merged_transaction
 9818        })
 9819    }
 9820
 9821    fn lsp_notify_abs_paths_changed(
 9822        &mut self,
 9823        server_id: LanguageServerId,
 9824        changes: Vec<PathEvent>,
 9825    ) {
 9826        maybe!({
 9827            let server = self.language_server_for_id(server_id)?;
 9828            let changes = changes
 9829                .into_iter()
 9830                .filter_map(|event| {
 9831                    let typ = match event.kind? {
 9832                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9833                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9834                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9835                    };
 9836                    Some(lsp::FileEvent {
 9837                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9838                        typ,
 9839                    })
 9840                })
 9841                .collect::<Vec<_>>();
 9842            if !changes.is_empty() {
 9843                server
 9844                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9845                        lsp::DidChangeWatchedFilesParams { changes },
 9846                    )
 9847                    .ok();
 9848            }
 9849            Some(())
 9850        });
 9851    }
 9852
 9853    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9854        self.as_local()?.language_server_for_id(id)
 9855    }
 9856
 9857    fn on_lsp_progress(
 9858        &mut self,
 9859        progress_params: lsp::ProgressParams,
 9860        language_server_id: LanguageServerId,
 9861        disk_based_diagnostics_progress_token: Option<String>,
 9862        cx: &mut Context<Self>,
 9863    ) {
 9864        match progress_params.value {
 9865            lsp::ProgressParamsValue::WorkDone(progress) => {
 9866                self.handle_work_done_progress(
 9867                    progress,
 9868                    language_server_id,
 9869                    disk_based_diagnostics_progress_token,
 9870                    ProgressToken::from_lsp(progress_params.token),
 9871                    cx,
 9872                );
 9873            }
 9874            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9875                let registration_id = match progress_params.token {
 9876                    lsp::NumberOrString::Number(_) => None,
 9877                    lsp::NumberOrString::String(token) => token
 9878                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9879                        .map(|(_, id)| id.to_owned()),
 9880                };
 9881                if let Some(LanguageServerState::Running {
 9882                    workspace_diagnostics_refresh_tasks,
 9883                    ..
 9884                }) = self
 9885                    .as_local_mut()
 9886                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9887                    && let Some(workspace_diagnostics) =
 9888                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9889                {
 9890                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9891                    self.apply_workspace_diagnostic_report(
 9892                        language_server_id,
 9893                        report,
 9894                        registration_id.map(SharedString::from),
 9895                        cx,
 9896                    )
 9897                }
 9898            }
 9899        }
 9900    }
 9901
 9902    fn handle_work_done_progress(
 9903        &mut self,
 9904        progress: lsp::WorkDoneProgress,
 9905        language_server_id: LanguageServerId,
 9906        disk_based_diagnostics_progress_token: Option<String>,
 9907        token: ProgressToken,
 9908        cx: &mut Context<Self>,
 9909    ) {
 9910        let language_server_status =
 9911            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9912                status
 9913            } else {
 9914                return;
 9915            };
 9916
 9917        if !language_server_status.progress_tokens.contains(&token) {
 9918            return;
 9919        }
 9920
 9921        let is_disk_based_diagnostics_progress =
 9922            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9923                (&disk_based_diagnostics_progress_token, &token)
 9924            {
 9925                token.starts_with(disk_based_token)
 9926            } else {
 9927                false
 9928            };
 9929
 9930        match progress {
 9931            lsp::WorkDoneProgress::Begin(report) => {
 9932                if is_disk_based_diagnostics_progress {
 9933                    self.disk_based_diagnostics_started(language_server_id, cx);
 9934                }
 9935                self.on_lsp_work_start(
 9936                    language_server_id,
 9937                    token.clone(),
 9938                    LanguageServerProgress {
 9939                        title: Some(report.title),
 9940                        is_disk_based_diagnostics_progress,
 9941                        is_cancellable: report.cancellable.unwrap_or(false),
 9942                        message: report.message.clone(),
 9943                        percentage: report.percentage.map(|p| p as usize),
 9944                        last_update_at: cx.background_executor().now(),
 9945                    },
 9946                    cx,
 9947                );
 9948            }
 9949            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9950                language_server_id,
 9951                token,
 9952                LanguageServerProgress {
 9953                    title: None,
 9954                    is_disk_based_diagnostics_progress,
 9955                    is_cancellable: report.cancellable.unwrap_or(false),
 9956                    message: report.message,
 9957                    percentage: report.percentage.map(|p| p as usize),
 9958                    last_update_at: cx.background_executor().now(),
 9959                },
 9960                cx,
 9961            ),
 9962            lsp::WorkDoneProgress::End(_) => {
 9963                language_server_status.progress_tokens.remove(&token);
 9964                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9965                if is_disk_based_diagnostics_progress {
 9966                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9967                }
 9968            }
 9969        }
 9970    }
 9971
 9972    fn on_lsp_work_start(
 9973        &mut self,
 9974        language_server_id: LanguageServerId,
 9975        token: ProgressToken,
 9976        progress: LanguageServerProgress,
 9977        cx: &mut Context<Self>,
 9978    ) {
 9979        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9980            status.pending_work.insert(token.clone(), progress.clone());
 9981            cx.notify();
 9982        }
 9983        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9984            language_server_id,
 9985            name: self
 9986                .language_server_adapter_for_id(language_server_id)
 9987                .map(|adapter| adapter.name()),
 9988            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9989                token: Some(token.to_proto()),
 9990                title: progress.title,
 9991                message: progress.message,
 9992                percentage: progress.percentage.map(|p| p as u32),
 9993                is_cancellable: Some(progress.is_cancellable),
 9994            }),
 9995        })
 9996    }
 9997
 9998    fn on_lsp_work_progress(
 9999        &mut self,
10000        language_server_id: LanguageServerId,
10001        token: ProgressToken,
10002        progress: LanguageServerProgress,
10003        cx: &mut Context<Self>,
10004    ) {
10005        let mut did_update = false;
10006        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10007            match status.pending_work.entry(token.clone()) {
10008                btree_map::Entry::Vacant(entry) => {
10009                    entry.insert(progress.clone());
10010                    did_update = true;
10011                }
10012                btree_map::Entry::Occupied(mut entry) => {
10013                    let entry = entry.get_mut();
10014                    if (progress.last_update_at - entry.last_update_at)
10015                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10016                    {
10017                        entry.last_update_at = progress.last_update_at;
10018                        if progress.message.is_some() {
10019                            entry.message = progress.message.clone();
10020                        }
10021                        if progress.percentage.is_some() {
10022                            entry.percentage = progress.percentage;
10023                        }
10024                        if progress.is_cancellable != entry.is_cancellable {
10025                            entry.is_cancellable = progress.is_cancellable;
10026                        }
10027                        did_update = true;
10028                    }
10029                }
10030            }
10031        }
10032
10033        if did_update {
10034            cx.emit(LspStoreEvent::LanguageServerUpdate {
10035                language_server_id,
10036                name: self
10037                    .language_server_adapter_for_id(language_server_id)
10038                    .map(|adapter| adapter.name()),
10039                message: proto::update_language_server::Variant::WorkProgress(
10040                    proto::LspWorkProgress {
10041                        token: Some(token.to_proto()),
10042                        message: progress.message,
10043                        percentage: progress.percentage.map(|p| p as u32),
10044                        is_cancellable: Some(progress.is_cancellable),
10045                    },
10046                ),
10047            })
10048        }
10049    }
10050
10051    fn on_lsp_work_end(
10052        &mut self,
10053        language_server_id: LanguageServerId,
10054        token: ProgressToken,
10055        cx: &mut Context<Self>,
10056    ) {
10057        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10058            if let Some(work) = status.pending_work.remove(&token)
10059                && !work.is_disk_based_diagnostics_progress
10060            {
10061                cx.emit(LspStoreEvent::RefreshInlayHints {
10062                    server_id: language_server_id,
10063                    request_id: None,
10064                });
10065            }
10066            cx.notify();
10067        }
10068
10069        cx.emit(LspStoreEvent::LanguageServerUpdate {
10070            language_server_id,
10071            name: self
10072                .language_server_adapter_for_id(language_server_id)
10073                .map(|adapter| adapter.name()),
10074            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10075                token: Some(token.to_proto()),
10076            }),
10077        })
10078    }
10079
10080    pub async fn handle_resolve_completion_documentation(
10081        this: Entity<Self>,
10082        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10083        mut cx: AsyncApp,
10084    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10085        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10086
10087        let completion = this
10088            .read_with(&cx, |this, cx| {
10089                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10090                let server = this
10091                    .language_server_for_id(id)
10092                    .with_context(|| format!("No language server {id}"))?;
10093
10094                let request_timeout = ProjectSettings::get_global(cx)
10095                    .global_lsp_settings
10096                    .get_request_timeout();
10097
10098                anyhow::Ok(cx.background_spawn(async move {
10099                    let can_resolve = server
10100                        .capabilities()
10101                        .completion_provider
10102                        .as_ref()
10103                        .and_then(|options| options.resolve_provider)
10104                        .unwrap_or(false);
10105                    if can_resolve {
10106                        server
10107                            .request::<lsp::request::ResolveCompletionItem>(
10108                                lsp_completion,
10109                                request_timeout,
10110                            )
10111                            .await
10112                            .into_response()
10113                            .context("resolve completion item")
10114                    } else {
10115                        anyhow::Ok(lsp_completion)
10116                    }
10117                }))
10118            })?
10119            .await?;
10120
10121        let mut documentation_is_markdown = false;
10122        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10123        let documentation = match completion.documentation {
10124            Some(lsp::Documentation::String(text)) => text,
10125
10126            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10127                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10128                value
10129            }
10130
10131            _ => String::new(),
10132        };
10133
10134        // If we have a new buffer_id, that means we're talking to a new client
10135        // and want to check for new text_edits in the completion too.
10136        let mut old_replace_start = None;
10137        let mut old_replace_end = None;
10138        let mut old_insert_start = None;
10139        let mut old_insert_end = None;
10140        let mut new_text = String::default();
10141        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10142            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10143                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10144                anyhow::Ok(buffer.read(cx).snapshot())
10145            })?;
10146
10147            if let Some(text_edit) = completion.text_edit.as_ref() {
10148                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10149
10150                if let Some(mut edit) = edit {
10151                    LineEnding::normalize(&mut edit.new_text);
10152
10153                    new_text = edit.new_text;
10154                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10155                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10156                    if let Some(insert_range) = edit.insert_range {
10157                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10158                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10159                    }
10160                }
10161            }
10162        }
10163
10164        Ok(proto::ResolveCompletionDocumentationResponse {
10165            documentation,
10166            documentation_is_markdown,
10167            old_replace_start,
10168            old_replace_end,
10169            new_text,
10170            lsp_completion,
10171            old_insert_start,
10172            old_insert_end,
10173        })
10174    }
10175
10176    async fn handle_on_type_formatting(
10177        this: Entity<Self>,
10178        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10179        mut cx: AsyncApp,
10180    ) -> Result<proto::OnTypeFormattingResponse> {
10181        let on_type_formatting = this.update(&mut cx, |this, cx| {
10182            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10183            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10184            let position = envelope
10185                .payload
10186                .position
10187                .and_then(deserialize_anchor)
10188                .context("invalid position")?;
10189            anyhow::Ok(this.apply_on_type_formatting(
10190                buffer,
10191                position,
10192                envelope.payload.trigger.clone(),
10193                cx,
10194            ))
10195        })?;
10196
10197        let transaction = on_type_formatting
10198            .await?
10199            .as_ref()
10200            .map(language::proto::serialize_transaction);
10201        Ok(proto::OnTypeFormattingResponse { transaction })
10202    }
10203
10204    async fn handle_pull_workspace_diagnostics(
10205        lsp_store: Entity<Self>,
10206        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10207        mut cx: AsyncApp,
10208    ) -> Result<proto::Ack> {
10209        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10210        lsp_store.update(&mut cx, |lsp_store, _| {
10211            lsp_store.pull_workspace_diagnostics(server_id);
10212        });
10213        Ok(proto::Ack {})
10214    }
10215
10216    async fn handle_open_buffer_for_symbol(
10217        this: Entity<Self>,
10218        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10219        mut cx: AsyncApp,
10220    ) -> Result<proto::OpenBufferForSymbolResponse> {
10221        let peer_id = envelope.original_sender_id().unwrap_or_default();
10222        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10223        let symbol = Self::deserialize_symbol(symbol)?;
10224        this.read_with(&cx, |this, _| {
10225            if let SymbolLocation::OutsideProject {
10226                abs_path,
10227                signature,
10228            } = &symbol.path
10229            {
10230                let new_signature = this.symbol_signature(&abs_path);
10231                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10232            }
10233            Ok(())
10234        })?;
10235        let buffer = this
10236            .update(&mut cx, |this, cx| {
10237                this.open_buffer_for_symbol(
10238                    &Symbol {
10239                        language_server_name: symbol.language_server_name,
10240                        source_worktree_id: symbol.source_worktree_id,
10241                        source_language_server_id: symbol.source_language_server_id,
10242                        path: symbol.path,
10243                        name: symbol.name,
10244                        kind: symbol.kind,
10245                        range: symbol.range,
10246                        label: CodeLabel::default(),
10247                        container_name: symbol.container_name,
10248                    },
10249                    cx,
10250                )
10251            })
10252            .await?;
10253
10254        this.update(&mut cx, |this, cx| {
10255            let is_private = buffer
10256                .read(cx)
10257                .file()
10258                .map(|f| f.is_private())
10259                .unwrap_or_default();
10260            if is_private {
10261                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10262            } else {
10263                this.buffer_store
10264                    .update(cx, |buffer_store, cx| {
10265                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10266                    })
10267                    .detach_and_log_err(cx);
10268                let buffer_id = buffer.read(cx).remote_id().to_proto();
10269                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10270            }
10271        })
10272    }
10273
10274    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10275        let mut hasher = Sha256::new();
10276        hasher.update(abs_path.to_string_lossy().as_bytes());
10277        hasher.update(self.nonce.to_be_bytes());
10278        hasher.finalize().as_slice().try_into().unwrap()
10279    }
10280
10281    pub async fn handle_get_project_symbols(
10282        this: Entity<Self>,
10283        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10284        mut cx: AsyncApp,
10285    ) -> Result<proto::GetProjectSymbolsResponse> {
10286        let symbols = this
10287            .update(&mut cx, |this, cx| {
10288                this.symbols(&envelope.payload.query, cx)
10289            })
10290            .await?;
10291
10292        Ok(proto::GetProjectSymbolsResponse {
10293            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10294        })
10295    }
10296
10297    pub async fn handle_restart_language_servers(
10298        this: Entity<Self>,
10299        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10300        mut cx: AsyncApp,
10301    ) -> Result<proto::Ack> {
10302        this.update(&mut cx, |lsp_store, cx| {
10303            let buffers =
10304                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10305            lsp_store.restart_language_servers_for_buffers(
10306                buffers,
10307                envelope
10308                    .payload
10309                    .only_servers
10310                    .into_iter()
10311                    .filter_map(|selector| {
10312                        Some(match selector.selector? {
10313                            proto::language_server_selector::Selector::ServerId(server_id) => {
10314                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10315                            }
10316                            proto::language_server_selector::Selector::Name(name) => {
10317                                LanguageServerSelector::Name(LanguageServerName(
10318                                    SharedString::from(name),
10319                                ))
10320                            }
10321                        })
10322                    })
10323                    .collect(),
10324                cx,
10325            );
10326        });
10327
10328        Ok(proto::Ack {})
10329    }
10330
10331    pub async fn handle_stop_language_servers(
10332        lsp_store: Entity<Self>,
10333        envelope: TypedEnvelope<proto::StopLanguageServers>,
10334        mut cx: AsyncApp,
10335    ) -> Result<proto::Ack> {
10336        lsp_store.update(&mut cx, |lsp_store, cx| {
10337            if envelope.payload.all
10338                && envelope.payload.also_servers.is_empty()
10339                && envelope.payload.buffer_ids.is_empty()
10340            {
10341                lsp_store.stop_all_language_servers(cx);
10342            } else {
10343                let buffers =
10344                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10345                lsp_store
10346                    .stop_language_servers_for_buffers(
10347                        buffers,
10348                        envelope
10349                            .payload
10350                            .also_servers
10351                            .into_iter()
10352                            .filter_map(|selector| {
10353                                Some(match selector.selector? {
10354                                    proto::language_server_selector::Selector::ServerId(
10355                                        server_id,
10356                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10357                                        server_id,
10358                                    )),
10359                                    proto::language_server_selector::Selector::Name(name) => {
10360                                        LanguageServerSelector::Name(LanguageServerName(
10361                                            SharedString::from(name),
10362                                        ))
10363                                    }
10364                                })
10365                            })
10366                            .collect(),
10367                        cx,
10368                    )
10369                    .detach_and_log_err(cx);
10370            }
10371        });
10372
10373        Ok(proto::Ack {})
10374    }
10375
10376    pub async fn handle_cancel_language_server_work(
10377        lsp_store: Entity<Self>,
10378        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10379        mut cx: AsyncApp,
10380    ) -> Result<proto::Ack> {
10381        lsp_store.update(&mut cx, |lsp_store, cx| {
10382            if let Some(work) = envelope.payload.work {
10383                match work {
10384                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10385                        let buffers =
10386                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10387                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10388                    }
10389                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10390                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10391                        let token = work
10392                            .token
10393                            .map(|token| {
10394                                ProgressToken::from_proto(token)
10395                                    .context("invalid work progress token")
10396                            })
10397                            .transpose()?;
10398                        lsp_store.cancel_language_server_work(server_id, token, cx);
10399                    }
10400                }
10401            }
10402            anyhow::Ok(())
10403        })?;
10404
10405        Ok(proto::Ack {})
10406    }
10407
10408    fn buffer_ids_to_buffers(
10409        &mut self,
10410        buffer_ids: impl Iterator<Item = u64>,
10411        cx: &mut Context<Self>,
10412    ) -> Vec<Entity<Buffer>> {
10413        buffer_ids
10414            .into_iter()
10415            .flat_map(|buffer_id| {
10416                self.buffer_store
10417                    .read(cx)
10418                    .get(BufferId::new(buffer_id).log_err()?)
10419            })
10420            .collect::<Vec<_>>()
10421    }
10422
10423    async fn handle_apply_additional_edits_for_completion(
10424        this: Entity<Self>,
10425        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10426        mut cx: AsyncApp,
10427    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10428        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10429            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10430            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10431            let completion = Self::deserialize_completion(
10432                envelope.payload.completion.context("invalid completion")?,
10433            )?;
10434            anyhow::Ok((buffer, completion))
10435        })?;
10436
10437        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10438            this.apply_additional_edits_for_completion(
10439                buffer,
10440                Rc::new(RefCell::new(Box::new([Completion {
10441                    replace_range: completion.replace_range,
10442                    new_text: completion.new_text,
10443                    source: completion.source,
10444                    documentation: None,
10445                    label: CodeLabel::default(),
10446                    match_start: None,
10447                    snippet_deduplication_key: None,
10448                    insert_text_mode: None,
10449                    icon_path: None,
10450                    confirm: None,
10451                }]))),
10452                0,
10453                false,
10454                cx,
10455            )
10456        });
10457
10458        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10459            transaction: apply_additional_edits
10460                .await?
10461                .as_ref()
10462                .map(language::proto::serialize_transaction),
10463        })
10464    }
10465
10466    pub fn last_formatting_failure(&self) -> Option<&str> {
10467        self.last_formatting_failure.as_deref()
10468    }
10469
10470    pub fn reset_last_formatting_failure(&mut self) {
10471        self.last_formatting_failure = None;
10472    }
10473
10474    pub fn environment_for_buffer(
10475        &self,
10476        buffer: &Entity<Buffer>,
10477        cx: &mut Context<Self>,
10478    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10479        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10480            environment.update(cx, |env, cx| {
10481                env.buffer_environment(buffer, &self.worktree_store, cx)
10482            })
10483        } else {
10484            Task::ready(None).shared()
10485        }
10486    }
10487
10488    pub fn format(
10489        &mut self,
10490        buffers: HashSet<Entity<Buffer>>,
10491        target: LspFormatTarget,
10492        push_to_history: bool,
10493        trigger: FormatTrigger,
10494        cx: &mut Context<Self>,
10495    ) -> Task<anyhow::Result<ProjectTransaction>> {
10496        let logger = zlog::scoped!("format");
10497        if self.as_local().is_some() {
10498            zlog::trace!(logger => "Formatting locally");
10499            let logger = zlog::scoped!(logger => "local");
10500            let buffers = buffers
10501                .into_iter()
10502                .map(|buffer_handle| {
10503                    let buffer = buffer_handle.read(cx);
10504                    let buffer_abs_path = File::from_dyn(buffer.file())
10505                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10506
10507                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10508                })
10509                .collect::<Vec<_>>();
10510
10511            cx.spawn(async move |lsp_store, cx| {
10512                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10513
10514                for (handle, abs_path, id) in buffers {
10515                    let env = lsp_store
10516                        .update(cx, |lsp_store, cx| {
10517                            lsp_store.environment_for_buffer(&handle, cx)
10518                        })?
10519                        .await;
10520
10521                    let ranges = match &target {
10522                        LspFormatTarget::Buffers => None,
10523                        LspFormatTarget::Ranges(ranges) => {
10524                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10525                        }
10526                    };
10527
10528                    formattable_buffers.push(FormattableBuffer {
10529                        handle,
10530                        abs_path,
10531                        env,
10532                        ranges,
10533                    });
10534                }
10535                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10536
10537                let format_timer = zlog::time!(logger => "Formatting buffers");
10538                let result = LocalLspStore::format_locally(
10539                    lsp_store.clone(),
10540                    formattable_buffers,
10541                    push_to_history,
10542                    trigger,
10543                    logger,
10544                    cx,
10545                )
10546                .await;
10547                format_timer.end();
10548
10549                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10550
10551                lsp_store.update(cx, |lsp_store, _| {
10552                    lsp_store.update_last_formatting_failure(&result);
10553                })?;
10554
10555                result
10556            })
10557        } else if let Some((client, project_id)) = self.upstream_client() {
10558            zlog::trace!(logger => "Formatting remotely");
10559            let logger = zlog::scoped!(logger => "remote");
10560
10561            let buffer_ranges = match &target {
10562                LspFormatTarget::Buffers => Vec::new(),
10563                LspFormatTarget::Ranges(ranges) => ranges
10564                    .iter()
10565                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10566                        buffer_id: buffer_id.to_proto(),
10567                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10568                    })
10569                    .collect(),
10570            };
10571
10572            let buffer_store = self.buffer_store();
10573            cx.spawn(async move |lsp_store, cx| {
10574                zlog::trace!(logger => "Sending remote format request");
10575                let request_timer = zlog::time!(logger => "remote format request");
10576                let result = client
10577                    .request(proto::FormatBuffers {
10578                        project_id,
10579                        trigger: trigger as i32,
10580                        buffer_ids: buffers
10581                            .iter()
10582                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10583                            .collect(),
10584                        buffer_ranges,
10585                    })
10586                    .await
10587                    .and_then(|result| result.transaction.context("missing transaction"));
10588                request_timer.end();
10589
10590                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10591
10592                lsp_store.update(cx, |lsp_store, _| {
10593                    lsp_store.update_last_formatting_failure(&result);
10594                })?;
10595
10596                let transaction_response = result?;
10597                let _timer = zlog::time!(logger => "deserializing project transaction");
10598                buffer_store
10599                    .update(cx, |buffer_store, cx| {
10600                        buffer_store.deserialize_project_transaction(
10601                            transaction_response,
10602                            push_to_history,
10603                            cx,
10604                        )
10605                    })
10606                    .await
10607            })
10608        } else {
10609            zlog::trace!(logger => "Not formatting");
10610            Task::ready(Ok(ProjectTransaction::default()))
10611        }
10612    }
10613
10614    async fn handle_format_buffers(
10615        this: Entity<Self>,
10616        envelope: TypedEnvelope<proto::FormatBuffers>,
10617        mut cx: AsyncApp,
10618    ) -> Result<proto::FormatBuffersResponse> {
10619        let sender_id = envelope.original_sender_id().unwrap_or_default();
10620        let format = this.update(&mut cx, |this, cx| {
10621            let mut buffers = HashSet::default();
10622            for buffer_id in &envelope.payload.buffer_ids {
10623                let buffer_id = BufferId::new(*buffer_id)?;
10624                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10625            }
10626
10627            let target = if envelope.payload.buffer_ranges.is_empty() {
10628                LspFormatTarget::Buffers
10629            } else {
10630                let mut ranges_map = BTreeMap::new();
10631                for buffer_range in &envelope.payload.buffer_ranges {
10632                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10633                    let ranges: Result<Vec<_>> = buffer_range
10634                        .ranges
10635                        .iter()
10636                        .map(|range| {
10637                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10638                        })
10639                        .collect();
10640                    ranges_map.insert(buffer_id, ranges?);
10641                }
10642                LspFormatTarget::Ranges(ranges_map)
10643            };
10644
10645            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10646            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10647        })?;
10648
10649        let project_transaction = format.await?;
10650        let project_transaction = this.update(&mut cx, |this, cx| {
10651            this.buffer_store.update(cx, |buffer_store, cx| {
10652                buffer_store.serialize_project_transaction_for_peer(
10653                    project_transaction,
10654                    sender_id,
10655                    cx,
10656                )
10657            })
10658        });
10659        Ok(proto::FormatBuffersResponse {
10660            transaction: Some(project_transaction),
10661        })
10662    }
10663
10664    async fn handle_apply_code_action_kind(
10665        this: Entity<Self>,
10666        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10667        mut cx: AsyncApp,
10668    ) -> Result<proto::ApplyCodeActionKindResponse> {
10669        let sender_id = envelope.original_sender_id().unwrap_or_default();
10670        let format = this.update(&mut cx, |this, cx| {
10671            let mut buffers = HashSet::default();
10672            for buffer_id in &envelope.payload.buffer_ids {
10673                let buffer_id = BufferId::new(*buffer_id)?;
10674                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10675            }
10676            let kind = match envelope.payload.kind.as_str() {
10677                "" => CodeActionKind::EMPTY,
10678                "quickfix" => CodeActionKind::QUICKFIX,
10679                "refactor" => CodeActionKind::REFACTOR,
10680                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10681                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10682                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10683                "source" => CodeActionKind::SOURCE,
10684                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10685                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10686                _ => anyhow::bail!(
10687                    "Invalid code action kind {}",
10688                    envelope.payload.kind.as_str()
10689                ),
10690            };
10691            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10692        })?;
10693
10694        let project_transaction = format.await?;
10695        let project_transaction = this.update(&mut cx, |this, cx| {
10696            this.buffer_store.update(cx, |buffer_store, cx| {
10697                buffer_store.serialize_project_transaction_for_peer(
10698                    project_transaction,
10699                    sender_id,
10700                    cx,
10701                )
10702            })
10703        });
10704        Ok(proto::ApplyCodeActionKindResponse {
10705            transaction: Some(project_transaction),
10706        })
10707    }
10708
10709    async fn shutdown_language_server(
10710        server_state: Option<LanguageServerState>,
10711        name: LanguageServerName,
10712        cx: &mut AsyncApp,
10713    ) {
10714        let server = match server_state {
10715            Some(LanguageServerState::Starting { startup, .. }) => {
10716                let mut timer = cx
10717                    .background_executor()
10718                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10719                    .fuse();
10720
10721                select! {
10722                    server = startup.fuse() => server,
10723                    () = timer => {
10724                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10725                        None
10726                    },
10727                }
10728            }
10729
10730            Some(LanguageServerState::Running { server, .. }) => Some(server),
10731
10732            None => None,
10733        };
10734
10735        let Some(server) = server else { return };
10736        if let Some(shutdown) = server.shutdown() {
10737            shutdown.await;
10738        }
10739    }
10740
10741    // Returns a list of all of the worktrees which no longer have a language server and the root path
10742    // for the stopped server
10743    fn stop_local_language_server(
10744        &mut self,
10745        server_id: LanguageServerId,
10746        cx: &mut Context<Self>,
10747    ) -> Task<()> {
10748        let local = match &mut self.mode {
10749            LspStoreMode::Local(local) => local,
10750            _ => {
10751                return Task::ready(());
10752            }
10753        };
10754
10755        // Remove this server ID from all entries in the given worktree.
10756        local
10757            .language_server_ids
10758            .retain(|_, state| state.id != server_id);
10759        self.buffer_store.update(cx, |buffer_store, cx| {
10760            for buffer in buffer_store.buffers() {
10761                buffer.update(cx, |buffer, cx| {
10762                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10763                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10764                });
10765            }
10766        });
10767
10768        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10769            summaries.retain(|path, summaries_by_server_id| {
10770                if summaries_by_server_id.remove(&server_id).is_some() {
10771                    if let Some((client, project_id)) = self.downstream_client.clone() {
10772                        client
10773                            .send(proto::UpdateDiagnosticSummary {
10774                                project_id,
10775                                worktree_id: worktree_id.to_proto(),
10776                                summary: Some(proto::DiagnosticSummary {
10777                                    path: path.as_ref().to_proto(),
10778                                    language_server_id: server_id.0 as u64,
10779                                    error_count: 0,
10780                                    warning_count: 0,
10781                                }),
10782                                more_summaries: Vec::new(),
10783                            })
10784                            .log_err();
10785                    }
10786                    !summaries_by_server_id.is_empty()
10787                } else {
10788                    true
10789                }
10790            });
10791        }
10792
10793        let local = self.as_local_mut().unwrap();
10794        for diagnostics in local.diagnostics.values_mut() {
10795            diagnostics.retain(|_, diagnostics_by_server_id| {
10796                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10797                    diagnostics_by_server_id.remove(ix);
10798                    !diagnostics_by_server_id.is_empty()
10799                } else {
10800                    true
10801                }
10802            });
10803        }
10804        local.language_server_watched_paths.remove(&server_id);
10805
10806        let server_state = local.language_servers.remove(&server_id);
10807        self.cleanup_lsp_data(server_id);
10808        let name = self
10809            .language_server_statuses
10810            .remove(&server_id)
10811            .map(|status| status.name)
10812            .or_else(|| {
10813                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10814                    Some(adapter.name())
10815                } else {
10816                    None
10817                }
10818            });
10819
10820        if let Some(name) = name {
10821            log::info!("stopping language server {name}");
10822            self.languages
10823                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10824            cx.notify();
10825
10826            return cx.spawn(async move |lsp_store, cx| {
10827                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10828                lsp_store
10829                    .update(cx, |lsp_store, cx| {
10830                        lsp_store
10831                            .languages
10832                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10833                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10834                        cx.notify();
10835                    })
10836                    .ok();
10837            });
10838        }
10839
10840        if server_state.is_some() {
10841            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10842        }
10843        Task::ready(())
10844    }
10845
10846    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10847        self.shutdown_all_language_servers(cx).detach();
10848    }
10849
10850    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
10851        if let Some((client, project_id)) = self.upstream_client() {
10852            let request = client.request(proto::StopLanguageServers {
10853                project_id,
10854                buffer_ids: Vec::new(),
10855                also_servers: Vec::new(),
10856                all: true,
10857            });
10858            cx.background_spawn(async move {
10859                request.await.ok();
10860            })
10861        } else {
10862            let Some(local) = self.as_local_mut() else {
10863                return Task::ready(());
10864            };
10865            let language_servers_to_stop = local
10866                .language_server_ids
10867                .values()
10868                .map(|state| state.id)
10869                .collect();
10870            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10871            let tasks = language_servers_to_stop
10872                .into_iter()
10873                .map(|server| self.stop_local_language_server(server, cx))
10874                .collect::<Vec<_>>();
10875            cx.background_spawn(async move {
10876                futures::future::join_all(tasks).await;
10877            })
10878        }
10879    }
10880
10881    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
10882        let buffers = self.buffer_store.read(cx).buffers().collect();
10883        self.restart_language_servers_for_buffers(buffers, HashSet::default(), cx);
10884    }
10885
10886    pub fn restart_language_servers_for_buffers(
10887        &mut self,
10888        buffers: Vec<Entity<Buffer>>,
10889        only_restart_servers: HashSet<LanguageServerSelector>,
10890        cx: &mut Context<Self>,
10891    ) {
10892        if let Some((client, project_id)) = self.upstream_client() {
10893            let request = client.request(proto::RestartLanguageServers {
10894                project_id,
10895                buffer_ids: buffers
10896                    .into_iter()
10897                    .map(|b| b.read(cx).remote_id().to_proto())
10898                    .collect(),
10899                only_servers: only_restart_servers
10900                    .into_iter()
10901                    .map(|selector| {
10902                        let selector = match selector {
10903                            LanguageServerSelector::Id(language_server_id) => {
10904                                proto::language_server_selector::Selector::ServerId(
10905                                    language_server_id.to_proto(),
10906                                )
10907                            }
10908                            LanguageServerSelector::Name(language_server_name) => {
10909                                proto::language_server_selector::Selector::Name(
10910                                    language_server_name.to_string(),
10911                                )
10912                            }
10913                        };
10914                        proto::LanguageServerSelector {
10915                            selector: Some(selector),
10916                        }
10917                    })
10918                    .collect(),
10919                all: false,
10920            });
10921            cx.background_spawn(request).detach_and_log_err(cx);
10922        } else {
10923            let stop_task = if only_restart_servers.is_empty() {
10924                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10925            } else {
10926                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10927            };
10928            cx.spawn(async move |lsp_store, cx| {
10929                stop_task.await;
10930                lsp_store.update(cx, |lsp_store, cx| {
10931                    for buffer in buffers {
10932                        lsp_store.register_buffer_with_language_servers(
10933                            &buffer,
10934                            only_restart_servers.clone(),
10935                            true,
10936                            cx,
10937                        );
10938                    }
10939                })
10940            })
10941            .detach();
10942        }
10943    }
10944
10945    pub fn stop_language_servers_for_buffers(
10946        &mut self,
10947        buffers: Vec<Entity<Buffer>>,
10948        also_stop_servers: HashSet<LanguageServerSelector>,
10949        cx: &mut Context<Self>,
10950    ) -> Task<Result<()>> {
10951        if let Some((client, project_id)) = self.upstream_client() {
10952            let request = client.request(proto::StopLanguageServers {
10953                project_id,
10954                buffer_ids: buffers
10955                    .into_iter()
10956                    .map(|b| b.read(cx).remote_id().to_proto())
10957                    .collect(),
10958                also_servers: also_stop_servers
10959                    .into_iter()
10960                    .map(|selector| {
10961                        let selector = match selector {
10962                            LanguageServerSelector::Id(language_server_id) => {
10963                                proto::language_server_selector::Selector::ServerId(
10964                                    language_server_id.to_proto(),
10965                                )
10966                            }
10967                            LanguageServerSelector::Name(language_server_name) => {
10968                                proto::language_server_selector::Selector::Name(
10969                                    language_server_name.to_string(),
10970                                )
10971                            }
10972                        };
10973                        proto::LanguageServerSelector {
10974                            selector: Some(selector),
10975                        }
10976                    })
10977                    .collect(),
10978                all: false,
10979            });
10980            cx.background_spawn(async move {
10981                let _ = request.await?;
10982                Ok(())
10983            })
10984        } else {
10985            let task =
10986                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10987            cx.background_spawn(async move {
10988                task.await;
10989                Ok(())
10990            })
10991        }
10992    }
10993
10994    fn stop_local_language_servers_for_buffers(
10995        &mut self,
10996        buffers: &[Entity<Buffer>],
10997        also_stop_servers: HashSet<LanguageServerSelector>,
10998        cx: &mut Context<Self>,
10999    ) -> Task<()> {
11000        let Some(local) = self.as_local_mut() else {
11001            return Task::ready(());
11002        };
11003        let mut language_server_names_to_stop = BTreeSet::default();
11004        let mut language_servers_to_stop = also_stop_servers
11005            .into_iter()
11006            .flat_map(|selector| match selector {
11007                LanguageServerSelector::Id(id) => Some(id),
11008                LanguageServerSelector::Name(name) => {
11009                    language_server_names_to_stop.insert(name);
11010                    None
11011                }
11012            })
11013            .collect::<BTreeSet<_>>();
11014
11015        let mut covered_worktrees = HashSet::default();
11016        for buffer in buffers {
11017            buffer.update(cx, |buffer, cx| {
11018                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11019                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11020                    && covered_worktrees.insert(worktree_id)
11021                {
11022                    language_server_names_to_stop.retain(|name| {
11023                        let old_ids_count = language_servers_to_stop.len();
11024                        let all_language_servers_with_this_name = local
11025                            .language_server_ids
11026                            .iter()
11027                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11028                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11029                        old_ids_count == language_servers_to_stop.len()
11030                    });
11031                }
11032            });
11033        }
11034        for name in language_server_names_to_stop {
11035            language_servers_to_stop.extend(
11036                local
11037                    .language_server_ids
11038                    .iter()
11039                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11040            );
11041        }
11042
11043        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11044        let tasks = language_servers_to_stop
11045            .into_iter()
11046            .map(|server| self.stop_local_language_server(server, cx))
11047            .collect::<Vec<_>>();
11048
11049        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11050    }
11051
11052    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11053        let (worktree, relative_path) =
11054            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11055
11056        let project_path = ProjectPath {
11057            worktree_id: worktree.read(cx).id(),
11058            path: relative_path,
11059        };
11060
11061        Some(
11062            self.buffer_store()
11063                .read(cx)
11064                .get_by_path(&project_path)?
11065                .read(cx),
11066        )
11067    }
11068
11069    #[cfg(any(test, feature = "test-support"))]
11070    pub fn update_diagnostics(
11071        &mut self,
11072        server_id: LanguageServerId,
11073        diagnostics: lsp::PublishDiagnosticsParams,
11074        result_id: Option<SharedString>,
11075        source_kind: DiagnosticSourceKind,
11076        disk_based_sources: &[String],
11077        cx: &mut Context<Self>,
11078    ) -> Result<()> {
11079        self.merge_lsp_diagnostics(
11080            source_kind,
11081            vec![DocumentDiagnosticsUpdate {
11082                diagnostics,
11083                result_id,
11084                server_id,
11085                disk_based_sources: Cow::Borrowed(disk_based_sources),
11086                registration_id: None,
11087            }],
11088            |_, _, _| false,
11089            cx,
11090        )
11091    }
11092
11093    pub fn merge_lsp_diagnostics(
11094        &mut self,
11095        source_kind: DiagnosticSourceKind,
11096        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11097        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11098        cx: &mut Context<Self>,
11099    ) -> Result<()> {
11100        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11101        let updates = lsp_diagnostics
11102            .into_iter()
11103            .filter_map(|update| {
11104                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11105                Some(DocumentDiagnosticsUpdate {
11106                    diagnostics: self.lsp_to_document_diagnostics(
11107                        abs_path,
11108                        source_kind,
11109                        update.server_id,
11110                        update.diagnostics,
11111                        &update.disk_based_sources,
11112                        update.registration_id.clone(),
11113                    ),
11114                    result_id: update.result_id,
11115                    server_id: update.server_id,
11116                    disk_based_sources: update.disk_based_sources,
11117                    registration_id: update.registration_id,
11118                })
11119            })
11120            .collect();
11121        self.merge_diagnostic_entries(updates, merge, cx)?;
11122        Ok(())
11123    }
11124
11125    fn lsp_to_document_diagnostics(
11126        &mut self,
11127        document_abs_path: PathBuf,
11128        source_kind: DiagnosticSourceKind,
11129        server_id: LanguageServerId,
11130        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11131        disk_based_sources: &[String],
11132        registration_id: Option<SharedString>,
11133    ) -> DocumentDiagnostics {
11134        let mut diagnostics = Vec::default();
11135        let mut primary_diagnostic_group_ids = HashMap::default();
11136        let mut sources_by_group_id = HashMap::default();
11137        let mut supporting_diagnostics = HashMap::default();
11138
11139        let adapter = self.language_server_adapter_for_id(server_id);
11140
11141        // Ensure that primary diagnostics are always the most severe
11142        lsp_diagnostics
11143            .diagnostics
11144            .sort_by_key(|item| item.severity);
11145
11146        for diagnostic in &lsp_diagnostics.diagnostics {
11147            let source = diagnostic.source.as_ref();
11148            let range = range_from_lsp(diagnostic.range);
11149            let is_supporting = diagnostic
11150                .related_information
11151                .as_ref()
11152                .is_some_and(|infos| {
11153                    infos.iter().any(|info| {
11154                        primary_diagnostic_group_ids.contains_key(&(
11155                            source,
11156                            diagnostic.code.clone(),
11157                            range_from_lsp(info.location.range),
11158                        ))
11159                    })
11160                });
11161
11162            let is_unnecessary = diagnostic
11163                .tags
11164                .as_ref()
11165                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11166
11167            let underline = self
11168                .language_server_adapter_for_id(server_id)
11169                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11170
11171            if is_supporting {
11172                supporting_diagnostics.insert(
11173                    (source, diagnostic.code.clone(), range),
11174                    (diagnostic.severity, is_unnecessary),
11175                );
11176            } else {
11177                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11178                let is_disk_based =
11179                    source.is_some_and(|source| disk_based_sources.contains(source));
11180
11181                sources_by_group_id.insert(group_id, source);
11182                primary_diagnostic_group_ids
11183                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11184
11185                diagnostics.push(DiagnosticEntry {
11186                    range,
11187                    diagnostic: Diagnostic {
11188                        source: diagnostic.source.clone(),
11189                        source_kind,
11190                        code: diagnostic.code.clone(),
11191                        code_description: diagnostic
11192                            .code_description
11193                            .as_ref()
11194                            .and_then(|d| d.href.clone()),
11195                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11196                        markdown: adapter.as_ref().and_then(|adapter| {
11197                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11198                        }),
11199                        message: diagnostic.message.trim().to_string(),
11200                        group_id,
11201                        is_primary: true,
11202                        is_disk_based,
11203                        is_unnecessary,
11204                        underline,
11205                        data: diagnostic.data.clone(),
11206                        registration_id: registration_id.clone(),
11207                    },
11208                });
11209                if let Some(infos) = &diagnostic.related_information {
11210                    for info in infos {
11211                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11212                            let range = range_from_lsp(info.location.range);
11213                            diagnostics.push(DiagnosticEntry {
11214                                range,
11215                                diagnostic: Diagnostic {
11216                                    source: diagnostic.source.clone(),
11217                                    source_kind,
11218                                    code: diagnostic.code.clone(),
11219                                    code_description: diagnostic
11220                                        .code_description
11221                                        .as_ref()
11222                                        .and_then(|d| d.href.clone()),
11223                                    severity: DiagnosticSeverity::INFORMATION,
11224                                    markdown: adapter.as_ref().and_then(|adapter| {
11225                                        adapter.diagnostic_message_to_markdown(&info.message)
11226                                    }),
11227                                    message: info.message.trim().to_string(),
11228                                    group_id,
11229                                    is_primary: false,
11230                                    is_disk_based,
11231                                    is_unnecessary: false,
11232                                    underline,
11233                                    data: diagnostic.data.clone(),
11234                                    registration_id: registration_id.clone(),
11235                                },
11236                            });
11237                        }
11238                    }
11239                }
11240            }
11241        }
11242
11243        for entry in &mut diagnostics {
11244            let diagnostic = &mut entry.diagnostic;
11245            if !diagnostic.is_primary {
11246                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11247                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11248                    source,
11249                    diagnostic.code.clone(),
11250                    entry.range.clone(),
11251                )) {
11252                    if let Some(severity) = severity {
11253                        diagnostic.severity = severity;
11254                    }
11255                    diagnostic.is_unnecessary = is_unnecessary;
11256                }
11257            }
11258        }
11259
11260        DocumentDiagnostics {
11261            diagnostics,
11262            document_abs_path,
11263            version: lsp_diagnostics.version,
11264        }
11265    }
11266
11267    fn insert_newly_running_language_server(
11268        &mut self,
11269        adapter: Arc<CachedLspAdapter>,
11270        language_server: Arc<LanguageServer>,
11271        server_id: LanguageServerId,
11272        key: LanguageServerSeed,
11273        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11274        cx: &mut Context<Self>,
11275    ) {
11276        let Some(local) = self.as_local_mut() else {
11277            return;
11278        };
11279        // If the language server for this key doesn't match the server id, don't store the
11280        // server. Which will cause it to be dropped, killing the process
11281        if local
11282            .language_server_ids
11283            .get(&key)
11284            .map(|state| state.id != server_id)
11285            .unwrap_or(false)
11286        {
11287            return;
11288        }
11289
11290        // Update language_servers collection with Running variant of LanguageServerState
11291        // indicating that the server is up and running and ready
11292        let workspace_folders = workspace_folders.lock().clone();
11293        language_server.set_workspace_folders(workspace_folders);
11294
11295        let workspace_diagnostics_refresh_tasks = language_server
11296            .capabilities()
11297            .diagnostic_provider
11298            .and_then(|provider| {
11299                local
11300                    .language_server_dynamic_registrations
11301                    .entry(server_id)
11302                    .or_default()
11303                    .diagnostics
11304                    .entry(None)
11305                    .or_insert(provider.clone());
11306                let workspace_refresher =
11307                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11308
11309                Some((None, workspace_refresher))
11310            })
11311            .into_iter()
11312            .collect();
11313        local.language_servers.insert(
11314            server_id,
11315            LanguageServerState::Running {
11316                workspace_diagnostics_refresh_tasks,
11317                adapter: adapter.clone(),
11318                server: language_server.clone(),
11319                simulate_disk_based_diagnostics_completion: None,
11320            },
11321        );
11322        local
11323            .languages
11324            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11325        if let Some(file_ops_caps) = language_server
11326            .capabilities()
11327            .workspace
11328            .as_ref()
11329            .and_then(|ws| ws.file_operations.as_ref())
11330        {
11331            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11332            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11333            if did_rename_caps.or(will_rename_caps).is_some() {
11334                let watcher = RenamePathsWatchedForServer::default()
11335                    .with_did_rename_patterns(did_rename_caps)
11336                    .with_will_rename_patterns(will_rename_caps);
11337                local
11338                    .language_server_paths_watched_for_rename
11339                    .insert(server_id, watcher);
11340            }
11341        }
11342
11343        self.language_server_statuses.insert(
11344            server_id,
11345            LanguageServerStatus {
11346                name: language_server.name(),
11347                server_version: language_server.version(),
11348                pending_work: Default::default(),
11349                has_pending_diagnostic_updates: false,
11350                progress_tokens: Default::default(),
11351                worktree: Some(key.worktree_id),
11352                binary: Some(language_server.binary().clone()),
11353                configuration: Some(language_server.configuration().clone()),
11354                workspace_folders: language_server.workspace_folders(),
11355                process_id: language_server.process_id(),
11356            },
11357        );
11358
11359        cx.emit(LspStoreEvent::LanguageServerAdded(
11360            server_id,
11361            language_server.name(),
11362            Some(key.worktree_id),
11363        ));
11364
11365        let server_capabilities = language_server.capabilities();
11366        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11367            downstream_client
11368                .send(proto::StartLanguageServer {
11369                    project_id: *project_id,
11370                    server: Some(proto::LanguageServer {
11371                        id: server_id.to_proto(),
11372                        name: language_server.name().to_string(),
11373                        worktree_id: Some(key.worktree_id.to_proto()),
11374                    }),
11375                    capabilities: serde_json::to_string(&server_capabilities)
11376                        .expect("serializing server LSP capabilities"),
11377                })
11378                .log_err();
11379        }
11380        self.lsp_server_capabilities
11381            .insert(server_id, server_capabilities);
11382
11383        // Tell the language server about every open buffer in the worktree that matches the language.
11384        // Also check for buffers in worktrees that reused this server
11385        let mut worktrees_using_server = vec![key.worktree_id];
11386        if let Some(local) = self.as_local() {
11387            // Find all worktrees that have this server in their language server tree
11388            for (worktree_id, servers) in &local.lsp_tree.instances {
11389                if *worktree_id != key.worktree_id {
11390                    for server_map in servers.roots.values() {
11391                        if server_map
11392                            .values()
11393                            .any(|(node, _)| node.id() == Some(server_id))
11394                        {
11395                            worktrees_using_server.push(*worktree_id);
11396                        }
11397                    }
11398                }
11399            }
11400        }
11401
11402        let mut buffer_paths_registered = Vec::new();
11403        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11404            let mut lsp_adapters = HashMap::default();
11405            for buffer_handle in buffer_store.buffers() {
11406                let buffer = buffer_handle.read(cx);
11407                let file = match File::from_dyn(buffer.file()) {
11408                    Some(file) => file,
11409                    None => continue,
11410                };
11411                let language = match buffer.language() {
11412                    Some(language) => language,
11413                    None => continue,
11414                };
11415
11416                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11417                    || !lsp_adapters
11418                        .entry(language.name())
11419                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11420                        .iter()
11421                        .any(|a| a.name == key.name)
11422                {
11423                    continue;
11424                }
11425                // didOpen
11426                let file = match file.as_local() {
11427                    Some(file) => file,
11428                    None => continue,
11429                };
11430
11431                let local = self.as_local_mut().unwrap();
11432
11433                let buffer_id = buffer.remote_id();
11434                if local.registered_buffers.contains_key(&buffer_id) {
11435                    let versions = local
11436                        .buffer_snapshots
11437                        .entry(buffer_id)
11438                        .or_default()
11439                        .entry(server_id)
11440                        .and_modify(|_| {
11441                            assert!(
11442                            false,
11443                            "There should not be an existing snapshot for a newly inserted buffer"
11444                        )
11445                        })
11446                        .or_insert_with(|| {
11447                            vec![LspBufferSnapshot {
11448                                version: 0,
11449                                snapshot: buffer.text_snapshot(),
11450                            }]
11451                        });
11452
11453                    let snapshot = versions.last().unwrap();
11454                    let version = snapshot.version;
11455                    let initial_snapshot = &snapshot.snapshot;
11456                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11457                    language_server.register_buffer(
11458                        uri,
11459                        adapter.language_id(&language.name()),
11460                        version,
11461                        initial_snapshot.text(),
11462                    );
11463                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11464                    local
11465                        .buffers_opened_in_servers
11466                        .entry(buffer_id)
11467                        .or_default()
11468                        .insert(server_id);
11469                }
11470                buffer_handle.update(cx, |buffer, cx| {
11471                    buffer.set_completion_triggers(
11472                        server_id,
11473                        language_server
11474                            .capabilities()
11475                            .completion_provider
11476                            .as_ref()
11477                            .and_then(|provider| {
11478                                provider
11479                                    .trigger_characters
11480                                    .as_ref()
11481                                    .map(|characters| characters.iter().cloned().collect())
11482                            })
11483                            .unwrap_or_default(),
11484                        cx,
11485                    )
11486                });
11487            }
11488        });
11489
11490        for (buffer_id, abs_path) in buffer_paths_registered {
11491            cx.emit(LspStoreEvent::LanguageServerUpdate {
11492                language_server_id: server_id,
11493                name: Some(adapter.name()),
11494                message: proto::update_language_server::Variant::RegisteredForBuffer(
11495                    proto::RegisteredForBuffer {
11496                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11497                        buffer_id: buffer_id.to_proto(),
11498                    },
11499                ),
11500            });
11501        }
11502
11503        cx.notify();
11504    }
11505
11506    pub fn language_servers_running_disk_based_diagnostics(
11507        &self,
11508    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11509        self.language_server_statuses
11510            .iter()
11511            .filter_map(|(id, status)| {
11512                if status.has_pending_diagnostic_updates {
11513                    Some(*id)
11514                } else {
11515                    None
11516                }
11517            })
11518    }
11519
11520    pub(crate) fn cancel_language_server_work_for_buffers(
11521        &mut self,
11522        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11523        cx: &mut Context<Self>,
11524    ) {
11525        if let Some((client, project_id)) = self.upstream_client() {
11526            let request = client.request(proto::CancelLanguageServerWork {
11527                project_id,
11528                work: Some(proto::cancel_language_server_work::Work::Buffers(
11529                    proto::cancel_language_server_work::Buffers {
11530                        buffer_ids: buffers
11531                            .into_iter()
11532                            .map(|b| b.read(cx).remote_id().to_proto())
11533                            .collect(),
11534                    },
11535                )),
11536            });
11537            cx.background_spawn(request).detach_and_log_err(cx);
11538        } else if let Some(local) = self.as_local() {
11539            let servers = buffers
11540                .into_iter()
11541                .flat_map(|buffer| {
11542                    buffer.update(cx, |buffer, cx| {
11543                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11544                    })
11545                })
11546                .collect::<HashSet<_>>();
11547            for server_id in servers {
11548                self.cancel_language_server_work(server_id, None, cx);
11549            }
11550        }
11551    }
11552
11553    pub(crate) fn cancel_language_server_work(
11554        &mut self,
11555        server_id: LanguageServerId,
11556        token_to_cancel: Option<ProgressToken>,
11557        cx: &mut Context<Self>,
11558    ) {
11559        if let Some(local) = self.as_local() {
11560            let status = self.language_server_statuses.get(&server_id);
11561            let server = local.language_servers.get(&server_id);
11562            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11563            {
11564                for (token, progress) in &status.pending_work {
11565                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11566                        && token != token_to_cancel
11567                    {
11568                        continue;
11569                    }
11570                    if progress.is_cancellable {
11571                        server
11572                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11573                                WorkDoneProgressCancelParams {
11574                                    token: token.to_lsp(),
11575                                },
11576                            )
11577                            .ok();
11578                    }
11579                }
11580            }
11581        } else if let Some((client, project_id)) = self.upstream_client() {
11582            let request = client.request(proto::CancelLanguageServerWork {
11583                project_id,
11584                work: Some(
11585                    proto::cancel_language_server_work::Work::LanguageServerWork(
11586                        proto::cancel_language_server_work::LanguageServerWork {
11587                            language_server_id: server_id.to_proto(),
11588                            token: token_to_cancel.map(|token| token.to_proto()),
11589                        },
11590                    ),
11591                ),
11592            });
11593            cx.background_spawn(request).detach_and_log_err(cx);
11594        }
11595    }
11596
11597    fn register_supplementary_language_server(
11598        &mut self,
11599        id: LanguageServerId,
11600        name: LanguageServerName,
11601        server: Arc<LanguageServer>,
11602        cx: &mut Context<Self>,
11603    ) {
11604        if let Some(local) = self.as_local_mut() {
11605            local
11606                .supplementary_language_servers
11607                .insert(id, (name.clone(), server));
11608            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11609        }
11610    }
11611
11612    fn unregister_supplementary_language_server(
11613        &mut self,
11614        id: LanguageServerId,
11615        cx: &mut Context<Self>,
11616    ) {
11617        if let Some(local) = self.as_local_mut() {
11618            local.supplementary_language_servers.remove(&id);
11619            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11620        }
11621    }
11622
11623    pub(crate) fn supplementary_language_servers(
11624        &self,
11625    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11626        self.as_local().into_iter().flat_map(|local| {
11627            local
11628                .supplementary_language_servers
11629                .iter()
11630                .map(|(id, (name, _))| (*id, name.clone()))
11631        })
11632    }
11633
11634    pub fn language_server_adapter_for_id(
11635        &self,
11636        id: LanguageServerId,
11637    ) -> Option<Arc<CachedLspAdapter>> {
11638        self.as_local()
11639            .and_then(|local| local.language_servers.get(&id))
11640            .and_then(|language_server_state| match language_server_state {
11641                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11642                _ => None,
11643            })
11644    }
11645
11646    pub(super) fn update_local_worktree_language_servers(
11647        &mut self,
11648        worktree_handle: &Entity<Worktree>,
11649        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11650        cx: &mut Context<Self>,
11651    ) {
11652        if changes.is_empty() {
11653            return;
11654        }
11655
11656        let Some(local) = self.as_local() else { return };
11657
11658        local.prettier_store.update(cx, |prettier_store, cx| {
11659            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11660        });
11661
11662        let worktree_id = worktree_handle.read(cx).id();
11663        let mut language_server_ids = local
11664            .language_server_ids
11665            .iter()
11666            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11667            .collect::<Vec<_>>();
11668        language_server_ids.sort();
11669        language_server_ids.dedup();
11670
11671        let active_servers: Vec<(LanguageServerId, &LanguageServerWatchedPaths)> =
11672            language_server_ids
11673                .iter()
11674                .filter_map(|server_id| {
11675                    if !matches!(
11676                        local.language_servers.get(server_id),
11677                        Some(LanguageServerState::Running { .. })
11678                    ) {
11679                        return None;
11680                    }
11681                    let watched_paths = local.language_server_watched_paths.get(server_id)?;
11682                    Some((*server_id, watched_paths))
11683                })
11684                .collect();
11685
11686        for (server_id, watched_paths) in &active_servers {
11687            if let Some(LanguageServerState::Running { server, .. }) =
11688                local.language_servers.get(server_id)
11689            {
11690                let params = lsp::DidChangeWatchedFilesParams {
11691                    changes: changes
11692                        .iter()
11693                        .filter_map(|(path, _, change)| {
11694                            let candidate = Candidate::new(path.as_std_path());
11695
11696                            if !watched_paths
11697                                .is_worktree_path_match_candidate(worktree_id, &candidate)
11698                            {
11699                                return None;
11700                            }
11701                            let typ = match change {
11702                                PathChange::Loaded => return None,
11703                                PathChange::Added => lsp::FileChangeType::CREATED,
11704                                PathChange::Removed => lsp::FileChangeType::DELETED,
11705                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11706                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11707                            };
11708                            let uri =
11709                                lsp::Uri::from_file_path(worktree_handle.read(cx).absolutize(path))
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    registrations: HashMap<String, WatchedPathsRegistration>,
13531}
13532
13533struct WatchedPathsRegistration {
13534    worktree_globs: HashMap<WorktreeId, GlobSet>,
13535    _abs_path_watchers: Vec<Task<()>>,
13536}
13537
13538impl LanguageServerWatchedPaths {
13539    fn is_worktree_path_match_candidate(
13540        &self,
13541        worktree_id: WorktreeId,
13542        candidate: &Candidate,
13543    ) -> bool {
13544        self.registrations.values().any(|reg| {
13545            reg.worktree_globs
13546                .get(&worktree_id)
13547                .is_some_and(|gs| gs.is_match_candidate(candidate))
13548        })
13549    }
13550}
13551
13552struct LspBufferSnapshot {
13553    version: i32,
13554    snapshot: TextBufferSnapshot,
13555}
13556
13557/// A prompt requested by LSP server.
13558#[derive(Clone, Debug)]
13559pub struct LanguageServerPromptRequest {
13560    pub id: usize,
13561    pub level: PromptLevel,
13562    pub message: String,
13563    pub actions: Vec<MessageActionItem>,
13564    pub lsp_name: String,
13565    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13566}
13567
13568impl LanguageServerPromptRequest {
13569    pub fn new(
13570        level: PromptLevel,
13571        message: String,
13572        actions: Vec<MessageActionItem>,
13573        lsp_name: String,
13574        response_channel: smol::channel::Sender<MessageActionItem>,
13575    ) -> Self {
13576        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13577        LanguageServerPromptRequest {
13578            id,
13579            level,
13580            message,
13581            actions,
13582            lsp_name,
13583            response_channel,
13584        }
13585    }
13586    pub async fn respond(self, index: usize) -> Option<()> {
13587        if let Some(response) = self.actions.into_iter().nth(index) {
13588            self.response_channel.send(response).await.ok()
13589        } else {
13590            None
13591        }
13592    }
13593
13594    #[cfg(any(test, feature = "test-support"))]
13595    pub fn test(
13596        level: PromptLevel,
13597        message: String,
13598        actions: Vec<MessageActionItem>,
13599        lsp_name: String,
13600    ) -> Self {
13601        let (tx, _rx) = smol::channel::unbounded();
13602        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13603    }
13604}
13605impl PartialEq for LanguageServerPromptRequest {
13606    fn eq(&self, other: &Self) -> bool {
13607        self.message == other.message && self.actions == other.actions
13608    }
13609}
13610
13611#[derive(Clone, Debug, PartialEq)]
13612pub enum LanguageServerLogType {
13613    Log(MessageType),
13614    Trace { verbose_info: Option<String> },
13615    Rpc { received: bool },
13616}
13617
13618impl LanguageServerLogType {
13619    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13620        match self {
13621            Self::Log(log_type) => {
13622                use proto::log_message::LogLevel;
13623                let level = match *log_type {
13624                    MessageType::ERROR => LogLevel::Error,
13625                    MessageType::WARNING => LogLevel::Warning,
13626                    MessageType::INFO => LogLevel::Info,
13627                    MessageType::LOG => LogLevel::Log,
13628                    other => {
13629                        log::warn!("Unknown lsp log message type: {other:?}");
13630                        LogLevel::Log
13631                    }
13632                };
13633                proto::language_server_log::LogType::Log(proto::LogMessage {
13634                    level: level as i32,
13635                })
13636            }
13637            Self::Trace { verbose_info } => {
13638                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13639                    verbose_info: verbose_info.to_owned(),
13640                })
13641            }
13642            Self::Rpc { received } => {
13643                let kind = if *received {
13644                    proto::rpc_message::Kind::Received
13645                } else {
13646                    proto::rpc_message::Kind::Sent
13647                };
13648                let kind = kind as i32;
13649                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13650            }
13651        }
13652    }
13653
13654    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13655        use proto::log_message::LogLevel;
13656        use proto::rpc_message;
13657        match log_type {
13658            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13659                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13660                    LogLevel::Error => MessageType::ERROR,
13661                    LogLevel::Warning => MessageType::WARNING,
13662                    LogLevel::Info => MessageType::INFO,
13663                    LogLevel::Log => MessageType::LOG,
13664                },
13665            ),
13666            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13667                verbose_info: trace_message.verbose_info,
13668            },
13669            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13670                received: match rpc_message::Kind::from_i32(message.kind)
13671                    .unwrap_or(rpc_message::Kind::Received)
13672                {
13673                    rpc_message::Kind::Received => true,
13674                    rpc_message::Kind::Sent => false,
13675                },
13676            },
13677        }
13678    }
13679}
13680
13681pub struct WorkspaceRefreshTask {
13682    refresh_tx: mpsc::Sender<()>,
13683    progress_tx: mpsc::Sender<()>,
13684    #[allow(dead_code)]
13685    task: Task<()>,
13686}
13687
13688pub enum LanguageServerState {
13689    Starting {
13690        startup: Task<Option<Arc<LanguageServer>>>,
13691        /// List of language servers that will be added to the workspace once it's initialization completes.
13692        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13693    },
13694
13695    Running {
13696        adapter: Arc<CachedLspAdapter>,
13697        server: Arc<LanguageServer>,
13698        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13699        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13700    },
13701}
13702
13703impl LanguageServerState {
13704    fn add_workspace_folder(&self, uri: Uri) {
13705        match self {
13706            LanguageServerState::Starting {
13707                pending_workspace_folders,
13708                ..
13709            } => {
13710                pending_workspace_folders.lock().insert(uri);
13711            }
13712            LanguageServerState::Running { server, .. } => {
13713                server.add_workspace_folder(uri);
13714            }
13715        }
13716    }
13717    fn _remove_workspace_folder(&self, uri: Uri) {
13718        match self {
13719            LanguageServerState::Starting {
13720                pending_workspace_folders,
13721                ..
13722            } => {
13723                pending_workspace_folders.lock().remove(&uri);
13724            }
13725            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13726        }
13727    }
13728}
13729
13730impl std::fmt::Debug for LanguageServerState {
13731    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13732        match self {
13733            LanguageServerState::Starting { .. } => {
13734                f.debug_struct("LanguageServerState::Starting").finish()
13735            }
13736            LanguageServerState::Running { .. } => {
13737                f.debug_struct("LanguageServerState::Running").finish()
13738            }
13739        }
13740    }
13741}
13742
13743#[derive(Clone, Debug, Serialize)]
13744pub struct LanguageServerProgress {
13745    pub is_disk_based_diagnostics_progress: bool,
13746    pub is_cancellable: bool,
13747    pub title: Option<String>,
13748    pub message: Option<String>,
13749    pub percentage: Option<usize>,
13750    #[serde(skip_serializing)]
13751    pub last_update_at: Instant,
13752}
13753
13754#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13755pub struct DiagnosticSummary {
13756    pub error_count: usize,
13757    pub warning_count: usize,
13758}
13759
13760impl DiagnosticSummary {
13761    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13762        let mut this = Self {
13763            error_count: 0,
13764            warning_count: 0,
13765        };
13766
13767        for entry in diagnostics {
13768            if entry.diagnostic.is_primary {
13769                match entry.diagnostic.severity {
13770                    DiagnosticSeverity::ERROR => this.error_count += 1,
13771                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13772                    _ => {}
13773                }
13774            }
13775        }
13776
13777        this
13778    }
13779
13780    pub fn is_empty(&self) -> bool {
13781        self.error_count == 0 && self.warning_count == 0
13782    }
13783
13784    pub fn to_proto(
13785        self,
13786        language_server_id: LanguageServerId,
13787        path: &RelPath,
13788    ) -> proto::DiagnosticSummary {
13789        proto::DiagnosticSummary {
13790            path: path.to_proto(),
13791            language_server_id: language_server_id.0 as u64,
13792            error_count: self.error_count as u32,
13793            warning_count: self.warning_count as u32,
13794        }
13795    }
13796}
13797
13798#[derive(Clone, Debug)]
13799pub enum CompletionDocumentation {
13800    /// There is no documentation for this completion.
13801    Undocumented,
13802    /// A single line of documentation.
13803    SingleLine(SharedString),
13804    /// Multiple lines of plain text documentation.
13805    MultiLinePlainText(SharedString),
13806    /// Markdown documentation.
13807    MultiLineMarkdown(SharedString),
13808    /// Both single line and multiple lines of plain text documentation.
13809    SingleLineAndMultiLinePlainText {
13810        single_line: SharedString,
13811        plain_text: Option<SharedString>,
13812    },
13813}
13814
13815impl CompletionDocumentation {
13816    #[cfg(any(test, feature = "test-support"))]
13817    pub fn text(&self) -> SharedString {
13818        match self {
13819            CompletionDocumentation::Undocumented => "".into(),
13820            CompletionDocumentation::SingleLine(s) => s.clone(),
13821            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13822            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13823            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13824                single_line.clone()
13825            }
13826        }
13827    }
13828}
13829
13830impl From<lsp::Documentation> for CompletionDocumentation {
13831    fn from(docs: lsp::Documentation) -> Self {
13832        match docs {
13833            lsp::Documentation::String(text) => {
13834                if text.lines().count() <= 1 {
13835                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
13836                } else {
13837                    CompletionDocumentation::MultiLinePlainText(text.into())
13838                }
13839            }
13840
13841            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13842                lsp::MarkupKind::PlainText => {
13843                    if value.lines().count() <= 1 {
13844                        CompletionDocumentation::SingleLine(value.into())
13845                    } else {
13846                        CompletionDocumentation::MultiLinePlainText(value.into())
13847                    }
13848                }
13849
13850                lsp::MarkupKind::Markdown => {
13851                    CompletionDocumentation::MultiLineMarkdown(value.into())
13852                }
13853            },
13854        }
13855    }
13856}
13857
13858pub enum ResolvedHint {
13859    Resolved(InlayHint),
13860    Resolving(Shared<Task<()>>),
13861}
13862
13863pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
13864    glob.components()
13865        .take_while(|component| match component {
13866            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13867            _ => true,
13868        })
13869        .collect()
13870}
13871
13872pub struct SshLspAdapter {
13873    name: LanguageServerName,
13874    binary: LanguageServerBinary,
13875    initialization_options: Option<String>,
13876    code_action_kinds: Option<Vec<CodeActionKind>>,
13877}
13878
13879impl SshLspAdapter {
13880    pub fn new(
13881        name: LanguageServerName,
13882        binary: LanguageServerBinary,
13883        initialization_options: Option<String>,
13884        code_action_kinds: Option<String>,
13885    ) -> Self {
13886        Self {
13887            name,
13888            binary,
13889            initialization_options,
13890            code_action_kinds: code_action_kinds
13891                .as_ref()
13892                .and_then(|c| serde_json::from_str(c).ok()),
13893        }
13894    }
13895}
13896
13897impl LspInstaller for SshLspAdapter {
13898    type BinaryVersion = ();
13899    async fn check_if_user_installed(
13900        &self,
13901        _: &dyn LspAdapterDelegate,
13902        _: Option<Toolchain>,
13903        _: &AsyncApp,
13904    ) -> Option<LanguageServerBinary> {
13905        Some(self.binary.clone())
13906    }
13907
13908    async fn cached_server_binary(
13909        &self,
13910        _: PathBuf,
13911        _: &dyn LspAdapterDelegate,
13912    ) -> Option<LanguageServerBinary> {
13913        None
13914    }
13915
13916    async fn fetch_latest_server_version(
13917        &self,
13918        _: &dyn LspAdapterDelegate,
13919        _: bool,
13920        _: &mut AsyncApp,
13921    ) -> Result<()> {
13922        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13923    }
13924
13925    async fn fetch_server_binary(
13926        &self,
13927        _: (),
13928        _: PathBuf,
13929        _: &dyn LspAdapterDelegate,
13930    ) -> Result<LanguageServerBinary> {
13931        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13932    }
13933}
13934
13935#[async_trait(?Send)]
13936impl LspAdapter for SshLspAdapter {
13937    fn name(&self) -> LanguageServerName {
13938        self.name.clone()
13939    }
13940
13941    async fn initialization_options(
13942        self: Arc<Self>,
13943        _: &Arc<dyn LspAdapterDelegate>,
13944    ) -> Result<Option<serde_json::Value>> {
13945        let Some(options) = &self.initialization_options else {
13946            return Ok(None);
13947        };
13948        let result = serde_json::from_str(options)?;
13949        Ok(result)
13950    }
13951
13952    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13953        self.code_action_kinds.clone()
13954    }
13955}
13956
13957pub fn language_server_settings<'a>(
13958    delegate: &'a dyn LspAdapterDelegate,
13959    language: &LanguageServerName,
13960    cx: &'a App,
13961) -> Option<&'a LspSettings> {
13962    language_server_settings_for(
13963        SettingsLocation {
13964            worktree_id: delegate.worktree_id(),
13965            path: RelPath::empty(),
13966        },
13967        language,
13968        cx,
13969    )
13970}
13971
13972pub fn language_server_settings_for<'a>(
13973    location: SettingsLocation<'a>,
13974    language: &LanguageServerName,
13975    cx: &'a App,
13976) -> Option<&'a LspSettings> {
13977    ProjectSettings::get(Some(location), cx).lsp.get(language)
13978}
13979
13980pub struct LocalLspAdapterDelegate {
13981    lsp_store: WeakEntity<LspStore>,
13982    worktree: worktree::Snapshot,
13983    fs: Arc<dyn Fs>,
13984    http_client: Arc<dyn HttpClient>,
13985    language_registry: Arc<LanguageRegistry>,
13986    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13987}
13988
13989impl LocalLspAdapterDelegate {
13990    pub fn new(
13991        language_registry: Arc<LanguageRegistry>,
13992        environment: &Entity<ProjectEnvironment>,
13993        lsp_store: WeakEntity<LspStore>,
13994        worktree: &Entity<Worktree>,
13995        http_client: Arc<dyn HttpClient>,
13996        fs: Arc<dyn Fs>,
13997        cx: &mut App,
13998    ) -> Arc<Self> {
13999        let load_shell_env_task =
14000            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14001
14002        Arc::new(Self {
14003            lsp_store,
14004            worktree: worktree.read(cx).snapshot(),
14005            fs,
14006            http_client,
14007            language_registry,
14008            load_shell_env_task,
14009        })
14010    }
14011
14012    pub fn from_local_lsp(
14013        local: &LocalLspStore,
14014        worktree: &Entity<Worktree>,
14015        cx: &mut App,
14016    ) -> Arc<Self> {
14017        Self::new(
14018            local.languages.clone(),
14019            &local.environment,
14020            local.weak.clone(),
14021            worktree,
14022            local.http_client.clone(),
14023            local.fs.clone(),
14024            cx,
14025        )
14026    }
14027}
14028
14029#[async_trait]
14030impl LspAdapterDelegate for LocalLspAdapterDelegate {
14031    fn show_notification(&self, message: &str, cx: &mut App) {
14032        self.lsp_store
14033            .update(cx, |_, cx| {
14034                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14035            })
14036            .ok();
14037    }
14038
14039    fn http_client(&self) -> Arc<dyn HttpClient> {
14040        self.http_client.clone()
14041    }
14042
14043    fn worktree_id(&self) -> WorktreeId {
14044        self.worktree.id()
14045    }
14046
14047    fn worktree_root_path(&self) -> &Path {
14048        self.worktree.abs_path().as_ref()
14049    }
14050
14051    fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
14052        self.worktree.resolve_relative_path(path)
14053    }
14054
14055    async fn shell_env(&self) -> HashMap<String, String> {
14056        let task = self.load_shell_env_task.clone();
14057        task.await.unwrap_or_default()
14058    }
14059
14060    async fn npm_package_installed_version(
14061        &self,
14062        package_name: &str,
14063    ) -> Result<Option<(PathBuf, Version)>> {
14064        let local_package_directory = self.worktree_root_path();
14065        let node_modules_directory = local_package_directory.join("node_modules");
14066
14067        if let Some(version) =
14068            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14069        {
14070            return Ok(Some((node_modules_directory, version)));
14071        }
14072        let Some(npm) = self.which("npm".as_ref()).await else {
14073            log::warn!(
14074                "Failed to find npm executable for {:?}",
14075                local_package_directory
14076            );
14077            return Ok(None);
14078        };
14079
14080        let env = self.shell_env().await;
14081        let output = util::command::new_command(&npm)
14082            .args(["root", "-g"])
14083            .envs(env)
14084            .current_dir(local_package_directory)
14085            .output()
14086            .await?;
14087        let global_node_modules =
14088            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14089
14090        if let Some(version) =
14091            read_package_installed_version(global_node_modules.clone(), package_name).await?
14092        {
14093            return Ok(Some((global_node_modules, version)));
14094        }
14095        return Ok(None);
14096    }
14097
14098    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14099        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14100        if self.fs.is_file(&worktree_abs_path).await {
14101            worktree_abs_path.pop();
14102        }
14103
14104        let env = self.shell_env().await;
14105
14106        let shell_path = env.get("PATH").cloned();
14107
14108        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14109    }
14110
14111    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14112        let mut working_dir = self.worktree_root_path().to_path_buf();
14113        if self.fs.is_file(&working_dir).await {
14114            working_dir.pop();
14115        }
14116        let output = util::command::new_command(&command.path)
14117            .args(command.arguments)
14118            .envs(command.env.clone().unwrap_or_default())
14119            .current_dir(working_dir)
14120            .output()
14121            .await?;
14122
14123        anyhow::ensure!(
14124            output.status.success(),
14125            "{}, stdout: {:?}, stderr: {:?}",
14126            output.status,
14127            String::from_utf8_lossy(&output.stdout),
14128            String::from_utf8_lossy(&output.stderr)
14129        );
14130        Ok(())
14131    }
14132
14133    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14134        self.language_registry
14135            .update_lsp_binary_status(server_name, status);
14136    }
14137
14138    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14139        self.language_registry
14140            .all_lsp_adapters()
14141            .into_iter()
14142            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14143            .collect()
14144    }
14145
14146    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14147        let dir = self.language_registry.language_server_download_dir(name)?;
14148
14149        if !dir.exists() {
14150            smol::fs::create_dir_all(&dir)
14151                .await
14152                .context("failed to create container directory")
14153                .log_err()?;
14154        }
14155
14156        Some(dir)
14157    }
14158
14159    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14160        let entry = self
14161            .worktree
14162            .entry_for_path(path)
14163            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14164        let abs_path = self.worktree.absolutize(&entry.path);
14165        self.fs.load(&abs_path).await
14166    }
14167}
14168
14169async fn populate_labels_for_symbols(
14170    symbols: Vec<CoreSymbol>,
14171    language_registry: &Arc<LanguageRegistry>,
14172    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14173    output: &mut Vec<Symbol>,
14174) {
14175    #[allow(clippy::mutable_key_type)]
14176    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14177
14178    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14179    for symbol in symbols {
14180        let Some(file_name) = symbol.path.file_name() else {
14181            continue;
14182        };
14183        let language = language_registry
14184            .load_language_for_file_path(Path::new(file_name))
14185            .await
14186            .ok()
14187            .or_else(|| {
14188                unknown_paths.insert(file_name.into());
14189                None
14190            });
14191        symbols_by_language
14192            .entry(language)
14193            .or_default()
14194            .push(symbol);
14195    }
14196
14197    for unknown_path in unknown_paths {
14198        log::info!("no language found for symbol in file {unknown_path:?}");
14199    }
14200
14201    let mut label_params = Vec::new();
14202    for (language, mut symbols) in symbols_by_language {
14203        label_params.clear();
14204        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14205            name: mem::take(&mut symbol.name),
14206            kind: symbol.kind,
14207            container_name: symbol.container_name.take(),
14208        }));
14209
14210        let mut labels = Vec::new();
14211        if let Some(language) = language {
14212            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14213                language_registry
14214                    .lsp_adapters(&language.name())
14215                    .first()
14216                    .cloned()
14217            });
14218            if let Some(lsp_adapter) = lsp_adapter {
14219                labels = lsp_adapter
14220                    .labels_for_symbols(&label_params, &language)
14221                    .await
14222                    .log_err()
14223                    .unwrap_or_default();
14224            }
14225        }
14226
14227        for (
14228            (
14229                symbol,
14230                language::Symbol {
14231                    name,
14232                    container_name,
14233                    ..
14234                },
14235            ),
14236            label,
14237        ) in symbols
14238            .into_iter()
14239            .zip(label_params.drain(..))
14240            .zip(labels.into_iter().chain(iter::repeat(None)))
14241        {
14242            output.push(Symbol {
14243                language_server_name: symbol.language_server_name,
14244                source_worktree_id: symbol.source_worktree_id,
14245                source_language_server_id: symbol.source_language_server_id,
14246                path: symbol.path,
14247                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14248                name,
14249                kind: symbol.kind,
14250                range: symbol.range,
14251                container_name,
14252            });
14253        }
14254    }
14255}
14256
14257pub(crate) fn collapse_newlines(text: &str, separator: &str) -> String {
14258    text.lines()
14259        .map(|line| line.trim())
14260        .filter(|line| !line.is_empty())
14261        .join(separator)
14262}
14263
14264fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14265    match server.capabilities().text_document_sync.as_ref()? {
14266        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14267            // Server wants didSave but didn't specify includeText.
14268            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14269            // Server doesn't want didSave at all.
14270            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14271            // Server provided SaveOptions.
14272            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14273                Some(save_options.include_text.unwrap_or(false))
14274            }
14275        },
14276        // We do not have any save info. Kind affects didChange only.
14277        lsp::TextDocumentSyncCapability::Kind(_) => None,
14278    }
14279}
14280
14281/// Completion items are displayed in a `UniformList`.
14282/// Usually, those items are single-line strings, but in LSP responses,
14283/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14284/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14285/// 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,
14286/// breaking the completions menu presentation.
14287///
14288/// 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.
14289pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14290    let mut new_text = String::with_capacity(label.text.len());
14291    let mut offset_map = vec![0; label.text.len() + 1];
14292    let mut last_char_was_space = false;
14293    let mut new_idx = 0;
14294    let chars = label.text.char_indices().fuse();
14295    let mut newlines_removed = false;
14296
14297    for (idx, c) in chars {
14298        offset_map[idx] = new_idx;
14299
14300        match c {
14301            '\n' if last_char_was_space => {
14302                newlines_removed = true;
14303            }
14304            '\t' | ' ' if last_char_was_space => {}
14305            '\n' if !last_char_was_space => {
14306                new_text.push(' ');
14307                new_idx += 1;
14308                last_char_was_space = true;
14309                newlines_removed = true;
14310            }
14311            ' ' | '\t' => {
14312                new_text.push(' ');
14313                new_idx += 1;
14314                last_char_was_space = true;
14315            }
14316            _ => {
14317                new_text.push(c);
14318                new_idx += c.len_utf8();
14319                last_char_was_space = false;
14320            }
14321        }
14322    }
14323    offset_map[label.text.len()] = new_idx;
14324
14325    // Only modify the label if newlines were removed.
14326    if !newlines_removed {
14327        return;
14328    }
14329
14330    let last_index = new_idx;
14331    let mut run_ranges_errors = Vec::new();
14332    label.runs.retain_mut(|(range, _)| {
14333        match offset_map.get(range.start) {
14334            Some(&start) => range.start = start,
14335            None => {
14336                run_ranges_errors.push(range.clone());
14337                return false;
14338            }
14339        }
14340
14341        match offset_map.get(range.end) {
14342            Some(&end) => range.end = end,
14343            None => {
14344                run_ranges_errors.push(range.clone());
14345                range.end = last_index;
14346            }
14347        }
14348        true
14349    });
14350    if !run_ranges_errors.is_empty() {
14351        log::error!(
14352            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14353            label.text
14354        );
14355    }
14356
14357    let mut wrong_filter_range = None;
14358    if label.filter_range == (0..label.text.len()) {
14359        label.filter_range = 0..new_text.len();
14360    } else {
14361        let mut original_filter_range = Some(label.filter_range.clone());
14362        match offset_map.get(label.filter_range.start) {
14363            Some(&start) => label.filter_range.start = start,
14364            None => {
14365                wrong_filter_range = original_filter_range.take();
14366                label.filter_range.start = last_index;
14367            }
14368        }
14369
14370        match offset_map.get(label.filter_range.end) {
14371            Some(&end) => label.filter_range.end = end,
14372            None => {
14373                wrong_filter_range = original_filter_range.take();
14374                label.filter_range.end = last_index;
14375            }
14376        }
14377    }
14378    if let Some(wrong_filter_range) = wrong_filter_range {
14379        log::error!(
14380            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14381            label.text
14382        );
14383    }
14384
14385    label.text = new_text;
14386}