lsp_store.rs

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