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    CodeLabelExt, Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff,
   75    File as _, Language, LanguageAwareStyling, LanguageName, LanguageRegistry, LocalFile,
   76    LspAdapter, LspAdapterDelegate, LspInstaller, ManifestDelegate, ManifestName, ModelineSettings,
   77    OffsetUtf16, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToOffsetUtf16, ToPointUtf16,
   78    Toolchain, Transaction, Unclipped,
   79    language_settings::{
   80        AllLanguageSettings, FormatOnSave, Formatter, LanguageSettings, all_language_settings,
   81    },
   82    modeline, 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;
  153#[cfg(any(test, feature = "test-support"))]
  154pub use prettier::RANGE_FORMAT_SUFFIX as TEST_PRETTIER_RANGE_FORMAT_SUFFIX;
  155pub use semantic_tokens::{
  156    BufferSemanticToken, BufferSemanticTokens, RefreshForServer, SemanticTokenStylizer, TokenType,
  157};
  158
  159pub use worktree::{
  160    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  161    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  162};
  163
  164const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  165pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  166const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  167const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  168static NEXT_PROMPT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
  169
  170#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  171pub enum ProgressToken {
  172    Number(i32),
  173    String(SharedString),
  174}
  175
  176impl std::fmt::Display for ProgressToken {
  177    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  178        match self {
  179            Self::Number(number) => write!(f, "{number}"),
  180            Self::String(string) => write!(f, "{string}"),
  181        }
  182    }
  183}
  184
  185impl ProgressToken {
  186    fn from_lsp(value: lsp::NumberOrString) -> Self {
  187        match value {
  188            lsp::NumberOrString::Number(number) => Self::Number(number),
  189            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  190        }
  191    }
  192
  193    fn to_lsp(&self) -> lsp::NumberOrString {
  194        match self {
  195            Self::Number(number) => lsp::NumberOrString::Number(*number),
  196            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  197        }
  198    }
  199
  200    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  201        Some(match value.value? {
  202            proto::progress_token::Value::Number(number) => Self::Number(number),
  203            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  204        })
  205    }
  206
  207    fn to_proto(&self) -> proto::ProgressToken {
  208        proto::ProgressToken {
  209            value: Some(match self {
  210                Self::Number(number) => proto::progress_token::Value::Number(*number),
  211                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  212            }),
  213        }
  214    }
  215}
  216
  217#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  218pub enum FormatTrigger {
  219    Save,
  220    Manual,
  221}
  222
  223pub enum LspFormatTarget {
  224    Buffers,
  225    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  226}
  227
  228#[derive(Debug, Clone, PartialEq, Eq, Hash)]
  229pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  230
  231struct OpenLspBuffer(Entity<Buffer>);
  232
  233impl FormatTrigger {
  234    fn from_proto(value: i32) -> FormatTrigger {
  235        match value {
  236            0 => FormatTrigger::Save,
  237            1 => FormatTrigger::Manual,
  238            _ => FormatTrigger::Save,
  239        }
  240    }
  241}
  242
  243#[derive(Clone)]
  244struct UnifiedLanguageServer {
  245    id: LanguageServerId,
  246    project_roots: HashSet<Arc<RelPath>>,
  247}
  248
  249/// Settings that affect language server identity.
  250///
  251/// Dynamic settings (`LspSettings::settings`) are excluded because they can be
  252/// updated via `workspace/didChangeConfiguration` without restarting the server.
  253#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  254struct LanguageServerSeedSettings {
  255    binary: Option<BinarySettings>,
  256    initialization_options: Option<serde_json::Value>,
  257}
  258
  259#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  260struct LanguageServerSeed {
  261    worktree_id: WorktreeId,
  262    name: LanguageServerName,
  263    toolchain: Option<Toolchain>,
  264    settings: LanguageServerSeedSettings,
  265}
  266
  267#[derive(Debug)]
  268pub struct DocumentDiagnosticsUpdate<'a, D> {
  269    pub diagnostics: D,
  270    pub result_id: Option<SharedString>,
  271    pub registration_id: Option<SharedString>,
  272    pub server_id: LanguageServerId,
  273    pub disk_based_sources: Cow<'a, [String]>,
  274}
  275
  276pub struct DocumentDiagnostics {
  277    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  278    document_abs_path: PathBuf,
  279    version: Option<i32>,
  280}
  281
  282#[derive(Default, Debug)]
  283struct DynamicRegistrations {
  284    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  285    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  286}
  287
  288pub struct LocalLspStore {
  289    weak: WeakEntity<LspStore>,
  290    pub worktree_store: Entity<WorktreeStore>,
  291    toolchain_store: Entity<LocalToolchainStore>,
  292    http_client: Arc<dyn HttpClient>,
  293    environment: Entity<ProjectEnvironment>,
  294    fs: Arc<dyn Fs>,
  295    languages: Arc<LanguageRegistry>,
  296    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  297    yarn: Entity<YarnPathStore>,
  298    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  299    buffers_being_formatted: HashSet<BufferId>,
  300    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  301    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  302    watched_manifest_filenames: HashSet<ManifestName>,
  303    language_server_paths_watched_for_rename:
  304        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  305    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  306    supplementary_language_servers:
  307        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  308    prettier_store: Entity<PrettierStore>,
  309    next_diagnostic_group_id: usize,
  310    diagnostics: HashMap<
  311        WorktreeId,
  312        HashMap<
  313            Arc<RelPath>,
  314            Vec<(
  315                LanguageServerId,
  316                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  317            )>,
  318        >,
  319    >,
  320    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  321    _subscription: gpui::Subscription,
  322    lsp_tree: LanguageServerTree,
  323    registered_buffers: HashMap<BufferId, usize>,
  324    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  325    buffer_pull_diagnostics_result_ids: HashMap<
  326        LanguageServerId,
  327        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  328    >,
  329    workspace_pull_diagnostics_result_ids: HashMap<
  330        LanguageServerId,
  331        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  332    >,
  333    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  334
  335    buffers_to_refresh_hash_set: HashSet<BufferId>,
  336    buffers_to_refresh_queue: VecDeque<BufferId>,
  337    _background_diagnostics_worker: Shared<Task<()>>,
  338}
  339
  340impl LocalLspStore {
  341    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  342    pub fn running_language_server_for_id(
  343        &self,
  344        id: LanguageServerId,
  345    ) -> Option<&Arc<LanguageServer>> {
  346        let language_server_state = self.language_servers.get(&id)?;
  347
  348        match language_server_state {
  349            LanguageServerState::Running { server, .. } => Some(server),
  350            LanguageServerState::Starting { .. } => None,
  351        }
  352    }
  353
  354    fn get_or_insert_language_server(
  355        &mut self,
  356        worktree_handle: &Entity<Worktree>,
  357        delegate: Arc<LocalLspAdapterDelegate>,
  358        disposition: &Arc<LaunchDisposition>,
  359        language_name: &LanguageName,
  360        cx: &mut App,
  361    ) -> LanguageServerId {
  362        let key = LanguageServerSeed {
  363            worktree_id: worktree_handle.read(cx).id(),
  364            name: disposition.server_name.clone(),
  365            settings: LanguageServerSeedSettings {
  366                binary: disposition.settings.binary.clone(),
  367                initialization_options: disposition.settings.initialization_options.clone(),
  368            },
  369            toolchain: disposition.toolchain.clone(),
  370        };
  371        if let Some(state) = self.language_server_ids.get_mut(&key) {
  372            state.project_roots.insert(disposition.path.path.clone());
  373            state.id
  374        } else {
  375            let adapter = self
  376                .languages
  377                .lsp_adapters(language_name)
  378                .into_iter()
  379                .find(|adapter| adapter.name() == disposition.server_name)
  380                .expect("To find LSP adapter");
  381            let new_language_server_id = self.start_language_server(
  382                worktree_handle,
  383                delegate,
  384                adapter,
  385                disposition.settings.clone(),
  386                key.clone(),
  387                language_name.clone(),
  388                cx,
  389            );
  390            if let Some(state) = self.language_server_ids.get_mut(&key) {
  391                state.project_roots.insert(disposition.path.path.clone());
  392            } else {
  393                debug_assert!(
  394                    false,
  395                    "Expected `start_language_server` to ensure that `key` exists in a map"
  396                );
  397            }
  398            new_language_server_id
  399        }
  400    }
  401
  402    fn start_language_server(
  403        &mut self,
  404        worktree_handle: &Entity<Worktree>,
  405        delegate: Arc<LocalLspAdapterDelegate>,
  406        adapter: Arc<CachedLspAdapter>,
  407        settings: Arc<LspSettings>,
  408        key: LanguageServerSeed,
  409        language_name: LanguageName,
  410        cx: &mut App,
  411    ) -> LanguageServerId {
  412        let worktree = worktree_handle.read(cx);
  413
  414        let worktree_id = worktree.id();
  415        let worktree_abs_path = worktree.abs_path();
  416        let toolchain = key.toolchain.clone();
  417        let override_options = settings.initialization_options.clone();
  418
  419        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  420
  421        let server_id = self.languages.next_language_server_id();
  422        log::trace!(
  423            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  424            adapter.name.0
  425        );
  426
  427        let wait_until_worktree_trust =
  428            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  429                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  430                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  431                });
  432                if can_trust {
  433                    self.restricted_worktrees_tasks.remove(&worktree_id);
  434                    None
  435                } else {
  436                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  437                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  438                        hash_map::Entry::Vacant(v) => {
  439                            let (mut tx, rx) = watch::channel::<bool>();
  440                            let lsp_store = self.weak.clone();
  441                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  442                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  443                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  444                                        tx.blocking_send(true).ok();
  445                                        lsp_store
  446                                            .update(cx, |lsp_store, _| {
  447                                                if let Some(local_lsp_store) =
  448                                                    lsp_store.as_local_mut()
  449                                                {
  450                                                    local_lsp_store
  451                                                        .restricted_worktrees_tasks
  452                                                        .remove(&worktree_id);
  453                                                }
  454                                            })
  455                                            .ok();
  456                                    }
  457                                }
  458                            });
  459                            v.insert((subscription, rx.clone()));
  460                            Some(rx)
  461                        }
  462                    }
  463                }
  464            });
  465        let update_binary_status = wait_until_worktree_trust.is_none();
  466
  467        let binary = self.get_language_server_binary(
  468            worktree_abs_path.clone(),
  469            adapter.clone(),
  470            settings,
  471            toolchain.clone(),
  472            delegate.clone(),
  473            true,
  474            wait_until_worktree_trust,
  475            cx,
  476        );
  477        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  478
  479        let pending_server = cx.spawn({
  480            let adapter = adapter.clone();
  481            let server_name = adapter.name.clone();
  482            let stderr_capture = stderr_capture.clone();
  483            #[cfg(any(test, feature = "test-support"))]
  484            let lsp_store = self.weak.clone();
  485            let pending_workspace_folders = pending_workspace_folders.clone();
  486            async move |cx| {
  487                let binary = binary.await?;
  488                #[cfg(any(test, feature = "test-support"))]
  489                if let Some(server) = lsp_store
  490                    .update(&mut cx.clone(), |this, cx| {
  491                        this.languages.create_fake_language_server(
  492                            server_id,
  493                            &server_name,
  494                            binary.clone(),
  495                            &mut cx.to_async(),
  496                        )
  497                    })
  498                    .ok()
  499                    .flatten()
  500                {
  501                    return Ok(server);
  502                }
  503
  504                let code_action_kinds = adapter.code_action_kinds();
  505                lsp::LanguageServer::new(
  506                    stderr_capture,
  507                    server_id,
  508                    server_name,
  509                    binary,
  510                    &worktree_abs_path,
  511                    code_action_kinds,
  512                    Some(pending_workspace_folders),
  513                    cx,
  514                )
  515            }
  516        });
  517
  518        let startup = {
  519            let server_name = adapter.name.0.clone();
  520            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  521            let key = key.clone();
  522            let adapter = adapter.clone();
  523            let lsp_store = self.weak.clone();
  524            let pending_workspace_folders = pending_workspace_folders.clone();
  525            let pull_diagnostics = ProjectSettings::get_global(cx)
  526                .diagnostics
  527                .lsp_pull_diagnostics
  528                .enabled;
  529            let settings_location = SettingsLocation {
  530                worktree_id,
  531                path: RelPath::empty(),
  532            };
  533            let augments_syntax_tokens = AllLanguageSettings::get(Some(settings_location), cx)
  534                .language(Some(settings_location), Some(&language_name), cx)
  535                .semantic_tokens
  536                .use_tree_sitter();
  537            cx.spawn(async move |cx| {
  538                let result = async {
  539                    let language_server = pending_server.await?;
  540
  541                    let workspace_config = Self::workspace_configuration_for_adapter(
  542                        adapter.adapter.clone(),
  543                        &delegate,
  544                        toolchain,
  545                        None,
  546                        cx,
  547                    )
  548                    .await?;
  549
  550                    let mut initialization_options = Self::initialization_options_for_adapter(
  551                        adapter.adapter.clone(),
  552                        &delegate,
  553                        cx,
  554                    )
  555                    .await?;
  556
  557                    match (&mut initialization_options, override_options) {
  558                        (Some(initialization_options), Some(override_options)) => {
  559                            merge_json_value_into(override_options, initialization_options);
  560                        }
  561                        (None, override_options) => initialization_options = override_options,
  562                        _ => {}
  563                    }
  564
  565                    let initialization_params = cx.update(|cx| {
  566                        let mut params = language_server.default_initialize_params(
  567                            pull_diagnostics,
  568                            augments_syntax_tokens,
  569                            cx,
  570                        );
  571                        params.initialization_options = initialization_options;
  572                        adapter.adapter.prepare_initialize_params(params, cx)
  573                    })?;
  574
  575                    Self::setup_lsp_messages(
  576                        lsp_store.clone(),
  577                        &language_server,
  578                        delegate.clone(),
  579                        adapter.clone(),
  580                    );
  581
  582                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  583                        settings: workspace_config,
  584                    };
  585                    let language_server = cx
  586                        .update(|cx| {
  587                            let request_timeout = ProjectSettings::get_global(cx)
  588                                .global_lsp_settings
  589                                .get_request_timeout();
  590
  591                            language_server.initialize(
  592                                initialization_params,
  593                                Arc::new(did_change_configuration_params.clone()),
  594                                request_timeout,
  595                                cx,
  596                            )
  597                        })
  598                        .await
  599                        .inspect_err(|_| {
  600                            if let Some(lsp_store) = lsp_store.upgrade() {
  601                                lsp_store.update(cx, |lsp_store, cx| {
  602                                    lsp_store.cleanup_lsp_data(server_id);
  603                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  604                                });
  605                            }
  606                        })?;
  607
  608                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  609                        did_change_configuration_params,
  610                    )?;
  611
  612                    anyhow::Ok(language_server)
  613                }
  614                .await;
  615
  616                match result {
  617                    Ok(server) => {
  618                        lsp_store
  619                            .update(cx, |lsp_store, cx| {
  620                                lsp_store.insert_newly_running_language_server(
  621                                    adapter,
  622                                    server.clone(),
  623                                    server_id,
  624                                    key,
  625                                    pending_workspace_folders,
  626                                    cx,
  627                                );
  628                            })
  629                            .ok();
  630                        stderr_capture.lock().take();
  631                        Some(server)
  632                    }
  633
  634                    Err(err) => {
  635                        let log = stderr_capture.lock().take().unwrap_or_default();
  636                        delegate.update_status(
  637                            adapter.name(),
  638                            BinaryStatus::Failed {
  639                                error: if log.is_empty() {
  640                                    format!("{err:#}")
  641                                } else {
  642                                    format!("{err:#}\n-- stderr --\n{log}")
  643                                },
  644                            },
  645                        );
  646                        log::error!(
  647                            "Failed to start language server {server_name:?}: {}",
  648                            redact_command(&format!("{err:?}"))
  649                        );
  650                        if !log.is_empty() {
  651                            log::error!("server stderr: {}", redact_command(&log));
  652                        }
  653                        None
  654                    }
  655                }
  656            })
  657        };
  658        let state = LanguageServerState::Starting {
  659            startup,
  660            pending_workspace_folders,
  661        };
  662
  663        if update_binary_status {
  664            self.languages
  665                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  666        }
  667
  668        self.language_servers.insert(server_id, state);
  669        self.language_server_ids
  670            .entry(key)
  671            .or_insert(UnifiedLanguageServer {
  672                id: server_id,
  673                project_roots: Default::default(),
  674            });
  675        server_id
  676    }
  677
  678    fn get_language_server_binary(
  679        &self,
  680        worktree_abs_path: Arc<Path>,
  681        adapter: Arc<CachedLspAdapter>,
  682        settings: Arc<LspSettings>,
  683        toolchain: Option<Toolchain>,
  684        delegate: Arc<dyn LspAdapterDelegate>,
  685        allow_binary_download: bool,
  686        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  687        cx: &mut App,
  688    ) -> Task<Result<LanguageServerBinary>> {
  689        if let Some(settings) = &settings.binary
  690            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  691        {
  692            let settings = settings.clone();
  693            let languages = self.languages.clone();
  694            return cx.background_spawn(async move {
  695                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  696                    let already_trusted =  *wait_until_worktree_trust.borrow();
  697                    if !already_trusted {
  698                        log::info!(
  699                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  700                            adapter.name(),
  701                        );
  702                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  703                            if worktree_trusted {
  704                                break;
  705                            }
  706                        }
  707                        log::info!(
  708                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  709                            adapter.name(),
  710                        );
  711                    }
  712                    languages
  713                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  714                }
  715                let mut env = delegate.shell_env().await;
  716                env.extend(settings.env.unwrap_or_default());
  717
  718                Ok(LanguageServerBinary {
  719                    path: delegate.resolve_relative_path(path),
  720                    env: Some(env),
  721                    arguments: settings
  722                        .arguments
  723                        .unwrap_or_default()
  724                        .iter()
  725                        .map(Into::into)
  726                        .collect(),
  727                })
  728            });
  729        }
  730        let lsp_binary_options = LanguageServerBinaryOptions {
  731            allow_path_lookup: !settings
  732                .binary
  733                .as_ref()
  734                .and_then(|b| b.ignore_system_version)
  735                .unwrap_or_default(),
  736            allow_binary_download,
  737            pre_release: settings
  738                .fetch
  739                .as_ref()
  740                .and_then(|f| f.pre_release)
  741                .unwrap_or(false),
  742        };
  743
  744        cx.spawn(async move |cx| {
  745            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  746                let already_trusted =  *wait_until_worktree_trust.borrow();
  747                if !already_trusted {
  748                    log::info!(
  749                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  750                        adapter.name(),
  751                    );
  752                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  753                        if worktree_trusted {
  754                            break;
  755                        }
  756                    }
  757                    log::info!(
  758                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  759                            adapter.name(),
  760                    );
  761                }
  762            }
  763
  764            let (existing_binary, maybe_download_binary) = adapter
  765                .clone()
  766                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  767                .await
  768                .await;
  769
  770            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  771
  772            let mut binary = match (existing_binary, maybe_download_binary) {
  773                (binary, None) => binary?,
  774                (Err(_), Some(downloader)) => downloader.await?,
  775                (Ok(existing_binary), Some(downloader)) => {
  776                    let mut download_timeout = cx
  777                        .background_executor()
  778                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  779                        .fuse();
  780                    let mut downloader = downloader.fuse();
  781                    futures::select! {
  782                        _ = download_timeout => {
  783                            // Return existing binary and kick the existing work to the background.
  784                            cx.spawn(async move |_| downloader.await).detach();
  785                            Ok(existing_binary)
  786                        },
  787                        downloaded_or_existing_binary = downloader => {
  788                            // If download fails, this results in the existing binary.
  789                            downloaded_or_existing_binary
  790                        }
  791                    }?
  792                }
  793            };
  794            let mut shell_env = delegate.shell_env().await;
  795
  796            shell_env.extend(binary.env.unwrap_or_default());
  797
  798            if let Some(settings) = settings.binary.as_ref() {
  799                if let Some(arguments) = &settings.arguments {
  800                    binary.arguments = arguments.iter().map(Into::into).collect();
  801                }
  802                if let Some(env) = &settings.env {
  803                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  804                }
  805            }
  806
  807            binary.env = Some(shell_env);
  808            Ok(binary)
  809        })
  810    }
  811
  812    fn setup_lsp_messages(
  813        lsp_store: WeakEntity<LspStore>,
  814        language_server: &LanguageServer,
  815        delegate: Arc<dyn LspAdapterDelegate>,
  816        adapter: Arc<CachedLspAdapter>,
  817    ) {
  818        let name = language_server.name();
  819        let server_id = language_server.server_id();
  820        language_server
  821            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  822                let adapter = adapter.clone();
  823                let this = lsp_store.clone();
  824                move |mut params, cx| {
  825                    let adapter = adapter.clone();
  826                    if let Some(this) = this.upgrade() {
  827                        this.update(cx, |this, cx| {
  828                            adapter.process_diagnostics(&mut params, server_id);
  829
  830                            this.merge_lsp_diagnostics(
  831                                DiagnosticSourceKind::Pushed,
  832                                vec![DocumentDiagnosticsUpdate {
  833                                    server_id,
  834                                    diagnostics: params,
  835                                    result_id: None,
  836                                    disk_based_sources: Cow::Borrowed(
  837                                        &adapter.disk_based_diagnostic_sources,
  838                                    ),
  839                                    registration_id: None,
  840                                }],
  841                                |_, diagnostic, _cx| match diagnostic.source_kind {
  842                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  843                                        adapter.retain_old_diagnostic(diagnostic)
  844                                    }
  845                                    DiagnosticSourceKind::Pulled => true,
  846                                },
  847                                cx,
  848                            )
  849                            .log_err();
  850                        });
  851                    }
  852                }
  853            })
  854            .detach();
  855        language_server
  856            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  857                let adapter = adapter.adapter.clone();
  858                let delegate = delegate.clone();
  859                let this = lsp_store.clone();
  860                move |params, cx| {
  861                    let adapter = adapter.clone();
  862                    let delegate = delegate.clone();
  863                    let this = this.clone();
  864                    let mut cx = cx.clone();
  865                    async move {
  866                        let toolchain_for_id = this
  867                            .update(&mut cx, |this, _| {
  868                                this.as_local()?.language_server_ids.iter().find_map(
  869                                    |(seed, value)| {
  870                                        (value.id == server_id).then(|| seed.toolchain.clone())
  871                                    },
  872                                )
  873                            })?
  874                            .context("Expected the LSP store to be in a local mode")?;
  875
  876                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  877                        for item in &params.items {
  878                            let scope_uri = item.scope_uri.clone();
  879                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  880                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  881                            else {
  882                                // We've already queried workspace configuration of this URI.
  883                                continue;
  884                            };
  885                            let workspace_config = Self::workspace_configuration_for_adapter(
  886                                adapter.clone(),
  887                                &delegate,
  888                                toolchain_for_id.clone(),
  889                                scope_uri,
  890                                &mut cx,
  891                            )
  892                            .await?;
  893                            new_scope_uri.insert(workspace_config);
  894                        }
  895
  896                        Ok(params
  897                            .items
  898                            .into_iter()
  899                            .filter_map(|item| {
  900                                let workspace_config =
  901                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  902                                if let Some(section) = &item.section {
  903                                    Some(
  904                                        workspace_config
  905                                            .get(section)
  906                                            .cloned()
  907                                            .unwrap_or(serde_json::Value::Null),
  908                                    )
  909                                } else {
  910                                    Some(workspace_config.clone())
  911                                }
  912                            })
  913                            .collect())
  914                    }
  915                }
  916            })
  917            .detach();
  918
  919        language_server
  920            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  921                let this = lsp_store.clone();
  922                move |_, cx| {
  923                    let this = this.clone();
  924                    let cx = cx.clone();
  925                    async move {
  926                        let Some(server) =
  927                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  928                        else {
  929                            return Ok(None);
  930                        };
  931                        let root = server.workspace_folders();
  932                        Ok(Some(
  933                            root.into_iter()
  934                                .map(|uri| WorkspaceFolder {
  935                                    uri,
  936                                    name: Default::default(),
  937                                })
  938                                .collect(),
  939                        ))
  940                    }
  941                }
  942            })
  943            .detach();
  944        // Even though we don't have handling for these requests, respond to them to
  945        // avoid stalling any language server like `gopls` which waits for a response
  946        // to these requests when initializing.
  947        language_server
  948            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  949                let this = lsp_store.clone();
  950                move |params, cx| {
  951                    let this = this.clone();
  952                    let mut cx = cx.clone();
  953                    async move {
  954                        this.update(&mut cx, |this, _| {
  955                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  956                            {
  957                                status
  958                                    .progress_tokens
  959                                    .insert(ProgressToken::from_lsp(params.token));
  960                            }
  961                        })?;
  962
  963                        Ok(())
  964                    }
  965                }
  966            })
  967            .detach();
  968
  969        language_server
  970            .on_request::<lsp::request::RegisterCapability, _, _>({
  971                let lsp_store = lsp_store.clone();
  972                move |params, cx| {
  973                    let lsp_store = lsp_store.clone();
  974                    let mut cx = cx.clone();
  975                    async move {
  976                        lsp_store
  977                            .update(&mut cx, |lsp_store, cx| {
  978                                if lsp_store.as_local().is_some() {
  979                                    match lsp_store
  980                                        .register_server_capabilities(server_id, params, cx)
  981                                    {
  982                                        Ok(()) => {}
  983                                        Err(e) => {
  984                                            log::error!(
  985                                                "Failed to register server capabilities: {e:#}"
  986                                            );
  987                                        }
  988                                    };
  989                                }
  990                            })
  991                            .ok();
  992                        Ok(())
  993                    }
  994                }
  995            })
  996            .detach();
  997
  998        language_server
  999            .on_request::<lsp::request::UnregisterCapability, _, _>({
 1000                let lsp_store = lsp_store.clone();
 1001                move |params, cx| {
 1002                    let lsp_store = lsp_store.clone();
 1003                    let mut cx = cx.clone();
 1004                    async move {
 1005                        lsp_store
 1006                            .update(&mut cx, |lsp_store, cx| {
 1007                                if lsp_store.as_local().is_some() {
 1008                                    match lsp_store
 1009                                        .unregister_server_capabilities(server_id, params, cx)
 1010                                    {
 1011                                        Ok(()) => {}
 1012                                        Err(e) => {
 1013                                            log::error!(
 1014                                                "Failed to unregister server capabilities: {e:#}"
 1015                                            );
 1016                                        }
 1017                                    }
 1018                                }
 1019                            })
 1020                            .ok();
 1021                        Ok(())
 1022                    }
 1023                }
 1024            })
 1025            .detach();
 1026
 1027        language_server
 1028            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
 1029                let this = lsp_store.clone();
 1030                move |params, cx| {
 1031                    let mut cx = cx.clone();
 1032                    let this = this.clone();
 1033                    async move {
 1034                        LocalLspStore::on_lsp_workspace_edit(
 1035                            this.clone(),
 1036                            params,
 1037                            server_id,
 1038                            &mut cx,
 1039                        )
 1040                        .await
 1041                    }
 1042                }
 1043            })
 1044            .detach();
 1045
 1046        language_server
 1047            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1048                let lsp_store = lsp_store.clone();
 1049                let request_id = Arc::new(AtomicUsize::new(0));
 1050                move |(), cx| {
 1051                    let lsp_store = lsp_store.clone();
 1052                    let request_id = request_id.clone();
 1053                    let mut cx = cx.clone();
 1054                    async move {
 1055                        lsp_store
 1056                            .update(&mut cx, |lsp_store, cx| {
 1057                                let request_id =
 1058                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1059                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1060                                    server_id,
 1061                                    request_id,
 1062                                });
 1063                                lsp_store
 1064                                    .downstream_client
 1065                                    .as_ref()
 1066                                    .map(|(client, project_id)| {
 1067                                        client.send(proto::RefreshInlayHints {
 1068                                            project_id: *project_id,
 1069                                            server_id: server_id.to_proto(),
 1070                                            request_id: request_id.map(|id| id as u64),
 1071                                        })
 1072                                    })
 1073                            })?
 1074                            .transpose()?;
 1075                        Ok(())
 1076                    }
 1077                }
 1078            })
 1079            .detach();
 1080
 1081        language_server
 1082            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1083                let this = lsp_store.clone();
 1084                move |(), cx| {
 1085                    let this = this.clone();
 1086                    let mut cx = cx.clone();
 1087                    async move {
 1088                        this.update(&mut cx, |this, cx| {
 1089                            this.invalidate_code_lens();
 1090                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1091                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1092                                client.send(proto::RefreshCodeLens {
 1093                                    project_id: *project_id,
 1094                                })
 1095                            })
 1096                        })?
 1097                        .transpose()?;
 1098                        Ok(())
 1099                    }
 1100                }
 1101            })
 1102            .detach();
 1103
 1104        language_server
 1105            .on_request::<lsp::request::SemanticTokensRefresh, _, _>({
 1106                let lsp_store = lsp_store.clone();
 1107                let request_id = Arc::new(AtomicUsize::new(0));
 1108                move |(), cx| {
 1109                    let lsp_store = lsp_store.clone();
 1110                    let request_id = request_id.clone();
 1111                    let mut cx = cx.clone();
 1112                    async move {
 1113                        lsp_store
 1114                            .update(&mut cx, |lsp_store, cx| {
 1115                                let request_id =
 1116                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1117                                cx.emit(LspStoreEvent::RefreshSemanticTokens {
 1118                                    server_id,
 1119                                    request_id,
 1120                                });
 1121                                lsp_store
 1122                                    .downstream_client
 1123                                    .as_ref()
 1124                                    .map(|(client, project_id)| {
 1125                                        client.send(proto::RefreshSemanticTokens {
 1126                                            project_id: *project_id,
 1127                                            server_id: server_id.to_proto(),
 1128                                            request_id: request_id.map(|id| id as u64),
 1129                                        })
 1130                                    })
 1131                            })?
 1132                            .transpose()?;
 1133                        Ok(())
 1134                    }
 1135                }
 1136            })
 1137            .detach();
 1138
 1139        language_server
 1140            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1141                let this = lsp_store.clone();
 1142                move |(), cx| {
 1143                    let this = this.clone();
 1144                    let mut cx = cx.clone();
 1145                    async move {
 1146                        this.update(&mut cx, |lsp_store, cx| {
 1147                            lsp_store.pull_workspace_diagnostics(server_id);
 1148                            lsp_store
 1149                                .downstream_client
 1150                                .as_ref()
 1151                                .map(|(client, project_id)| {
 1152                                    client.send(proto::PullWorkspaceDiagnostics {
 1153                                        project_id: *project_id,
 1154                                        server_id: server_id.to_proto(),
 1155                                    })
 1156                                })
 1157                                .transpose()?;
 1158                            anyhow::Ok(
 1159                                lsp_store.pull_document_diagnostics_for_server(server_id, None, cx),
 1160                            )
 1161                        })??
 1162                        .await;
 1163                        Ok(())
 1164                    }
 1165                }
 1166            })
 1167            .detach();
 1168
 1169        language_server
 1170            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1171                let this = lsp_store.clone();
 1172                let name = name.to_string();
 1173                let adapter = adapter.clone();
 1174                move |params, cx| {
 1175                    let this = this.clone();
 1176                    let name = name.to_string();
 1177                    let adapter = adapter.clone();
 1178                    let mut cx = cx.clone();
 1179                    async move {
 1180                        let actions = params.actions.unwrap_or_default();
 1181                        let message = params.message.clone();
 1182                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1183                        let level = match params.typ {
 1184                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1185                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1186                            _ => PromptLevel::Info,
 1187                        };
 1188                        let request = LanguageServerPromptRequest::new(
 1189                            level,
 1190                            params.message,
 1191                            actions,
 1192                            name.clone(),
 1193                            tx,
 1194                        );
 1195
 1196                        let did_update = this
 1197                            .update(&mut cx, |_, cx| {
 1198                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1199                            })
 1200                            .is_ok();
 1201                        if did_update {
 1202                            let response = rx.recv().await.ok();
 1203                            if let Some(ref selected_action) = response {
 1204                                let context = language::PromptResponseContext {
 1205                                    message,
 1206                                    selected_action: selected_action.clone(),
 1207                                };
 1208                                adapter.process_prompt_response(&context, &mut cx)
 1209                            }
 1210
 1211                            Ok(response)
 1212                        } else {
 1213                            Ok(None)
 1214                        }
 1215                    }
 1216                }
 1217            })
 1218            .detach();
 1219        language_server
 1220            .on_notification::<lsp::notification::ShowMessage, _>({
 1221                let this = lsp_store.clone();
 1222                let name = name.to_string();
 1223                move |params, cx| {
 1224                    let this = this.clone();
 1225                    let name = name.to_string();
 1226                    let mut cx = cx.clone();
 1227
 1228                    let (tx, _) = smol::channel::bounded(1);
 1229                    let level = match params.typ {
 1230                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1231                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1232                        _ => PromptLevel::Info,
 1233                    };
 1234                    let request =
 1235                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1236
 1237                    let _ = this.update(&mut cx, |_, cx| {
 1238                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1239                    });
 1240                }
 1241            })
 1242            .detach();
 1243
 1244        let disk_based_diagnostics_progress_token =
 1245            adapter.disk_based_diagnostics_progress_token.clone();
 1246
 1247        language_server
 1248            .on_notification::<lsp::notification::Progress, _>({
 1249                let this = lsp_store.clone();
 1250                move |params, cx| {
 1251                    if let Some(this) = this.upgrade() {
 1252                        this.update(cx, |this, cx| {
 1253                            this.on_lsp_progress(
 1254                                params,
 1255                                server_id,
 1256                                disk_based_diagnostics_progress_token.clone(),
 1257                                cx,
 1258                            );
 1259                        });
 1260                    }
 1261                }
 1262            })
 1263            .detach();
 1264
 1265        language_server
 1266            .on_notification::<lsp::notification::LogMessage, _>({
 1267                let this = lsp_store.clone();
 1268                move |params, cx| {
 1269                    if let Some(this) = this.upgrade() {
 1270                        this.update(cx, |_, cx| {
 1271                            cx.emit(LspStoreEvent::LanguageServerLog(
 1272                                server_id,
 1273                                LanguageServerLogType::Log(params.typ),
 1274                                params.message,
 1275                            ));
 1276                        });
 1277                    }
 1278                }
 1279            })
 1280            .detach();
 1281
 1282        language_server
 1283            .on_notification::<lsp::notification::LogTrace, _>({
 1284                let this = lsp_store.clone();
 1285                move |params, cx| {
 1286                    let mut cx = cx.clone();
 1287                    if let Some(this) = this.upgrade() {
 1288                        this.update(&mut cx, |_, cx| {
 1289                            cx.emit(LspStoreEvent::LanguageServerLog(
 1290                                server_id,
 1291                                LanguageServerLogType::Trace {
 1292                                    verbose_info: params.verbose,
 1293                                },
 1294                                params.message,
 1295                            ));
 1296                        });
 1297                    }
 1298                }
 1299            })
 1300            .detach();
 1301
 1302        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1303        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1304        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1305        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1306    }
 1307
 1308    fn shutdown_language_servers_on_quit(&mut self) -> impl Future<Output = ()> + use<> {
 1309        let shutdown_futures = self
 1310            .language_servers
 1311            .drain()
 1312            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1313            .collect::<Vec<_>>();
 1314
 1315        async move {
 1316            join_all(shutdown_futures).await;
 1317        }
 1318    }
 1319
 1320    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1321        match server_state {
 1322            LanguageServerState::Running { server, .. } => {
 1323                if let Some(shutdown) = server.shutdown() {
 1324                    shutdown.await;
 1325                }
 1326            }
 1327            LanguageServerState::Starting { startup, .. } => {
 1328                if let Some(server) = startup.await
 1329                    && let Some(shutdown) = server.shutdown()
 1330                {
 1331                    shutdown.await;
 1332                }
 1333            }
 1334        }
 1335        Ok(())
 1336    }
 1337
 1338    fn language_servers_for_worktree(
 1339        &self,
 1340        worktree_id: WorktreeId,
 1341    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1342        self.language_server_ids
 1343            .iter()
 1344            .filter_map(move |(seed, state)| {
 1345                if seed.worktree_id != worktree_id {
 1346                    return None;
 1347                }
 1348
 1349                if let Some(LanguageServerState::Running { server, .. }) =
 1350                    self.language_servers.get(&state.id)
 1351                {
 1352                    Some(server)
 1353                } else {
 1354                    None
 1355                }
 1356            })
 1357    }
 1358
 1359    fn language_server_ids_for_project_path(
 1360        &self,
 1361        project_path: ProjectPath,
 1362        language: &Language,
 1363        cx: &mut App,
 1364    ) -> Vec<LanguageServerId> {
 1365        let Some(worktree) = self
 1366            .worktree_store
 1367            .read(cx)
 1368            .worktree_for_id(project_path.worktree_id, cx)
 1369        else {
 1370            return Vec::new();
 1371        };
 1372        let delegate: Arc<dyn ManifestDelegate> =
 1373            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1374
 1375        self.lsp_tree
 1376            .get(
 1377                project_path,
 1378                language.name(),
 1379                language.manifest(),
 1380                &delegate,
 1381                cx,
 1382            )
 1383            .collect::<Vec<_>>()
 1384    }
 1385
 1386    fn language_server_ids_for_buffer(
 1387        &self,
 1388        buffer: &Buffer,
 1389        cx: &mut App,
 1390    ) -> Vec<LanguageServerId> {
 1391        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1392            let worktree_id = file.worktree_id(cx);
 1393
 1394            let path: Arc<RelPath> = file
 1395                .path()
 1396                .parent()
 1397                .map(Arc::from)
 1398                .unwrap_or_else(|| file.path().clone());
 1399            let worktree_path = ProjectPath { worktree_id, path };
 1400            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1401        } else {
 1402            Vec::new()
 1403        }
 1404    }
 1405
 1406    fn language_servers_for_buffer<'a>(
 1407        &'a self,
 1408        buffer: &'a Buffer,
 1409        cx: &'a mut App,
 1410    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1411        self.language_server_ids_for_buffer(buffer, cx)
 1412            .into_iter()
 1413            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1414                LanguageServerState::Running {
 1415                    adapter, server, ..
 1416                } => Some((adapter, server)),
 1417                _ => None,
 1418            })
 1419    }
 1420
 1421    async fn execute_code_action_kind_locally(
 1422        lsp_store: WeakEntity<LspStore>,
 1423        mut buffers: Vec<Entity<Buffer>>,
 1424        kind: CodeActionKind,
 1425        push_to_history: bool,
 1426        cx: &mut AsyncApp,
 1427    ) -> anyhow::Result<ProjectTransaction> {
 1428        // Do not allow multiple concurrent code actions requests for the
 1429        // same buffer.
 1430        lsp_store.update(cx, |this, cx| {
 1431            let this = this.as_local_mut().unwrap();
 1432            buffers.retain(|buffer| {
 1433                this.buffers_being_formatted
 1434                    .insert(buffer.read(cx).remote_id())
 1435            });
 1436        })?;
 1437        let _cleanup = defer({
 1438            let this = lsp_store.clone();
 1439            let mut cx = cx.clone();
 1440            let buffers = &buffers;
 1441            move || {
 1442                this.update(&mut cx, |this, cx| {
 1443                    let this = this.as_local_mut().unwrap();
 1444                    for buffer in buffers {
 1445                        this.buffers_being_formatted
 1446                            .remove(&buffer.read(cx).remote_id());
 1447                    }
 1448                })
 1449                .ok();
 1450            }
 1451        });
 1452        let mut project_transaction = ProjectTransaction::default();
 1453
 1454        for buffer in &buffers {
 1455            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1456                buffer.update(cx, |buffer, cx| {
 1457                    lsp_store
 1458                        .as_local()
 1459                        .unwrap()
 1460                        .language_servers_for_buffer(buffer, cx)
 1461                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1462                        .collect::<Vec<_>>()
 1463                })
 1464            })?;
 1465            for (_, language_server) in adapters_and_servers.iter() {
 1466                let actions = Self::get_server_code_actions_from_action_kinds(
 1467                    &lsp_store,
 1468                    language_server.server_id(),
 1469                    vec![kind.clone()],
 1470                    buffer,
 1471                    cx,
 1472                )
 1473                .await?;
 1474                Self::execute_code_actions_on_server(
 1475                    &lsp_store,
 1476                    language_server,
 1477                    actions,
 1478                    push_to_history,
 1479                    &mut project_transaction,
 1480                    cx,
 1481                )
 1482                .await?;
 1483            }
 1484        }
 1485        Ok(project_transaction)
 1486    }
 1487
 1488    async fn format_locally(
 1489        lsp_store: WeakEntity<LspStore>,
 1490        mut buffers: Vec<FormattableBuffer>,
 1491        push_to_history: bool,
 1492        trigger: FormatTrigger,
 1493        logger: zlog::Logger,
 1494        cx: &mut AsyncApp,
 1495    ) -> anyhow::Result<ProjectTransaction> {
 1496        // Do not allow multiple concurrent formatting requests for the
 1497        // same buffer.
 1498        lsp_store.update(cx, |this, cx| {
 1499            let this = this.as_local_mut().unwrap();
 1500            buffers.retain(|buffer| {
 1501                this.buffers_being_formatted
 1502                    .insert(buffer.handle.read(cx).remote_id())
 1503            });
 1504        })?;
 1505
 1506        let _cleanup = defer({
 1507            let this = lsp_store.clone();
 1508            let mut cx = cx.clone();
 1509            let buffers = &buffers;
 1510            move || {
 1511                this.update(&mut cx, |this, cx| {
 1512                    let this = this.as_local_mut().unwrap();
 1513                    for buffer in buffers {
 1514                        this.buffers_being_formatted
 1515                            .remove(&buffer.handle.read(cx).remote_id());
 1516                    }
 1517                })
 1518                .ok();
 1519            }
 1520        });
 1521
 1522        let mut project_transaction = ProjectTransaction::default();
 1523
 1524        for buffer in &buffers {
 1525            zlog::debug!(
 1526                logger =>
 1527                "formatting buffer '{:?}'",
 1528                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1529            );
 1530            // Create an empty transaction to hold all of the formatting edits.
 1531            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1532                // ensure no transactions created while formatting are
 1533                // grouped with the previous transaction in the history
 1534                // based on the transaction group interval
 1535                buffer.finalize_last_transaction();
 1536                buffer
 1537                    .start_transaction()
 1538                    .context("transaction already open")?;
 1539                buffer.end_transaction(cx);
 1540                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1541                buffer.finalize_last_transaction();
 1542                anyhow::Ok(transaction_id)
 1543            })?;
 1544
 1545            let result = Self::format_buffer_locally(
 1546                lsp_store.clone(),
 1547                buffer,
 1548                formatting_transaction_id,
 1549                trigger,
 1550                logger,
 1551                cx,
 1552            )
 1553            .await;
 1554
 1555            buffer.handle.update(cx, |buffer, cx| {
 1556                let Some(formatting_transaction) =
 1557                    buffer.get_transaction(formatting_transaction_id).cloned()
 1558                else {
 1559                    zlog::warn!(logger => "no formatting transaction");
 1560                    return;
 1561                };
 1562                if formatting_transaction.edit_ids.is_empty() {
 1563                    zlog::debug!(logger => "no changes made while formatting");
 1564                    buffer.forget_transaction(formatting_transaction_id);
 1565                    return;
 1566                }
 1567                if !push_to_history {
 1568                    zlog::trace!(logger => "forgetting format transaction");
 1569                    buffer.forget_transaction(formatting_transaction.id);
 1570                }
 1571                project_transaction
 1572                    .0
 1573                    .insert(cx.entity(), formatting_transaction);
 1574            });
 1575
 1576            result?;
 1577        }
 1578
 1579        Ok(project_transaction)
 1580    }
 1581
 1582    async fn format_buffer_locally(
 1583        lsp_store: WeakEntity<LspStore>,
 1584        buffer: &FormattableBuffer,
 1585        formatting_transaction_id: clock::Lamport,
 1586        trigger: FormatTrigger,
 1587        logger: zlog::Logger,
 1588        cx: &mut AsyncApp,
 1589    ) -> Result<()> {
 1590        let (adapters_and_servers, settings, request_timeout) =
 1591            lsp_store.update(cx, |lsp_store, cx| {
 1592                buffer.handle.update(cx, |buffer, cx| {
 1593                    let adapters_and_servers = lsp_store
 1594                        .as_local()
 1595                        .unwrap()
 1596                        .language_servers_for_buffer(buffer, cx)
 1597                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1598                        .collect::<Vec<_>>();
 1599                    let settings = LanguageSettings::for_buffer(buffer, cx).into_owned();
 1600                    let request_timeout = ProjectSettings::get_global(cx)
 1601                        .global_lsp_settings
 1602                        .get_request_timeout();
 1603                    (adapters_and_servers, settings, request_timeout)
 1604                })
 1605            })?;
 1606
 1607        // handle whitespace formatting
 1608        if settings.remove_trailing_whitespace_on_save {
 1609            zlog::trace!(logger => "removing trailing whitespace");
 1610            let diff = buffer
 1611                .handle
 1612                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1613                .await;
 1614            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1615                buffer.apply_diff(diff, cx);
 1616            })?;
 1617        }
 1618
 1619        if settings.ensure_final_newline_on_save {
 1620            zlog::trace!(logger => "ensuring final newline");
 1621            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1622                buffer.ensure_final_newline(cx);
 1623            })?;
 1624        }
 1625
 1626        // Formatter for `code_actions_on_format` that runs before
 1627        // the rest of the formatters
 1628        let mut code_actions_on_format_formatters = None;
 1629        let should_run_code_actions_on_format = !matches!(
 1630            (trigger, &settings.format_on_save),
 1631            (FormatTrigger::Save, &FormatOnSave::Off)
 1632        );
 1633        if should_run_code_actions_on_format {
 1634            let have_code_actions_to_run_on_format = settings
 1635                .code_actions_on_format
 1636                .values()
 1637                .any(|enabled| *enabled);
 1638            if have_code_actions_to_run_on_format {
 1639                zlog::trace!(logger => "going to run code actions on format");
 1640                code_actions_on_format_formatters = Some(
 1641                    settings
 1642                        .code_actions_on_format
 1643                        .iter()
 1644                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1645                        .cloned()
 1646                        .map(Formatter::CodeAction)
 1647                        .collect::<Vec<_>>(),
 1648                );
 1649            }
 1650        }
 1651
 1652        let formatters = match (trigger, &settings.format_on_save) {
 1653            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1654            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1655                settings.formatter.as_ref()
 1656            }
 1657        };
 1658
 1659        let formatters = code_actions_on_format_formatters
 1660            .iter()
 1661            .flatten()
 1662            .chain(formatters);
 1663
 1664        for formatter in formatters {
 1665            let formatter = if formatter == &Formatter::Auto {
 1666                if settings.prettier.allowed {
 1667                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1668                    &Formatter::Prettier
 1669                } else {
 1670                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1671                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1672                }
 1673            } else {
 1674                formatter
 1675            };
 1676            if let Err(err) = Self::apply_formatter(
 1677                formatter,
 1678                &lsp_store,
 1679                buffer,
 1680                formatting_transaction_id,
 1681                &adapters_and_servers,
 1682                &settings,
 1683                request_timeout,
 1684                logger,
 1685                cx,
 1686            )
 1687            .await
 1688            {
 1689                zlog::error!(logger => "Formatter failed, skipping: {err:#}");
 1690            }
 1691        }
 1692
 1693        Ok(())
 1694    }
 1695
 1696    async fn apply_formatter(
 1697        formatter: &Formatter,
 1698        lsp_store: &WeakEntity<LspStore>,
 1699        buffer: &FormattableBuffer,
 1700        formatting_transaction_id: clock::Lamport,
 1701        adapters_and_servers: &[(Arc<CachedLspAdapter>, Arc<LanguageServer>)],
 1702        settings: &LanguageSettings,
 1703        request_timeout: Duration,
 1704        logger: zlog::Logger,
 1705        cx: &mut AsyncApp,
 1706    ) -> anyhow::Result<()> {
 1707        match formatter {
 1708            Formatter::None => {
 1709                zlog::trace!(logger => "skipping formatter 'none'");
 1710                return Ok(());
 1711            }
 1712            Formatter::Auto => {
 1713                debug_panic!("Auto resolved above");
 1714                return Ok(());
 1715            }
 1716            Formatter::Prettier => {
 1717                let logger = zlog::scoped!(logger => "prettier");
 1718                zlog::trace!(logger => "formatting");
 1719                let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1720
 1721                // When selection ranges are provided (via FormatSelections), we pass the
 1722                // encompassing UTF-16 range to Prettier so it can scope its formatting.
 1723                // After diffing, we filter the resulting edits to only keep those that
 1724                // overlap with the original byte-level selection ranges.
 1725                let (range_utf16, byte_ranges) = match buffer.ranges.as_ref() {
 1726                    Some(ranges) if !ranges.is_empty() => {
 1727                        let (utf16_range, byte_ranges) =
 1728                            buffer.handle.read_with(cx, |buffer, _cx| {
 1729                                let snapshot = buffer.snapshot();
 1730                                let mut min_start_utf16 = OffsetUtf16(usize::MAX);
 1731                                let mut max_end_utf16 = OffsetUtf16(0);
 1732                                let mut byte_ranges = Vec::with_capacity(ranges.len());
 1733                                for range in ranges {
 1734                                    let start_utf16 = range.start.to_offset_utf16(&snapshot);
 1735                                    let end_utf16 = range.end.to_offset_utf16(&snapshot);
 1736                                    min_start_utf16.0 = min_start_utf16.0.min(start_utf16.0);
 1737                                    max_end_utf16.0 = max_end_utf16.0.max(end_utf16.0);
 1738
 1739                                    let start_byte = range.start.to_offset(&snapshot);
 1740                                    let end_byte = range.end.to_offset(&snapshot);
 1741                                    byte_ranges.push(start_byte..end_byte);
 1742                                }
 1743                                (min_start_utf16..max_end_utf16, byte_ranges)
 1744                            });
 1745                        (Some(utf16_range), Some(byte_ranges))
 1746                    }
 1747                    _ => (None, None),
 1748                };
 1749
 1750                let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1751                    lsp_store.prettier_store().unwrap().downgrade()
 1752                })?;
 1753                let diff = prettier_store::format_with_prettier(
 1754                    &prettier,
 1755                    &buffer.handle,
 1756                    range_utf16,
 1757                    cx,
 1758                )
 1759                .await
 1760                .transpose()?;
 1761                let Some(mut diff) = diff else {
 1762                    zlog::trace!(logger => "No changes");
 1763                    return Ok(());
 1764                };
 1765
 1766                if let Some(byte_ranges) = byte_ranges {
 1767                    diff.edits.retain(|(edit_range, _)| {
 1768                        byte_ranges.iter().any(|selection_range| {
 1769                            edit_range.start < selection_range.end
 1770                                && edit_range.end > selection_range.start
 1771                        })
 1772                    });
 1773                    if diff.edits.is_empty() {
 1774                        zlog::trace!(logger => "No changes within selection");
 1775                        return Ok(());
 1776                    }
 1777                }
 1778
 1779                extend_formatting_transaction(
 1780                    buffer,
 1781                    formatting_transaction_id,
 1782                    cx,
 1783                    |buffer, cx| {
 1784                        buffer.apply_diff(diff, cx);
 1785                    },
 1786                )?;
 1787            }
 1788            Formatter::External { command, arguments } => {
 1789                let logger = zlog::scoped!(logger => "command");
 1790
 1791                if buffer.ranges.is_some() {
 1792                    zlog::debug!(logger => "External formatter does not support range formatting; skipping");
 1793                    return Ok(());
 1794                }
 1795
 1796                zlog::trace!(logger => "formatting");
 1797                let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1798
 1799                let diff =
 1800                    Self::format_via_external_command(buffer, &command, arguments.as_deref(), cx)
 1801                        .await
 1802                        .with_context(|| {
 1803                            format!("Failed to format buffer via external command: {}", command)
 1804                        })?;
 1805                let Some(diff) = diff else {
 1806                    zlog::trace!(logger => "No changes");
 1807                    return Ok(());
 1808                };
 1809
 1810                extend_formatting_transaction(
 1811                    buffer,
 1812                    formatting_transaction_id,
 1813                    cx,
 1814                    |buffer, cx| {
 1815                        buffer.apply_diff(diff, cx);
 1816                    },
 1817                )?;
 1818            }
 1819            Formatter::LanguageServer(specifier) => {
 1820                let logger = zlog::scoped!(logger => "language-server");
 1821                zlog::trace!(logger => "formatting");
 1822                let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1823
 1824                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1825                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1826                    return Ok(());
 1827                };
 1828
 1829                let language_server = match specifier {
 1830                    settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1831                        adapters_and_servers.iter().find_map(|(adapter, server)| {
 1832                            if adapter.name.0.as_ref() == name {
 1833                                Some(server.clone())
 1834                            } else {
 1835                                None
 1836                            }
 1837                        })
 1838                    }
 1839                    settings::LanguageServerFormatterSpecifier::Current => adapters_and_servers
 1840                        .iter()
 1841                        .find(|(_, server)| Self::server_supports_formatting(server))
 1842                        .map(|(_, server)| server.clone()),
 1843                };
 1844
 1845                let Some(language_server) = language_server else {
 1846                    log::debug!(
 1847                        "No language server found to format buffer '{:?}'. Skipping",
 1848                        buffer_path_abs.as_path().to_string_lossy()
 1849                    );
 1850                    return Ok(());
 1851                };
 1852
 1853                zlog::trace!(
 1854                    logger =>
 1855                    "Formatting buffer '{:?}' using language server '{:?}'",
 1856                    buffer_path_abs.as_path().to_string_lossy(),
 1857                    language_server.name()
 1858                );
 1859
 1860                let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1861                    zlog::trace!(logger => "formatting ranges");
 1862                    Self::format_ranges_via_lsp(
 1863                        &lsp_store,
 1864                        &buffer.handle,
 1865                        ranges,
 1866                        buffer_path_abs,
 1867                        &language_server,
 1868                        &settings,
 1869                        cx,
 1870                    )
 1871                    .await
 1872                    .context("Failed to format ranges via language server")?
 1873                } else {
 1874                    zlog::trace!(logger => "formatting full");
 1875                    Self::format_via_lsp(
 1876                        &lsp_store,
 1877                        &buffer.handle,
 1878                        buffer_path_abs,
 1879                        &language_server,
 1880                        &settings,
 1881                        cx,
 1882                    )
 1883                    .await
 1884                    .context("failed to format via language server")?
 1885                };
 1886
 1887                if edits.is_empty() {
 1888                    zlog::trace!(logger => "No changes");
 1889                    return Ok(());
 1890                }
 1891                extend_formatting_transaction(
 1892                    buffer,
 1893                    formatting_transaction_id,
 1894                    cx,
 1895                    |buffer, cx| {
 1896                        buffer.edit(edits, None, cx);
 1897                    },
 1898                )?;
 1899            }
 1900            Formatter::CodeAction(code_action_name) => {
 1901                let logger = zlog::scoped!(logger => "code-actions");
 1902                zlog::trace!(logger => "formatting");
 1903                let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1904
 1905                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1906                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1907                    return Ok(());
 1908                };
 1909
 1910                let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1911                zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1912
 1913                let mut actions_and_servers = Vec::new();
 1914
 1915                for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1916                    let actions_result = Self::get_server_code_actions_from_action_kinds(
 1917                        &lsp_store,
 1918                        language_server.server_id(),
 1919                        vec![code_action_kind.clone()],
 1920                        &buffer.handle,
 1921                        cx,
 1922                    )
 1923                    .await
 1924                    .with_context(|| {
 1925                        format!(
 1926                            "Failed to resolve code action {:?} with language server {}",
 1927                            code_action_kind,
 1928                            language_server.name()
 1929                        )
 1930                    });
 1931                    let Ok(actions) = actions_result else {
 1932                        // note: it may be better to set result to the error and break formatters here
 1933                        // but for now we try to execute the actions that we can resolve and skip the rest
 1934                        zlog::error!(
 1935                            logger =>
 1936                            "Failed to resolve code action {:?} with language server {}",
 1937                            code_action_kind,
 1938                            language_server.name()
 1939                        );
 1940                        continue;
 1941                    };
 1942                    for action in actions {
 1943                        actions_and_servers.push((action, index));
 1944                    }
 1945                }
 1946
 1947                if actions_and_servers.is_empty() {
 1948                    zlog::warn!(logger => "No code actions were resolved, continuing");
 1949                    return Ok(());
 1950                }
 1951
 1952                'actions: for (mut action, server_index) in actions_and_servers {
 1953                    let server = &adapters_and_servers[server_index].1;
 1954
 1955                    let describe_code_action = |action: &CodeAction| {
 1956                        format!(
 1957                            "code action '{}' with title \"{}\" on server {}",
 1958                            action
 1959                                .lsp_action
 1960                                .action_kind()
 1961                                .unwrap_or("unknown".into())
 1962                                .as_str(),
 1963                            action.lsp_action.title(),
 1964                            server.name(),
 1965                        )
 1966                    };
 1967
 1968                    zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1969
 1970                    if let Err(err) =
 1971                        Self::try_resolve_code_action(server, &mut action, request_timeout).await
 1972                    {
 1973                        zlog::error!(
 1974                            logger =>
 1975                            "Failed to resolve {}. Error: {}",
 1976                            describe_code_action(&action),
 1977                            err
 1978                        );
 1979                        continue;
 1980                    }
 1981
 1982                    if let Some(edit) = action.lsp_action.edit().cloned() {
 1983                        // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1984                        // but filters out and logs warnings for code actions that require unreasonably
 1985                        // difficult handling on our part, such as:
 1986                        // - applying edits that call commands
 1987                        //   which can result in arbitrary workspace edits being sent from the server that
 1988                        //   have no way of being tied back to the command that initiated them (i.e. we
 1989                        //   can't know which edits are part of the format request, or if the server is done sending
 1990                        //   actions in response to the command)
 1991                        // - actions that create/delete/modify/rename files other than the one we are formatting
 1992                        //   as we then would need to handle such changes correctly in the local history as well
 1993                        //   as the remote history through the ProjectTransaction
 1994                        // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1995                        // Supporting these actions is not impossible, but not supported as of yet.
 1996                        if edit.changes.is_none() && edit.document_changes.is_none() {
 1997                            zlog::trace!(
 1998                                logger =>
 1999                                "No changes for code action. Skipping {}",
 2000                                describe_code_action(&action),
 2001                            );
 2002                            continue;
 2003                        }
 2004
 2005                        let mut operations = Vec::new();
 2006                        if let Some(document_changes) = edit.document_changes {
 2007                            match document_changes {
 2008                                lsp::DocumentChanges::Edits(edits) => operations.extend(
 2009                                    edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 2010                                ),
 2011                                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2012                            }
 2013                        } else if let Some(changes) = edit.changes {
 2014                            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2015                                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2016                                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2017                                        uri,
 2018                                        version: None,
 2019                                    },
 2020                                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2021                                })
 2022                            }));
 2023                        }
 2024
 2025                        let mut edits = Vec::with_capacity(operations.len());
 2026
 2027                        if operations.is_empty() {
 2028                            zlog::trace!(
 2029                                logger =>
 2030                                "No changes for code action. Skipping {}",
 2031                                describe_code_action(&action),
 2032                            );
 2033                            continue;
 2034                        }
 2035                        for operation in operations {
 2036                            let op = match operation {
 2037                                lsp::DocumentChangeOperation::Edit(op) => op,
 2038                                lsp::DocumentChangeOperation::Op(_) => {
 2039                                    zlog::warn!(
 2040                                        logger =>
 2041                                        "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 2042                                        describe_code_action(&action),
 2043                                    );
 2044                                    continue 'actions;
 2045                                }
 2046                            };
 2047                            let Ok(file_path) = op.text_document.uri.to_file_path() else {
 2048                                zlog::warn!(
 2049                                    logger =>
 2050                                    "Failed to convert URI '{:?}' to file path. Skipping {}",
 2051                                    &op.text_document.uri,
 2052                                    describe_code_action(&action),
 2053                                );
 2054                                continue 'actions;
 2055                            };
 2056                            if &file_path != buffer_path_abs {
 2057                                zlog::warn!(
 2058                                    logger =>
 2059                                    "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 2060                                    file_path,
 2061                                    buffer_path_abs,
 2062                                    describe_code_action(&action),
 2063                                );
 2064                                continue 'actions;
 2065                            }
 2066
 2067                            let mut lsp_edits = Vec::new();
 2068                            for edit in op.edits {
 2069                                match edit {
 2070                                    Edit::Plain(edit) => {
 2071                                        if !lsp_edits.contains(&edit) {
 2072                                            lsp_edits.push(edit);
 2073                                        }
 2074                                    }
 2075                                    Edit::Annotated(edit) => {
 2076                                        if !lsp_edits.contains(&edit.text_edit) {
 2077                                            lsp_edits.push(edit.text_edit);
 2078                                        }
 2079                                    }
 2080                                    Edit::Snippet(_) => {
 2081                                        zlog::warn!(
 2082                                            logger =>
 2083                                            "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 2084                                            describe_code_action(&action),
 2085                                        );
 2086                                        continue 'actions;
 2087                                    }
 2088                                }
 2089                            }
 2090                            let edits_result = lsp_store
 2091                                .update(cx, |lsp_store, cx| {
 2092                                    lsp_store.as_local_mut().unwrap().edits_from_lsp(
 2093                                        &buffer.handle,
 2094                                        lsp_edits,
 2095                                        server.server_id(),
 2096                                        op.text_document.version,
 2097                                        cx,
 2098                                    )
 2099                                })?
 2100                                .await;
 2101                            let Ok(resolved_edits) = edits_result else {
 2102                                zlog::warn!(
 2103                                    logger =>
 2104                                    "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 2105                                    buffer_path_abs.as_path(),
 2106                                    describe_code_action(&action),
 2107                                );
 2108                                continue 'actions;
 2109                            };
 2110                            edits.extend(resolved_edits);
 2111                        }
 2112
 2113                        if edits.is_empty() {
 2114                            zlog::warn!(logger => "No edits resolved from LSP");
 2115                            continue;
 2116                        }
 2117
 2118                        extend_formatting_transaction(
 2119                            buffer,
 2120                            formatting_transaction_id,
 2121                            cx,
 2122                            |buffer, cx| {
 2123                                zlog::info!(
 2124                                    "Applying edits {edits:?}. Content: {:?}",
 2125                                    buffer.text()
 2126                                );
 2127                                buffer.edit(edits, None, cx);
 2128                                zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 2129                            },
 2130                        )?;
 2131                    }
 2132
 2133                    let Some(command) = action.lsp_action.command() else {
 2134                        continue;
 2135                    };
 2136
 2137                    zlog::warn!(
 2138                        logger =>
 2139                        "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 2140                        &command.command,
 2141                    );
 2142
 2143                    let server_capabilities = server.capabilities();
 2144                    let available_commands = server_capabilities
 2145                        .execute_command_provider
 2146                        .as_ref()
 2147                        .map(|options| options.commands.as_slice())
 2148                        .unwrap_or_default();
 2149                    if !available_commands.contains(&command.command) {
 2150                        zlog::warn!(
 2151                            logger =>
 2152                            "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2153                            command.command,
 2154                            server.name(),
 2155                        );
 2156                        continue;
 2157                    }
 2158
 2159                    extend_formatting_transaction(
 2160                        buffer,
 2161                        formatting_transaction_id,
 2162                        cx,
 2163                        |_, _| {},
 2164                    )?;
 2165                    zlog::info!(logger => "Executing command {}", &command.command);
 2166
 2167                    lsp_store.update(cx, |this, _| {
 2168                        this.as_local_mut()
 2169                            .unwrap()
 2170                            .last_workspace_edits_by_language_server
 2171                            .remove(&server.server_id());
 2172                    })?;
 2173
 2174                    let execute_command_result = server
 2175                        .request::<lsp::request::ExecuteCommand>(
 2176                            lsp::ExecuteCommandParams {
 2177                                command: command.command.clone(),
 2178                                arguments: command.arguments.clone().unwrap_or_default(),
 2179                                ..Default::default()
 2180                            },
 2181                            request_timeout,
 2182                        )
 2183                        .await
 2184                        .into_response();
 2185
 2186                    if execute_command_result.is_err() {
 2187                        zlog::error!(
 2188                            logger =>
 2189                            "Failed to execute command '{}' as part of {}",
 2190                            &command.command,
 2191                            describe_code_action(&action),
 2192                        );
 2193                        continue 'actions;
 2194                    }
 2195
 2196                    let mut project_transaction_command = lsp_store.update(cx, |this, _| {
 2197                        this.as_local_mut()
 2198                            .unwrap()
 2199                            .last_workspace_edits_by_language_server
 2200                            .remove(&server.server_id())
 2201                            .unwrap_or_default()
 2202                    })?;
 2203
 2204                    if let Some(transaction) = project_transaction_command.0.remove(&buffer.handle)
 2205                    {
 2206                        zlog::trace!(
 2207                            logger =>
 2208                            "Successfully captured {} edits that resulted from command {}",
 2209                            transaction.edit_ids.len(),
 2210                            &command.command,
 2211                        );
 2212                        let transaction_id_project_transaction = transaction.id;
 2213                        buffer.handle.update(cx, |buffer, _| {
 2214                            // it may have been removed from history if push_to_history was
 2215                            // false in deserialize_workspace_edit. If so push it so we
 2216                            // can merge it with the format transaction
 2217                            // and pop the combined transaction off the history stack
 2218                            // later if push_to_history is false
 2219                            if buffer.get_transaction(transaction.id).is_none() {
 2220                                buffer.push_transaction(transaction, Instant::now());
 2221                            }
 2222                            buffer.merge_transactions(
 2223                                transaction_id_project_transaction,
 2224                                formatting_transaction_id,
 2225                            );
 2226                        });
 2227                    }
 2228
 2229                    if project_transaction_command.0.is_empty() {
 2230                        continue;
 2231                    }
 2232
 2233                    let mut extra_buffers = String::new();
 2234                    for buffer in project_transaction_command.0.keys() {
 2235                        buffer.read_with(cx, |b, cx| {
 2236                            let Some(path) = b.project_path(cx) else {
 2237                                return;
 2238                            };
 2239
 2240                            if !extra_buffers.is_empty() {
 2241                                extra_buffers.push_str(", ");
 2242                            }
 2243                            extra_buffers.push_str(path.path.as_unix_str());
 2244                        });
 2245                    }
 2246                    zlog::warn!(
 2247                        logger =>
 2248                        "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2249                        &command.command,
 2250                        extra_buffers,
 2251                    );
 2252                    // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2253                    // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2254                    // add it so it's included, and merge it into the format transaction when its created later
 2255                }
 2256            }
 2257        }
 2258
 2259        Ok(())
 2260    }
 2261
 2262    pub async fn format_ranges_via_lsp(
 2263        this: &WeakEntity<LspStore>,
 2264        buffer_handle: &Entity<Buffer>,
 2265        ranges: &[Range<Anchor>],
 2266        abs_path: &Path,
 2267        language_server: &Arc<LanguageServer>,
 2268        settings: &LanguageSettings,
 2269        cx: &mut AsyncApp,
 2270    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2271        let capabilities = &language_server.capabilities();
 2272        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2273        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2274            anyhow::bail!(
 2275                "{} language server does not support range formatting",
 2276                language_server.name()
 2277            );
 2278        }
 2279
 2280        let uri = file_path_to_lsp_url(abs_path)?;
 2281        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2282
 2283        let request_timeout = cx.update(|app| {
 2284            ProjectSettings::get_global(app)
 2285                .global_lsp_settings
 2286                .get_request_timeout()
 2287        });
 2288        let lsp_edits = {
 2289            let mut lsp_ranges = Vec::new();
 2290            this.update(cx, |_this, cx| {
 2291                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2292                // not have been sent to the language server. This seems like a fairly systemic
 2293                // issue, though, the resolution probably is not specific to formatting.
 2294                //
 2295                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2296                // LSP.
 2297                let snapshot = buffer_handle.read(cx).snapshot();
 2298                for range in ranges {
 2299                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2300                }
 2301                anyhow::Ok(())
 2302            })??;
 2303
 2304            let mut edits = None;
 2305            for range in lsp_ranges {
 2306                if let Some(mut edit) = language_server
 2307                    .request::<lsp::request::RangeFormatting>(
 2308                        lsp::DocumentRangeFormattingParams {
 2309                            text_document: text_document.clone(),
 2310                            range,
 2311                            options: lsp_command::lsp_formatting_options(settings),
 2312                            work_done_progress_params: Default::default(),
 2313                        },
 2314                        request_timeout,
 2315                    )
 2316                    .await
 2317                    .into_response()?
 2318                {
 2319                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2320                }
 2321            }
 2322            edits
 2323        };
 2324
 2325        if let Some(lsp_edits) = lsp_edits {
 2326            this.update(cx, |this, cx| {
 2327                this.as_local_mut().unwrap().edits_from_lsp(
 2328                    buffer_handle,
 2329                    lsp_edits,
 2330                    language_server.server_id(),
 2331                    None,
 2332                    cx,
 2333                )
 2334            })?
 2335            .await
 2336        } else {
 2337            Ok(Vec::with_capacity(0))
 2338        }
 2339    }
 2340
 2341    fn server_supports_formatting(server: &Arc<LanguageServer>) -> bool {
 2342        let capabilities = server.capabilities();
 2343        let formatting = capabilities.document_formatting_provider.as_ref();
 2344        let range_formatting = capabilities.document_range_formatting_provider.as_ref();
 2345        matches!(formatting, Some(p) if *p != OneOf::Left(false))
 2346            || matches!(range_formatting, Some(p) if *p != OneOf::Left(false))
 2347    }
 2348
 2349    async fn format_via_lsp(
 2350        this: &WeakEntity<LspStore>,
 2351        buffer: &Entity<Buffer>,
 2352        abs_path: &Path,
 2353        language_server: &Arc<LanguageServer>,
 2354        settings: &LanguageSettings,
 2355        cx: &mut AsyncApp,
 2356    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2357        let logger = zlog::scoped!("lsp_format");
 2358        zlog::debug!(logger => "Formatting via LSP");
 2359
 2360        let uri = file_path_to_lsp_url(abs_path)?;
 2361        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2362        let capabilities = &language_server.capabilities();
 2363
 2364        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2365        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2366
 2367        let request_timeout = cx.update(|app| {
 2368            ProjectSettings::get_global(app)
 2369                .global_lsp_settings
 2370                .get_request_timeout()
 2371        });
 2372
 2373        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2374            let _timer = zlog::time!(logger => "format-full");
 2375            language_server
 2376                .request::<lsp::request::Formatting>(
 2377                    lsp::DocumentFormattingParams {
 2378                        text_document,
 2379                        options: lsp_command::lsp_formatting_options(settings),
 2380                        work_done_progress_params: Default::default(),
 2381                    },
 2382                    request_timeout,
 2383                )
 2384                .await
 2385                .into_response()?
 2386        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2387            let _timer = zlog::time!(logger => "format-range");
 2388            let buffer_start = lsp::Position::new(0, 0);
 2389            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2390            language_server
 2391                .request::<lsp::request::RangeFormatting>(
 2392                    lsp::DocumentRangeFormattingParams {
 2393                        text_document: text_document.clone(),
 2394                        range: lsp::Range::new(buffer_start, buffer_end),
 2395                        options: lsp_command::lsp_formatting_options(settings),
 2396                        work_done_progress_params: Default::default(),
 2397                    },
 2398                    request_timeout,
 2399                )
 2400                .await
 2401                .into_response()?
 2402        } else {
 2403            None
 2404        };
 2405
 2406        if let Some(lsp_edits) = lsp_edits {
 2407            this.update(cx, |this, cx| {
 2408                this.as_local_mut().unwrap().edits_from_lsp(
 2409                    buffer,
 2410                    lsp_edits,
 2411                    language_server.server_id(),
 2412                    None,
 2413                    cx,
 2414                )
 2415            })?
 2416            .await
 2417        } else {
 2418            Ok(Vec::with_capacity(0))
 2419        }
 2420    }
 2421
 2422    async fn format_via_external_command(
 2423        buffer: &FormattableBuffer,
 2424        command: &str,
 2425        arguments: Option<&[String]>,
 2426        cx: &mut AsyncApp,
 2427    ) -> Result<Option<Diff>> {
 2428        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2429            let file = File::from_dyn(buffer.file())?;
 2430            let worktree = file.worktree.read(cx);
 2431            let mut worktree_path = worktree.abs_path().to_path_buf();
 2432            if worktree.root_entry()?.is_file() {
 2433                worktree_path.pop();
 2434            }
 2435            Some(worktree_path)
 2436        });
 2437
 2438        use util::command::Stdio;
 2439        let mut child = util::command::new_command(command);
 2440
 2441        if let Some(buffer_env) = buffer.env.as_ref() {
 2442            child.envs(buffer_env);
 2443        }
 2444
 2445        if let Some(working_dir_path) = working_dir_path {
 2446            child.current_dir(working_dir_path);
 2447        }
 2448
 2449        if let Some(arguments) = arguments {
 2450            child.args(arguments.iter().map(|arg| {
 2451                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2452                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2453                } else {
 2454                    arg.replace("{buffer_path}", "Untitled")
 2455                }
 2456            }));
 2457        }
 2458
 2459        let mut child = child
 2460            .stdin(Stdio::piped())
 2461            .stdout(Stdio::piped())
 2462            .stderr(Stdio::piped())
 2463            .spawn()?;
 2464
 2465        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2466        let text = buffer
 2467            .handle
 2468            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2469        for chunk in text.chunks() {
 2470            stdin.write_all(chunk.as_bytes()).await?;
 2471        }
 2472        stdin.flush().await?;
 2473
 2474        let output = child.output().await?;
 2475        anyhow::ensure!(
 2476            output.status.success(),
 2477            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2478            output.status.code(),
 2479            String::from_utf8_lossy(&output.stdout),
 2480            String::from_utf8_lossy(&output.stderr),
 2481        );
 2482
 2483        let stdout = String::from_utf8(output.stdout)?;
 2484        Ok(Some(
 2485            buffer
 2486                .handle
 2487                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2488                .await,
 2489        ))
 2490    }
 2491
 2492    async fn try_resolve_code_action(
 2493        lang_server: &LanguageServer,
 2494        action: &mut CodeAction,
 2495        request_timeout: Duration,
 2496    ) -> anyhow::Result<()> {
 2497        match &mut action.lsp_action {
 2498            LspAction::Action(lsp_action) => {
 2499                if !action.resolved
 2500                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2501                    && lsp_action.data.is_some()
 2502                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2503                {
 2504                    **lsp_action = lang_server
 2505                        .request::<lsp::request::CodeActionResolveRequest>(
 2506                            *lsp_action.clone(),
 2507                            request_timeout,
 2508                        )
 2509                        .await
 2510                        .into_response()?;
 2511                }
 2512            }
 2513            LspAction::CodeLens(lens) => {
 2514                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2515                    *lens = lang_server
 2516                        .request::<lsp::request::CodeLensResolve>(lens.clone(), request_timeout)
 2517                        .await
 2518                        .into_response()?;
 2519                }
 2520            }
 2521            LspAction::Command(_) => {}
 2522        }
 2523
 2524        action.resolved = true;
 2525        anyhow::Ok(())
 2526    }
 2527
 2528    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2529        let buffer = buffer_handle.read(cx);
 2530
 2531        let file = buffer.file().cloned();
 2532
 2533        let Some(file) = File::from_dyn(file.as_ref()) else {
 2534            return;
 2535        };
 2536        if !file.is_local() {
 2537            return;
 2538        }
 2539        let path = ProjectPath::from_file(file, cx);
 2540        let worktree_id = file.worktree_id(cx);
 2541        let language = buffer.language().cloned();
 2542
 2543        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2544            for (server_id, diagnostics) in
 2545                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2546            {
 2547                self.update_buffer_diagnostics(
 2548                    buffer_handle,
 2549                    server_id,
 2550                    None,
 2551                    None,
 2552                    None,
 2553                    Vec::new(),
 2554                    diagnostics,
 2555                    cx,
 2556                )
 2557                .log_err();
 2558            }
 2559        }
 2560        let Some(language) = language else {
 2561            return;
 2562        };
 2563        let Some(snapshot) = self
 2564            .worktree_store
 2565            .read(cx)
 2566            .worktree_for_id(worktree_id, cx)
 2567            .map(|worktree| worktree.read(cx).snapshot())
 2568        else {
 2569            return;
 2570        };
 2571        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2572
 2573        for server_id in
 2574            self.lsp_tree
 2575                .get(path, language.name(), language.manifest(), &delegate, cx)
 2576        {
 2577            let server = self
 2578                .language_servers
 2579                .get(&server_id)
 2580                .and_then(|server_state| {
 2581                    if let LanguageServerState::Running { server, .. } = server_state {
 2582                        Some(server.clone())
 2583                    } else {
 2584                        None
 2585                    }
 2586                });
 2587            let server = match server {
 2588                Some(server) => server,
 2589                None => continue,
 2590            };
 2591
 2592            buffer_handle.update(cx, |buffer, cx| {
 2593                buffer.set_completion_triggers(
 2594                    server.server_id(),
 2595                    server
 2596                        .capabilities()
 2597                        .completion_provider
 2598                        .as_ref()
 2599                        .and_then(|provider| {
 2600                            provider
 2601                                .trigger_characters
 2602                                .as_ref()
 2603                                .map(|characters| characters.iter().cloned().collect())
 2604                        })
 2605                        .unwrap_or_default(),
 2606                    cx,
 2607                );
 2608            });
 2609        }
 2610    }
 2611
 2612    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2613        buffer.update(cx, |buffer, cx| {
 2614            let Some(language) = buffer.language() else {
 2615                return;
 2616            };
 2617            let path = ProjectPath {
 2618                worktree_id: old_file.worktree_id(cx),
 2619                path: old_file.path.clone(),
 2620            };
 2621            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2622                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2623                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2624            }
 2625        });
 2626    }
 2627
 2628    fn update_buffer_diagnostics(
 2629        &mut self,
 2630        buffer: &Entity<Buffer>,
 2631        server_id: LanguageServerId,
 2632        registration_id: Option<Option<SharedString>>,
 2633        result_id: Option<SharedString>,
 2634        version: Option<i32>,
 2635        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2636        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2637        cx: &mut Context<LspStore>,
 2638    ) -> Result<()> {
 2639        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2640            Ordering::Equal
 2641                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2642                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2643                .then_with(|| a.severity.cmp(&b.severity))
 2644                .then_with(|| a.message.cmp(&b.message))
 2645        }
 2646
 2647        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2648        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2649        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2650
 2651        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2652            Ordering::Equal
 2653                .then_with(|| a.range.start.cmp(&b.range.start))
 2654                .then_with(|| b.range.end.cmp(&a.range.end))
 2655                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2656        });
 2657
 2658        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2659
 2660        let edits_since_save = std::cell::LazyCell::new(|| {
 2661            let saved_version = buffer.read(cx).saved_version();
 2662            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2663        });
 2664
 2665        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2666
 2667        for (new_diagnostic, entry) in diagnostics {
 2668            let start;
 2669            let end;
 2670            if new_diagnostic && entry.diagnostic.is_disk_based {
 2671                // Some diagnostics are based on files on disk instead of buffers'
 2672                // current contents. Adjust these diagnostics' ranges to reflect
 2673                // any unsaved edits.
 2674                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2675                // and were properly adjusted on reuse.
 2676                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2677                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2678            } else {
 2679                start = entry.range.start;
 2680                end = entry.range.end;
 2681            }
 2682
 2683            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2684                ..snapshot.clip_point_utf16(end, Bias::Right);
 2685
 2686            // Expand empty ranges by one codepoint
 2687            if range.start == range.end {
 2688                // This will be go to the next boundary when being clipped
 2689                range.end.column += 1;
 2690                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2691                if range.start == range.end && range.end.column > 0 {
 2692                    range.start.column -= 1;
 2693                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2694                }
 2695            }
 2696
 2697            sanitized_diagnostics.push(DiagnosticEntry {
 2698                range,
 2699                diagnostic: entry.diagnostic,
 2700            });
 2701        }
 2702        drop(edits_since_save);
 2703
 2704        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2705        buffer.update(cx, |buffer, cx| {
 2706            if let Some(registration_id) = registration_id {
 2707                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2708                    self.buffer_pull_diagnostics_result_ids
 2709                        .entry(server_id)
 2710                        .or_default()
 2711                        .entry(registration_id)
 2712                        .or_default()
 2713                        .insert(abs_path, result_id);
 2714                }
 2715            }
 2716
 2717            buffer.update_diagnostics(server_id, set, cx)
 2718        });
 2719
 2720        Ok(())
 2721    }
 2722
 2723    fn register_language_server_for_invisible_worktree(
 2724        &mut self,
 2725        worktree: &Entity<Worktree>,
 2726        language_server_id: LanguageServerId,
 2727        cx: &mut App,
 2728    ) {
 2729        let worktree = worktree.read(cx);
 2730        let worktree_id = worktree.id();
 2731        debug_assert!(!worktree.is_visible());
 2732        let Some(mut origin_seed) = self
 2733            .language_server_ids
 2734            .iter()
 2735            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2736        else {
 2737            return;
 2738        };
 2739        origin_seed.worktree_id = worktree_id;
 2740        self.language_server_ids
 2741            .entry(origin_seed)
 2742            .or_insert_with(|| UnifiedLanguageServer {
 2743                id: language_server_id,
 2744                project_roots: Default::default(),
 2745            });
 2746    }
 2747
 2748    fn register_buffer_with_language_servers(
 2749        &mut self,
 2750        buffer_handle: &Entity<Buffer>,
 2751        only_register_servers: HashSet<LanguageServerSelector>,
 2752        cx: &mut Context<LspStore>,
 2753    ) {
 2754        let buffer = buffer_handle.read(cx);
 2755        let buffer_id = buffer.remote_id();
 2756
 2757        let Some(file) = File::from_dyn(buffer.file()) else {
 2758            return;
 2759        };
 2760        if !file.is_local() {
 2761            return;
 2762        }
 2763
 2764        let abs_path = file.abs_path(cx);
 2765        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2766            return;
 2767        };
 2768        let initial_snapshot = buffer.text_snapshot();
 2769        let worktree_id = file.worktree_id(cx);
 2770
 2771        let Some(language) = buffer.language().cloned() else {
 2772            return;
 2773        };
 2774        let path: Arc<RelPath> = file
 2775            .path()
 2776            .parent()
 2777            .map(Arc::from)
 2778            .unwrap_or_else(|| file.path().clone());
 2779        let Some(worktree) = self
 2780            .worktree_store
 2781            .read(cx)
 2782            .worktree_for_id(worktree_id, cx)
 2783        else {
 2784            return;
 2785        };
 2786        let language_name = language.name();
 2787        let (reused, delegate, servers) = self
 2788            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2789            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2790            .unwrap_or_else(|| {
 2791                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2792                let delegate: Arc<dyn ManifestDelegate> =
 2793                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2794
 2795                let servers = self
 2796                    .lsp_tree
 2797                    .walk(
 2798                        ProjectPath { worktree_id, path },
 2799                        language.name(),
 2800                        language.manifest(),
 2801                        &delegate,
 2802                        cx,
 2803                    )
 2804                    .collect::<Vec<_>>();
 2805                (false, lsp_delegate, servers)
 2806            });
 2807        let servers_and_adapters = servers
 2808            .into_iter()
 2809            .filter_map(|server_node| {
 2810                if reused && server_node.server_id().is_none() {
 2811                    return None;
 2812                }
 2813                if !only_register_servers.is_empty() {
 2814                    if let Some(server_id) = server_node.server_id()
 2815                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2816                    {
 2817                        return None;
 2818                    }
 2819                    if let Some(name) = server_node.name()
 2820                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2821                    {
 2822                        return None;
 2823                    }
 2824                }
 2825
 2826                let server_id = server_node.server_id_or_init(|disposition| {
 2827                    let path = &disposition.path;
 2828
 2829                    {
 2830                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2831
 2832                        let server_id = self.get_or_insert_language_server(
 2833                            &worktree,
 2834                            delegate.clone(),
 2835                            disposition,
 2836                            &language_name,
 2837                            cx,
 2838                        );
 2839
 2840                        if let Some(state) = self.language_servers.get(&server_id)
 2841                            && let Ok(uri) = uri
 2842                        {
 2843                            state.add_workspace_folder(uri);
 2844                        };
 2845                        server_id
 2846                    }
 2847                })?;
 2848                let server_state = self.language_servers.get(&server_id)?;
 2849                if let LanguageServerState::Running {
 2850                    server, adapter, ..
 2851                } = server_state
 2852                {
 2853                    Some((server.clone(), adapter.clone()))
 2854                } else {
 2855                    None
 2856                }
 2857            })
 2858            .collect::<Vec<_>>();
 2859        for (server, adapter) in servers_and_adapters {
 2860            buffer_handle.update(cx, |buffer, cx| {
 2861                buffer.set_completion_triggers(
 2862                    server.server_id(),
 2863                    server
 2864                        .capabilities()
 2865                        .completion_provider
 2866                        .as_ref()
 2867                        .and_then(|provider| {
 2868                            provider
 2869                                .trigger_characters
 2870                                .as_ref()
 2871                                .map(|characters| characters.iter().cloned().collect())
 2872                        })
 2873                        .unwrap_or_default(),
 2874                    cx,
 2875                );
 2876            });
 2877
 2878            let snapshot = LspBufferSnapshot {
 2879                version: 0,
 2880                snapshot: initial_snapshot.clone(),
 2881            };
 2882
 2883            let mut registered = false;
 2884            self.buffer_snapshots
 2885                .entry(buffer_id)
 2886                .or_default()
 2887                .entry(server.server_id())
 2888                .or_insert_with(|| {
 2889                    registered = true;
 2890                    server.register_buffer(
 2891                        uri.clone(),
 2892                        adapter.language_id(&language.name()),
 2893                        0,
 2894                        initial_snapshot.text(),
 2895                    );
 2896
 2897                    vec![snapshot]
 2898                });
 2899
 2900            self.buffers_opened_in_servers
 2901                .entry(buffer_id)
 2902                .or_default()
 2903                .insert(server.server_id());
 2904            if registered {
 2905                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2906                    language_server_id: server.server_id(),
 2907                    name: None,
 2908                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2909                        proto::RegisteredForBuffer {
 2910                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2911                            buffer_id: buffer_id.to_proto(),
 2912                        },
 2913                    ),
 2914                });
 2915            }
 2916        }
 2917    }
 2918
 2919    fn reuse_existing_language_server<'lang_name>(
 2920        &self,
 2921        server_tree: &LanguageServerTree,
 2922        worktree: &Entity<Worktree>,
 2923        language_name: &'lang_name LanguageName,
 2924        cx: &mut App,
 2925    ) -> Option<(
 2926        Arc<LocalLspAdapterDelegate>,
 2927        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2928    )> {
 2929        if worktree.read(cx).is_visible() {
 2930            return None;
 2931        }
 2932
 2933        let worktree_store = self.worktree_store.read(cx);
 2934        let servers = server_tree
 2935            .instances
 2936            .iter()
 2937            .filter(|(worktree_id, _)| {
 2938                worktree_store
 2939                    .worktree_for_id(**worktree_id, cx)
 2940                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2941            })
 2942            .flat_map(|(worktree_id, servers)| {
 2943                servers
 2944                    .roots
 2945                    .iter()
 2946                    .flat_map(|(_, language_servers)| language_servers)
 2947                    .map(move |(_, (server_node, server_languages))| {
 2948                        (worktree_id, server_node, server_languages)
 2949                    })
 2950                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2951                    .map(|(worktree_id, server_node, _)| {
 2952                        (
 2953                            *worktree_id,
 2954                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2955                        )
 2956                    })
 2957            })
 2958            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2959                acc.entry(worktree_id)
 2960                    .or_insert_with(Vec::new)
 2961                    .push(server_node);
 2962                acc
 2963            })
 2964            .into_values()
 2965            .max_by_key(|servers| servers.len())?;
 2966
 2967        let worktree_id = worktree.read(cx).id();
 2968        let apply = move |tree: &mut LanguageServerTree| {
 2969            for server_node in &servers {
 2970                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2971            }
 2972            servers
 2973        };
 2974
 2975        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2976        Some((delegate, apply))
 2977    }
 2978
 2979    pub(crate) fn unregister_old_buffer_from_language_servers(
 2980        &mut self,
 2981        buffer: &Entity<Buffer>,
 2982        old_file: &File,
 2983        cx: &mut App,
 2984    ) {
 2985        let old_path = match old_file.as_local() {
 2986            Some(local) => local.abs_path(cx),
 2987            None => return,
 2988        };
 2989
 2990        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2991            debug_panic!("{old_path:?} is not parseable as an URI");
 2992            return;
 2993        };
 2994        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2995    }
 2996
 2997    pub(crate) fn unregister_buffer_from_language_servers(
 2998        &mut self,
 2999        buffer: &Entity<Buffer>,
 3000        file_url: &lsp::Uri,
 3001        cx: &mut App,
 3002    ) {
 3003        buffer.update(cx, |buffer, cx| {
 3004            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 3005
 3006            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 3007                if snapshots
 3008                    .as_mut()
 3009                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 3010                {
 3011                    language_server.unregister_buffer(file_url.clone());
 3012                }
 3013            }
 3014        });
 3015    }
 3016
 3017    fn buffer_snapshot_for_lsp_version(
 3018        &mut self,
 3019        buffer: &Entity<Buffer>,
 3020        server_id: LanguageServerId,
 3021        version: Option<i32>,
 3022        cx: &App,
 3023    ) -> Result<TextBufferSnapshot> {
 3024        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 3025
 3026        if let Some(version) = version {
 3027            let buffer_id = buffer.read(cx).remote_id();
 3028            let snapshots = if let Some(snapshots) = self
 3029                .buffer_snapshots
 3030                .get_mut(&buffer_id)
 3031                .and_then(|m| m.get_mut(&server_id))
 3032            {
 3033                snapshots
 3034            } else if version == 0 {
 3035                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 3036                // We detect this case and treat it as if the version was `None`.
 3037                return Ok(buffer.read(cx).text_snapshot());
 3038            } else {
 3039                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 3040            };
 3041
 3042            let found_snapshot = snapshots
 3043                    .binary_search_by_key(&version, |e| e.version)
 3044                    .map(|ix| snapshots[ix].snapshot.clone())
 3045                    .map_err(|_| {
 3046                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 3047                    })?;
 3048
 3049            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 3050            Ok(found_snapshot)
 3051        } else {
 3052            Ok((buffer.read(cx)).text_snapshot())
 3053        }
 3054    }
 3055
 3056    async fn get_server_code_actions_from_action_kinds(
 3057        lsp_store: &WeakEntity<LspStore>,
 3058        language_server_id: LanguageServerId,
 3059        code_action_kinds: Vec<lsp::CodeActionKind>,
 3060        buffer: &Entity<Buffer>,
 3061        cx: &mut AsyncApp,
 3062    ) -> Result<Vec<CodeAction>> {
 3063        let actions = lsp_store
 3064            .update(cx, move |this, cx| {
 3065                let request = GetCodeActions {
 3066                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 3067                    kinds: Some(code_action_kinds),
 3068                };
 3069                let server = LanguageServerToQuery::Other(language_server_id);
 3070                this.request_lsp(buffer.clone(), server, request, cx)
 3071            })?
 3072            .await?;
 3073        Ok(actions)
 3074    }
 3075
 3076    pub async fn execute_code_actions_on_server(
 3077        lsp_store: &WeakEntity<LspStore>,
 3078        language_server: &Arc<LanguageServer>,
 3079        actions: Vec<CodeAction>,
 3080        push_to_history: bool,
 3081        project_transaction: &mut ProjectTransaction,
 3082        cx: &mut AsyncApp,
 3083    ) -> anyhow::Result<()> {
 3084        let request_timeout = cx.update(|app| {
 3085            ProjectSettings::get_global(app)
 3086                .global_lsp_settings
 3087                .get_request_timeout()
 3088        });
 3089
 3090        for mut action in actions {
 3091            Self::try_resolve_code_action(language_server, &mut action, request_timeout)
 3092                .await
 3093                .context("resolving a formatting code action")?;
 3094
 3095            if let Some(edit) = action.lsp_action.edit() {
 3096                if edit.changes.is_none() && edit.document_changes.is_none() {
 3097                    continue;
 3098                }
 3099
 3100                let new = Self::deserialize_workspace_edit(
 3101                    lsp_store.upgrade().context("project dropped")?,
 3102                    edit.clone(),
 3103                    push_to_history,
 3104                    language_server.clone(),
 3105                    cx,
 3106                )
 3107                .await?;
 3108                project_transaction.0.extend(new.0);
 3109            }
 3110
 3111            let Some(command) = action.lsp_action.command() else {
 3112                continue;
 3113            };
 3114
 3115            let server_capabilities = language_server.capabilities();
 3116            let available_commands = server_capabilities
 3117                .execute_command_provider
 3118                .as_ref()
 3119                .map(|options| options.commands.as_slice())
 3120                .unwrap_or_default();
 3121            if !available_commands.contains(&command.command) {
 3122                log::warn!(
 3123                    "Cannot execute a command {} not listed in the language server capabilities",
 3124                    command.command
 3125                );
 3126                continue;
 3127            }
 3128
 3129            lsp_store.update(cx, |lsp_store, _| {
 3130                if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 3131                    mode.last_workspace_edits_by_language_server
 3132                        .remove(&language_server.server_id());
 3133                }
 3134            })?;
 3135
 3136            language_server
 3137                .request::<lsp::request::ExecuteCommand>(
 3138                    lsp::ExecuteCommandParams {
 3139                        command: command.command.clone(),
 3140                        arguments: command.arguments.clone().unwrap_or_default(),
 3141                        ..Default::default()
 3142                    },
 3143                    request_timeout,
 3144                )
 3145                .await
 3146                .into_response()
 3147                .context("execute command")?;
 3148
 3149            lsp_store.update(cx, |this, _| {
 3150                if let LspStoreMode::Local(mode) = &mut this.mode {
 3151                    project_transaction.0.extend(
 3152                        mode.last_workspace_edits_by_language_server
 3153                            .remove(&language_server.server_id())
 3154                            .unwrap_or_default()
 3155                            .0,
 3156                    )
 3157                }
 3158            })?;
 3159        }
 3160        Ok(())
 3161    }
 3162
 3163    pub async fn deserialize_text_edits(
 3164        this: Entity<LspStore>,
 3165        buffer_to_edit: Entity<Buffer>,
 3166        edits: Vec<lsp::TextEdit>,
 3167        push_to_history: bool,
 3168        _: Arc<CachedLspAdapter>,
 3169        language_server: Arc<LanguageServer>,
 3170        cx: &mut AsyncApp,
 3171    ) -> Result<Option<Transaction>> {
 3172        let edits = this
 3173            .update(cx, |this, cx| {
 3174                this.as_local_mut().unwrap().edits_from_lsp(
 3175                    &buffer_to_edit,
 3176                    edits,
 3177                    language_server.server_id(),
 3178                    None,
 3179                    cx,
 3180                )
 3181            })
 3182            .await?;
 3183
 3184        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3185            buffer.finalize_last_transaction();
 3186            buffer.start_transaction();
 3187            for (range, text) in edits {
 3188                buffer.edit([(range, text)], None, cx);
 3189            }
 3190
 3191            if buffer.end_transaction(cx).is_some() {
 3192                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3193                if !push_to_history {
 3194                    buffer.forget_transaction(transaction.id);
 3195                }
 3196                Some(transaction)
 3197            } else {
 3198                None
 3199            }
 3200        });
 3201
 3202        Ok(transaction)
 3203    }
 3204
 3205    #[allow(clippy::type_complexity)]
 3206    pub fn edits_from_lsp(
 3207        &mut self,
 3208        buffer: &Entity<Buffer>,
 3209        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3210        server_id: LanguageServerId,
 3211        version: Option<i32>,
 3212        cx: &mut Context<LspStore>,
 3213    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3214        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3215        cx.background_spawn(async move {
 3216            let snapshot = snapshot?;
 3217            let mut lsp_edits = lsp_edits
 3218                .into_iter()
 3219                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3220                .collect::<Vec<_>>();
 3221
 3222            lsp_edits.sort_unstable_by_key(|(range, _)| (range.start, range.end));
 3223
 3224            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3225            let mut edits = Vec::new();
 3226            while let Some((range, mut new_text)) = lsp_edits.next() {
 3227                // Clip invalid ranges provided by the language server.
 3228                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3229                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3230
 3231                // Combine any LSP edits that are adjacent.
 3232                //
 3233                // Also, combine LSP edits that are separated from each other by only
 3234                // a newline. This is important because for some code actions,
 3235                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3236                // are separated by unchanged newline characters.
 3237                //
 3238                // In order for the diffing logic below to work properly, any edits that
 3239                // cancel each other out must be combined into one.
 3240                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3241                    if next_range.start.0 > range.end {
 3242                        if next_range.start.0.row > range.end.row + 1
 3243                            || next_range.start.0.column > 0
 3244                            || snapshot.clip_point_utf16(
 3245                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3246                                Bias::Left,
 3247                            ) > range.end
 3248                        {
 3249                            break;
 3250                        }
 3251                        new_text.push('\n');
 3252                    }
 3253                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3254                    new_text.push_str(next_text);
 3255                    lsp_edits.next();
 3256                }
 3257
 3258                // For multiline edits, perform a diff of the old and new text so that
 3259                // we can identify the changes more precisely, preserving the locations
 3260                // of any anchors positioned in the unchanged regions.
 3261                if range.end.row > range.start.row {
 3262                    let offset = range.start.to_offset(&snapshot);
 3263                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3264                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3265                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3266                        (
 3267                            snapshot.anchor_after(offset + range.start)
 3268                                ..snapshot.anchor_before(offset + range.end),
 3269                            replacement,
 3270                        )
 3271                    }));
 3272                } else if range.end == range.start {
 3273                    let anchor = snapshot.anchor_after(range.start);
 3274                    edits.push((anchor..anchor, new_text.into()));
 3275                } else {
 3276                    let edit_start = snapshot.anchor_after(range.start);
 3277                    let edit_end = snapshot.anchor_before(range.end);
 3278                    edits.push((edit_start..edit_end, new_text.into()));
 3279                }
 3280            }
 3281
 3282            Ok(edits)
 3283        })
 3284    }
 3285
 3286    pub(crate) async fn deserialize_workspace_edit(
 3287        this: Entity<LspStore>,
 3288        edit: lsp::WorkspaceEdit,
 3289        push_to_history: bool,
 3290        language_server: Arc<LanguageServer>,
 3291        cx: &mut AsyncApp,
 3292    ) -> Result<ProjectTransaction> {
 3293        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3294
 3295        let mut operations = Vec::new();
 3296        if let Some(document_changes) = edit.document_changes {
 3297            match document_changes {
 3298                lsp::DocumentChanges::Edits(edits) => {
 3299                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3300                }
 3301                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3302            }
 3303        } else if let Some(changes) = edit.changes {
 3304            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3305                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3306                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3307                        uri,
 3308                        version: None,
 3309                    },
 3310                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3311                })
 3312            }));
 3313        }
 3314
 3315        let mut project_transaction = ProjectTransaction::default();
 3316        for operation in operations {
 3317            match operation {
 3318                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3319                    let abs_path = op
 3320                        .uri
 3321                        .to_file_path()
 3322                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3323
 3324                    if let Some(parent_path) = abs_path.parent() {
 3325                        fs.create_dir(parent_path).await?;
 3326                    }
 3327                    if abs_path.ends_with("/") {
 3328                        fs.create_dir(&abs_path).await?;
 3329                    } else {
 3330                        fs.create_file(
 3331                            &abs_path,
 3332                            op.options
 3333                                .map(|options| fs::CreateOptions {
 3334                                    overwrite: options.overwrite.unwrap_or(false),
 3335                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3336                                })
 3337                                .unwrap_or_default(),
 3338                        )
 3339                        .await?;
 3340                    }
 3341                }
 3342
 3343                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3344                    let source_abs_path = op
 3345                        .old_uri
 3346                        .to_file_path()
 3347                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3348                    let target_abs_path = op
 3349                        .new_uri
 3350                        .to_file_path()
 3351                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3352
 3353                    let options = fs::RenameOptions {
 3354                        overwrite: op
 3355                            .options
 3356                            .as_ref()
 3357                            .and_then(|options| options.overwrite)
 3358                            .unwrap_or(false),
 3359                        ignore_if_exists: op
 3360                            .options
 3361                            .as_ref()
 3362                            .and_then(|options| options.ignore_if_exists)
 3363                            .unwrap_or(false),
 3364                        create_parents: true,
 3365                    };
 3366
 3367                    fs.rename(&source_abs_path, &target_abs_path, options)
 3368                        .await?;
 3369                }
 3370
 3371                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3372                    let abs_path = op
 3373                        .uri
 3374                        .to_file_path()
 3375                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3376                    let options = op
 3377                        .options
 3378                        .map(|options| fs::RemoveOptions {
 3379                            recursive: options.recursive.unwrap_or(false),
 3380                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3381                        })
 3382                        .unwrap_or_default();
 3383                    if abs_path.ends_with("/") {
 3384                        fs.remove_dir(&abs_path, options).await?;
 3385                    } else {
 3386                        fs.remove_file(&abs_path, options).await?;
 3387                    }
 3388                }
 3389
 3390                lsp::DocumentChangeOperation::Edit(op) => {
 3391                    let buffer_to_edit = this
 3392                        .update(cx, |this, cx| {
 3393                            this.open_local_buffer_via_lsp(
 3394                                op.text_document.uri.clone(),
 3395                                language_server.server_id(),
 3396                                cx,
 3397                            )
 3398                        })
 3399                        .await?;
 3400
 3401                    let edits = this
 3402                        .update(cx, |this, cx| {
 3403                            let path = buffer_to_edit.read(cx).project_path(cx);
 3404                            let active_entry = this.active_entry;
 3405                            let is_active_entry = path.is_some_and(|project_path| {
 3406                                this.worktree_store
 3407                                    .read(cx)
 3408                                    .entry_for_path(&project_path, cx)
 3409                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3410                            });
 3411                            let local = this.as_local_mut().unwrap();
 3412
 3413                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3414                            for edit in op.edits {
 3415                                match edit {
 3416                                    Edit::Plain(edit) => {
 3417                                        if !edits.contains(&edit) {
 3418                                            edits.push(edit)
 3419                                        }
 3420                                    }
 3421                                    Edit::Annotated(edit) => {
 3422                                        if !edits.contains(&edit.text_edit) {
 3423                                            edits.push(edit.text_edit)
 3424                                        }
 3425                                    }
 3426                                    Edit::Snippet(edit) => {
 3427                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3428                                        else {
 3429                                            continue;
 3430                                        };
 3431
 3432                                        if is_active_entry {
 3433                                            snippet_edits.push((edit.range, snippet));
 3434                                        } else {
 3435                                            // Since this buffer is not focused, apply a normal edit.
 3436                                            let new_edit = TextEdit {
 3437                                                range: edit.range,
 3438                                                new_text: snippet.text,
 3439                                            };
 3440                                            if !edits.contains(&new_edit) {
 3441                                                edits.push(new_edit);
 3442                                            }
 3443                                        }
 3444                                    }
 3445                                }
 3446                            }
 3447                            if !snippet_edits.is_empty() {
 3448                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3449                                let version = if let Some(buffer_version) = op.text_document.version
 3450                                {
 3451                                    local
 3452                                        .buffer_snapshot_for_lsp_version(
 3453                                            &buffer_to_edit,
 3454                                            language_server.server_id(),
 3455                                            Some(buffer_version),
 3456                                            cx,
 3457                                        )
 3458                                        .ok()
 3459                                        .map(|snapshot| snapshot.version)
 3460                                } else {
 3461                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3462                                };
 3463
 3464                                let most_recent_edit =
 3465                                    version.and_then(|version| version.most_recent());
 3466                                // Check if the edit that triggered that edit has been made by this participant.
 3467
 3468                                if let Some(most_recent_edit) = most_recent_edit {
 3469                                    cx.emit(LspStoreEvent::SnippetEdit {
 3470                                        buffer_id,
 3471                                        edits: snippet_edits,
 3472                                        most_recent_edit,
 3473                                    });
 3474                                }
 3475                            }
 3476
 3477                            local.edits_from_lsp(
 3478                                &buffer_to_edit,
 3479                                edits,
 3480                                language_server.server_id(),
 3481                                op.text_document.version,
 3482                                cx,
 3483                            )
 3484                        })
 3485                        .await?;
 3486
 3487                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3488                        buffer.finalize_last_transaction();
 3489                        buffer.start_transaction();
 3490                        for (range, text) in edits {
 3491                            buffer.edit([(range, text)], None, cx);
 3492                        }
 3493
 3494                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3495                            if push_to_history {
 3496                                buffer.finalize_last_transaction();
 3497                                buffer.get_transaction(transaction_id).cloned()
 3498                            } else {
 3499                                buffer.forget_transaction(transaction_id)
 3500                            }
 3501                        })
 3502                    });
 3503                    if let Some(transaction) = transaction {
 3504                        project_transaction.0.insert(buffer_to_edit, transaction);
 3505                    }
 3506                }
 3507            }
 3508        }
 3509
 3510        Ok(project_transaction)
 3511    }
 3512
 3513    async fn on_lsp_workspace_edit(
 3514        this: WeakEntity<LspStore>,
 3515        params: lsp::ApplyWorkspaceEditParams,
 3516        server_id: LanguageServerId,
 3517        cx: &mut AsyncApp,
 3518    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3519        let this = this.upgrade().context("project project closed")?;
 3520        let language_server = this
 3521            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3522            .context("language server not found")?;
 3523        let transaction = Self::deserialize_workspace_edit(
 3524            this.clone(),
 3525            params.edit,
 3526            true,
 3527            language_server.clone(),
 3528            cx,
 3529        )
 3530        .await
 3531        .log_err();
 3532        this.update(cx, |this, cx| {
 3533            if let Some(transaction) = transaction {
 3534                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3535
 3536                this.as_local_mut()
 3537                    .unwrap()
 3538                    .last_workspace_edits_by_language_server
 3539                    .insert(server_id, transaction);
 3540            }
 3541        });
 3542        Ok(lsp::ApplyWorkspaceEditResponse {
 3543            applied: true,
 3544            failed_change: None,
 3545            failure_reason: None,
 3546        })
 3547    }
 3548
 3549    fn remove_worktree(
 3550        &mut self,
 3551        id_to_remove: WorktreeId,
 3552        cx: &mut Context<LspStore>,
 3553    ) -> Vec<LanguageServerId> {
 3554        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3555        self.diagnostics.remove(&id_to_remove);
 3556        self.prettier_store.update(cx, |prettier_store, cx| {
 3557            prettier_store.remove_worktree(id_to_remove, cx);
 3558        });
 3559
 3560        let mut servers_to_remove = BTreeSet::default();
 3561        let mut servers_to_preserve = HashSet::default();
 3562        for (seed, state) in &self.language_server_ids {
 3563            if seed.worktree_id == id_to_remove {
 3564                servers_to_remove.insert(state.id);
 3565            } else {
 3566                servers_to_preserve.insert(state.id);
 3567            }
 3568        }
 3569        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3570        self.language_server_ids
 3571            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3572        for server_id_to_remove in &servers_to_remove {
 3573            self.language_server_watched_paths
 3574                .remove(server_id_to_remove);
 3575            self.language_server_paths_watched_for_rename
 3576                .remove(server_id_to_remove);
 3577            self.last_workspace_edits_by_language_server
 3578                .remove(server_id_to_remove);
 3579            self.language_servers.remove(server_id_to_remove);
 3580            self.buffer_pull_diagnostics_result_ids
 3581                .remove(server_id_to_remove);
 3582            self.workspace_pull_diagnostics_result_ids
 3583                .remove(server_id_to_remove);
 3584            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3585                buffer_servers.remove(server_id_to_remove);
 3586            }
 3587            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3588        }
 3589        servers_to_remove.into_iter().collect()
 3590    }
 3591
 3592    fn rebuild_watched_paths_inner<'a>(
 3593        &'a self,
 3594        language_server_id: LanguageServerId,
 3595        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3596        cx: &mut Context<LspStore>,
 3597    ) -> LanguageServerWatchedPathsBuilder {
 3598        let worktrees = self
 3599            .worktree_store
 3600            .read(cx)
 3601            .worktrees()
 3602            .filter_map(|worktree| {
 3603                self.language_servers_for_worktree(worktree.read(cx).id())
 3604                    .find(|server| server.server_id() == language_server_id)
 3605                    .map(|_| worktree)
 3606            })
 3607            .collect::<Vec<_>>();
 3608
 3609        let mut worktree_globs = HashMap::default();
 3610        let mut abs_globs = HashMap::default();
 3611        log::trace!(
 3612            "Processing new watcher paths for language server with id {}",
 3613            language_server_id
 3614        );
 3615
 3616        for watcher in watchers {
 3617            if let Some((worktree, literal_prefix, pattern)) =
 3618                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3619            {
 3620                worktree.update(cx, |worktree, _| {
 3621                    if let Some((tree, glob)) =
 3622                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3623                    {
 3624                        tree.add_path_prefix_to_scan(literal_prefix);
 3625                        worktree_globs
 3626                            .entry(tree.id())
 3627                            .or_insert_with(GlobSetBuilder::new)
 3628                            .add(glob);
 3629                    }
 3630                });
 3631            } else {
 3632                let (path, pattern) = match &watcher.glob_pattern {
 3633                    lsp::GlobPattern::String(s) => {
 3634                        let watcher_path = SanitizedPath::new(s);
 3635                        let path = glob_literal_prefix(watcher_path.as_path());
 3636                        let pattern = watcher_path
 3637                            .as_path()
 3638                            .strip_prefix(&path)
 3639                            .map(|p| p.to_string_lossy().into_owned())
 3640                            .unwrap_or_else(|e| {
 3641                                debug_panic!(
 3642                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3643                                    s,
 3644                                    path.display(),
 3645                                    e
 3646                                );
 3647                                watcher_path.as_path().to_string_lossy().into_owned()
 3648                            });
 3649                        (path, pattern)
 3650                    }
 3651                    lsp::GlobPattern::Relative(rp) => {
 3652                        let Ok(mut base_uri) = match &rp.base_uri {
 3653                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3654                            lsp::OneOf::Right(base_uri) => base_uri,
 3655                        }
 3656                        .to_file_path() else {
 3657                            continue;
 3658                        };
 3659
 3660                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3661                        let pattern = Path::new(&rp.pattern)
 3662                            .strip_prefix(&path)
 3663                            .map(|p| p.to_string_lossy().into_owned())
 3664                            .unwrap_or_else(|e| {
 3665                                debug_panic!(
 3666                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3667                                    rp.pattern,
 3668                                    path.display(),
 3669                                    e
 3670                                );
 3671                                rp.pattern.clone()
 3672                            });
 3673                        base_uri.push(path);
 3674                        (base_uri, pattern)
 3675                    }
 3676                };
 3677
 3678                if let Some(glob) = Glob::new(&pattern).log_err() {
 3679                    if !path
 3680                        .components()
 3681                        .any(|c| matches!(c, path::Component::Normal(_)))
 3682                    {
 3683                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3684                        // rather than adding a new watcher for `/`.
 3685                        for worktree in &worktrees {
 3686                            worktree_globs
 3687                                .entry(worktree.read(cx).id())
 3688                                .or_insert_with(GlobSetBuilder::new)
 3689                                .add(glob.clone());
 3690                        }
 3691                    } else {
 3692                        abs_globs
 3693                            .entry(path.into())
 3694                            .or_insert_with(GlobSetBuilder::new)
 3695                            .add(glob);
 3696                    }
 3697                }
 3698            }
 3699        }
 3700
 3701        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3702        for (worktree_id, builder) in worktree_globs {
 3703            if let Ok(globset) = builder.build() {
 3704                watch_builder.watch_worktree(worktree_id, globset);
 3705            }
 3706        }
 3707        for (abs_path, builder) in abs_globs {
 3708            if let Ok(globset) = builder.build() {
 3709                watch_builder.watch_abs_path(abs_path, globset);
 3710            }
 3711        }
 3712        watch_builder
 3713    }
 3714
 3715    fn worktree_and_path_for_file_watcher(
 3716        worktrees: &[Entity<Worktree>],
 3717        watcher: &FileSystemWatcher,
 3718        cx: &App,
 3719    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3720        worktrees.iter().find_map(|worktree| {
 3721            let tree = worktree.read(cx);
 3722            let worktree_root_path = tree.abs_path();
 3723            let path_style = tree.path_style();
 3724            match &watcher.glob_pattern {
 3725                lsp::GlobPattern::String(s) => {
 3726                    let watcher_path = SanitizedPath::new(s);
 3727                    let relative = watcher_path
 3728                        .as_path()
 3729                        .strip_prefix(&worktree_root_path)
 3730                        .ok()?;
 3731                    let literal_prefix = glob_literal_prefix(relative);
 3732                    Some((
 3733                        worktree.clone(),
 3734                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3735                        relative.to_string_lossy().into_owned(),
 3736                    ))
 3737                }
 3738                lsp::GlobPattern::Relative(rp) => {
 3739                    let base_uri = match &rp.base_uri {
 3740                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3741                        lsp::OneOf::Right(base_uri) => base_uri,
 3742                    }
 3743                    .to_file_path()
 3744                    .ok()?;
 3745                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3746                    let mut literal_prefix = relative.to_owned();
 3747                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3748                    Some((
 3749                        worktree.clone(),
 3750                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3751                        rp.pattern.clone(),
 3752                    ))
 3753                }
 3754            }
 3755        })
 3756    }
 3757
 3758    fn rebuild_watched_paths(
 3759        &mut self,
 3760        language_server_id: LanguageServerId,
 3761        cx: &mut Context<LspStore>,
 3762    ) {
 3763        let Some(registrations) = self
 3764            .language_server_dynamic_registrations
 3765            .get(&language_server_id)
 3766        else {
 3767            return;
 3768        };
 3769
 3770        let watch_builder = self.rebuild_watched_paths_inner(
 3771            language_server_id,
 3772            registrations.did_change_watched_files.values().flatten(),
 3773            cx,
 3774        );
 3775        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3776        self.language_server_watched_paths
 3777            .insert(language_server_id, watcher);
 3778
 3779        cx.notify();
 3780    }
 3781
 3782    fn on_lsp_did_change_watched_files(
 3783        &mut self,
 3784        language_server_id: LanguageServerId,
 3785        registration_id: &str,
 3786        params: DidChangeWatchedFilesRegistrationOptions,
 3787        cx: &mut Context<LspStore>,
 3788    ) {
 3789        let registrations = self
 3790            .language_server_dynamic_registrations
 3791            .entry(language_server_id)
 3792            .or_default();
 3793
 3794        registrations
 3795            .did_change_watched_files
 3796            .insert(registration_id.to_string(), params.watchers);
 3797
 3798        self.rebuild_watched_paths(language_server_id, cx);
 3799    }
 3800
 3801    fn on_lsp_unregister_did_change_watched_files(
 3802        &mut self,
 3803        language_server_id: LanguageServerId,
 3804        registration_id: &str,
 3805        cx: &mut Context<LspStore>,
 3806    ) {
 3807        let registrations = self
 3808            .language_server_dynamic_registrations
 3809            .entry(language_server_id)
 3810            .or_default();
 3811
 3812        if registrations
 3813            .did_change_watched_files
 3814            .remove(registration_id)
 3815            .is_some()
 3816        {
 3817            log::info!(
 3818                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3819                language_server_id,
 3820                registration_id
 3821            );
 3822        } else {
 3823            log::warn!(
 3824                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3825                language_server_id,
 3826                registration_id
 3827            );
 3828        }
 3829
 3830        self.rebuild_watched_paths(language_server_id, cx);
 3831    }
 3832
 3833    async fn initialization_options_for_adapter(
 3834        adapter: Arc<dyn LspAdapter>,
 3835        delegate: &Arc<dyn LspAdapterDelegate>,
 3836        cx: &mut AsyncApp,
 3837    ) -> Result<Option<serde_json::Value>> {
 3838        let Some(mut initialization_config) =
 3839            adapter.clone().initialization_options(delegate, cx).await?
 3840        else {
 3841            return Ok(None);
 3842        };
 3843
 3844        for other_adapter in delegate.registered_lsp_adapters() {
 3845            if other_adapter.name() == adapter.name() {
 3846                continue;
 3847            }
 3848            if let Ok(Some(target_config)) = other_adapter
 3849                .clone()
 3850                .additional_initialization_options(adapter.name(), delegate)
 3851                .await
 3852            {
 3853                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3854            }
 3855        }
 3856
 3857        Ok(Some(initialization_config))
 3858    }
 3859
 3860    async fn workspace_configuration_for_adapter(
 3861        adapter: Arc<dyn LspAdapter>,
 3862        delegate: &Arc<dyn LspAdapterDelegate>,
 3863        toolchain: Option<Toolchain>,
 3864        requested_uri: Option<Uri>,
 3865        cx: &mut AsyncApp,
 3866    ) -> Result<serde_json::Value> {
 3867        let mut workspace_config = adapter
 3868            .clone()
 3869            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3870            .await?;
 3871
 3872        for other_adapter in delegate.registered_lsp_adapters() {
 3873            if other_adapter.name() == adapter.name() {
 3874                continue;
 3875            }
 3876            if let Ok(Some(target_config)) = other_adapter
 3877                .clone()
 3878                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3879                .await
 3880            {
 3881                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3882            }
 3883        }
 3884
 3885        Ok(workspace_config)
 3886    }
 3887
 3888    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3889        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3890            Some(server.clone())
 3891        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3892            Some(Arc::clone(server))
 3893        } else {
 3894            None
 3895        }
 3896    }
 3897}
 3898
 3899fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3900    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3901        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3902            language_server_id: server.server_id(),
 3903            name: Some(server.name()),
 3904            message: proto::update_language_server::Variant::MetadataUpdated(
 3905                proto::ServerMetadataUpdated {
 3906                    capabilities: Some(capabilities),
 3907                    binary: Some(proto::LanguageServerBinaryInfo {
 3908                        path: server.binary().path.to_string_lossy().into_owned(),
 3909                        arguments: server
 3910                            .binary()
 3911                            .arguments
 3912                            .iter()
 3913                            .map(|arg| arg.to_string_lossy().into_owned())
 3914                            .collect(),
 3915                    }),
 3916                    configuration: serde_json::to_string(server.configuration()).ok(),
 3917                    workspace_folders: server
 3918                        .workspace_folders()
 3919                        .iter()
 3920                        .map(|uri| uri.to_string())
 3921                        .collect(),
 3922                },
 3923            ),
 3924        });
 3925    }
 3926}
 3927
 3928#[derive(Debug)]
 3929pub struct FormattableBuffer {
 3930    handle: Entity<Buffer>,
 3931    abs_path: Option<PathBuf>,
 3932    env: Option<HashMap<String, String>>,
 3933    ranges: Option<Vec<Range<Anchor>>>,
 3934}
 3935
 3936pub struct RemoteLspStore {
 3937    upstream_client: Option<AnyProtoClient>,
 3938    upstream_project_id: u64,
 3939}
 3940
 3941pub(crate) enum LspStoreMode {
 3942    Local(LocalLspStore),   // ssh host and collab host
 3943    Remote(RemoteLspStore), // collab guest
 3944}
 3945
 3946impl LspStoreMode {
 3947    fn is_local(&self) -> bool {
 3948        matches!(self, LspStoreMode::Local(_))
 3949    }
 3950}
 3951
 3952pub struct LspStore {
 3953    mode: LspStoreMode,
 3954    last_formatting_failure: Option<String>,
 3955    downstream_client: Option<(AnyProtoClient, u64)>,
 3956    nonce: u128,
 3957    buffer_store: Entity<BufferStore>,
 3958    worktree_store: Entity<WorktreeStore>,
 3959    pub languages: Arc<LanguageRegistry>,
 3960    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3961    active_entry: Option<ProjectEntryId>,
 3962    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3963    _maintain_buffer_languages: Task<()>,
 3964    diagnostic_summaries:
 3965        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3966    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3967    semantic_token_config: SemanticTokenConfig,
 3968    lsp_data: HashMap<BufferId, BufferLspData>,
 3969    buffer_reload_tasks: HashMap<BufferId, Task<anyhow::Result<()>>>,
 3970    next_hint_id: Arc<AtomicUsize>,
 3971}
 3972
 3973#[derive(Debug)]
 3974pub struct BufferLspData {
 3975    buffer_version: Global,
 3976    document_colors: Option<DocumentColorData>,
 3977    code_lens: Option<CodeLensData>,
 3978    semantic_tokens: Option<SemanticTokensData>,
 3979    folding_ranges: Option<FoldingRangeData>,
 3980    document_symbols: Option<DocumentSymbolsData>,
 3981    inlay_hints: BufferInlayHints,
 3982    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3983    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3984}
 3985
 3986#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3987struct LspKey {
 3988    request_type: TypeId,
 3989    server_queried: Option<LanguageServerId>,
 3990}
 3991
 3992impl BufferLspData {
 3993    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3994        Self {
 3995            buffer_version: buffer.read(cx).version(),
 3996            document_colors: None,
 3997            code_lens: None,
 3998            semantic_tokens: None,
 3999            folding_ranges: None,
 4000            document_symbols: None,
 4001            inlay_hints: BufferInlayHints::new(buffer, cx),
 4002            lsp_requests: HashMap::default(),
 4003            chunk_lsp_requests: HashMap::default(),
 4004        }
 4005    }
 4006
 4007    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 4008        if let Some(document_colors) = &mut self.document_colors {
 4009            document_colors.remove_server_data(for_server);
 4010        }
 4011
 4012        if let Some(code_lens) = &mut self.code_lens {
 4013            code_lens.remove_server_data(for_server);
 4014        }
 4015
 4016        self.inlay_hints.remove_server_data(for_server);
 4017
 4018        if let Some(semantic_tokens) = &mut self.semantic_tokens {
 4019            semantic_tokens.remove_server_data(for_server);
 4020        }
 4021
 4022        if let Some(folding_ranges) = &mut self.folding_ranges {
 4023            folding_ranges.ranges.remove(&for_server);
 4024        }
 4025
 4026        if let Some(document_symbols) = &mut self.document_symbols {
 4027            document_symbols.remove_server_data(for_server);
 4028        }
 4029    }
 4030
 4031    #[cfg(any(test, feature = "test-support"))]
 4032    pub fn inlay_hints(&self) -> &BufferInlayHints {
 4033        &self.inlay_hints
 4034    }
 4035}
 4036
 4037#[derive(Debug)]
 4038pub enum LspStoreEvent {
 4039    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 4040    LanguageServerRemoved(LanguageServerId),
 4041    LanguageServerUpdate {
 4042        language_server_id: LanguageServerId,
 4043        name: Option<LanguageServerName>,
 4044        message: proto::update_language_server::Variant,
 4045    },
 4046    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 4047    LanguageServerPrompt(LanguageServerPromptRequest),
 4048    LanguageDetected {
 4049        buffer: Entity<Buffer>,
 4050        new_language: Option<Arc<Language>>,
 4051    },
 4052    Notification(String),
 4053    RefreshInlayHints {
 4054        server_id: LanguageServerId,
 4055        request_id: Option<usize>,
 4056    },
 4057    RefreshSemanticTokens {
 4058        server_id: LanguageServerId,
 4059        request_id: Option<usize>,
 4060    },
 4061    RefreshCodeLens,
 4062    DiagnosticsUpdated {
 4063        server_id: LanguageServerId,
 4064        paths: Vec<ProjectPath>,
 4065    },
 4066    DiskBasedDiagnosticsStarted {
 4067        language_server_id: LanguageServerId,
 4068    },
 4069    DiskBasedDiagnosticsFinished {
 4070        language_server_id: LanguageServerId,
 4071    },
 4072    SnippetEdit {
 4073        buffer_id: BufferId,
 4074        edits: Vec<(lsp::Range, Snippet)>,
 4075        most_recent_edit: clock::Lamport,
 4076    },
 4077    WorkspaceEditApplied(ProjectTransaction),
 4078}
 4079
 4080#[derive(Clone, Debug, Serialize)]
 4081pub struct LanguageServerStatus {
 4082    pub name: LanguageServerName,
 4083    pub server_version: Option<SharedString>,
 4084    pub server_readable_version: Option<SharedString>,
 4085    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 4086    pub has_pending_diagnostic_updates: bool,
 4087    pub progress_tokens: HashSet<ProgressToken>,
 4088    pub worktree: Option<WorktreeId>,
 4089    pub binary: Option<LanguageServerBinary>,
 4090    pub configuration: Option<Value>,
 4091    pub workspace_folders: BTreeSet<Uri>,
 4092    pub process_id: Option<u32>,
 4093}
 4094
 4095#[derive(Clone, Debug)]
 4096struct CoreSymbol {
 4097    pub language_server_name: LanguageServerName,
 4098    pub source_worktree_id: WorktreeId,
 4099    pub source_language_server_id: LanguageServerId,
 4100    pub path: SymbolLocation,
 4101    pub name: String,
 4102    pub kind: lsp::SymbolKind,
 4103    pub range: Range<Unclipped<PointUtf16>>,
 4104    pub container_name: Option<String>,
 4105}
 4106
 4107#[derive(Clone, Debug, PartialEq, Eq)]
 4108pub enum SymbolLocation {
 4109    InProject(ProjectPath),
 4110    OutsideProject {
 4111        abs_path: Arc<Path>,
 4112        signature: [u8; 32],
 4113    },
 4114}
 4115
 4116impl SymbolLocation {
 4117    fn file_name(&self) -> Option<&str> {
 4118        match self {
 4119            Self::InProject(path) => path.path.file_name(),
 4120            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 4121        }
 4122    }
 4123}
 4124
 4125impl LspStore {
 4126    pub fn init(client: &AnyProtoClient) {
 4127        client.add_entity_request_handler(Self::handle_lsp_query);
 4128        client.add_entity_message_handler(Self::handle_lsp_query_response);
 4129        client.add_entity_request_handler(Self::handle_restart_language_servers);
 4130        client.add_entity_request_handler(Self::handle_stop_language_servers);
 4131        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 4132        client.add_entity_message_handler(Self::handle_start_language_server);
 4133        client.add_entity_message_handler(Self::handle_update_language_server);
 4134        client.add_entity_message_handler(Self::handle_language_server_log);
 4135        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 4136        client.add_entity_request_handler(Self::handle_format_buffers);
 4137        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 4138        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 4139        client.add_entity_request_handler(Self::handle_apply_code_action);
 4140        client.add_entity_request_handler(Self::handle_get_project_symbols);
 4141        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 4142        client.add_entity_request_handler(Self::handle_get_color_presentation);
 4143        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 4144        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 4145        client.add_entity_request_handler(Self::handle_refresh_semantic_tokens);
 4146        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 4147        client.add_entity_request_handler(Self::handle_on_type_formatting);
 4148        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 4149        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 4150        client.add_entity_request_handler(Self::handle_rename_project_entry);
 4151        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 4152        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 4153        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 4154        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 4155        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 4156        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 4157        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 4158
 4159        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 4160        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 4161        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 4162        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 4163        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 4164        client.add_entity_request_handler(
 4165            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 4166        );
 4167        client.add_entity_request_handler(
 4168            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 4169        );
 4170        client.add_entity_request_handler(
 4171            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 4172        );
 4173    }
 4174
 4175    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 4176        match &self.mode {
 4177            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 4178            _ => None,
 4179        }
 4180    }
 4181
 4182    pub fn as_local(&self) -> Option<&LocalLspStore> {
 4183        match &self.mode {
 4184            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4185            _ => None,
 4186        }
 4187    }
 4188
 4189    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 4190        match &mut self.mode {
 4191            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4192            _ => None,
 4193        }
 4194    }
 4195
 4196    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4197        match &self.mode {
 4198            LspStoreMode::Remote(RemoteLspStore {
 4199                upstream_client: Some(upstream_client),
 4200                upstream_project_id,
 4201                ..
 4202            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4203
 4204            LspStoreMode::Remote(RemoteLspStore {
 4205                upstream_client: None,
 4206                ..
 4207            }) => None,
 4208            LspStoreMode::Local(_) => None,
 4209        }
 4210    }
 4211
 4212    pub fn new_local(
 4213        buffer_store: Entity<BufferStore>,
 4214        worktree_store: Entity<WorktreeStore>,
 4215        prettier_store: Entity<PrettierStore>,
 4216        toolchain_store: Entity<LocalToolchainStore>,
 4217        environment: Entity<ProjectEnvironment>,
 4218        manifest_tree: Entity<ManifestTree>,
 4219        languages: Arc<LanguageRegistry>,
 4220        http_client: Arc<dyn HttpClient>,
 4221        fs: Arc<dyn Fs>,
 4222        cx: &mut Context<Self>,
 4223    ) -> Self {
 4224        let yarn = YarnPathStore::new(fs.clone(), cx);
 4225        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4226            .detach();
 4227        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4228            .detach();
 4229        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4230            .detach();
 4231        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4232            .detach();
 4233        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4234            .detach();
 4235        subscribe_to_binary_statuses(&languages, cx).detach();
 4236
 4237        let _maintain_workspace_config = {
 4238            let (sender, receiver) = watch::channel();
 4239            (Self::maintain_workspace_config(receiver, cx), sender)
 4240        };
 4241
 4242        Self {
 4243            mode: LspStoreMode::Local(LocalLspStore {
 4244                weak: cx.weak_entity(),
 4245                worktree_store: worktree_store.clone(),
 4246
 4247                supplementary_language_servers: Default::default(),
 4248                languages: languages.clone(),
 4249                language_server_ids: Default::default(),
 4250                language_servers: Default::default(),
 4251                last_workspace_edits_by_language_server: Default::default(),
 4252                language_server_watched_paths: Default::default(),
 4253                language_server_paths_watched_for_rename: Default::default(),
 4254                language_server_dynamic_registrations: Default::default(),
 4255                buffers_being_formatted: Default::default(),
 4256                buffers_to_refresh_hash_set: HashSet::default(),
 4257                buffers_to_refresh_queue: VecDeque::new(),
 4258                _background_diagnostics_worker: Task::ready(()).shared(),
 4259                buffer_snapshots: Default::default(),
 4260                prettier_store,
 4261                environment,
 4262                http_client,
 4263                fs,
 4264                yarn,
 4265                next_diagnostic_group_id: Default::default(),
 4266                diagnostics: Default::default(),
 4267                _subscription: cx.on_app_quit(|this, _| {
 4268                    this.as_local_mut()
 4269                        .unwrap()
 4270                        .shutdown_language_servers_on_quit()
 4271                }),
 4272                lsp_tree: LanguageServerTree::new(
 4273                    manifest_tree,
 4274                    languages.clone(),
 4275                    toolchain_store.clone(),
 4276                ),
 4277                toolchain_store,
 4278                registered_buffers: HashMap::default(),
 4279                buffers_opened_in_servers: HashMap::default(),
 4280                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4281                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4282                restricted_worktrees_tasks: HashMap::default(),
 4283                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4284                    .manifest_file_names(),
 4285            }),
 4286            last_formatting_failure: None,
 4287            downstream_client: None,
 4288            buffer_store,
 4289            worktree_store,
 4290            languages: languages.clone(),
 4291            language_server_statuses: Default::default(),
 4292            nonce: StdRng::from_os_rng().random(),
 4293            diagnostic_summaries: HashMap::default(),
 4294            lsp_server_capabilities: HashMap::default(),
 4295            semantic_token_config: SemanticTokenConfig::new(cx),
 4296            lsp_data: HashMap::default(),
 4297            buffer_reload_tasks: HashMap::default(),
 4298            next_hint_id: Arc::default(),
 4299            active_entry: None,
 4300            _maintain_workspace_config,
 4301            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4302        }
 4303    }
 4304
 4305    fn send_lsp_proto_request<R: LspCommand>(
 4306        &self,
 4307        buffer: Entity<Buffer>,
 4308        client: AnyProtoClient,
 4309        upstream_project_id: u64,
 4310        request: R,
 4311        cx: &mut Context<LspStore>,
 4312    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4313        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4314            return Task::ready(Ok(R::Response::default()));
 4315        }
 4316        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4317        cx.spawn(async move |this, cx| {
 4318            let response = client.request(message).await?;
 4319            let this = this.upgrade().context("project dropped")?;
 4320            request
 4321                .response_from_proto(response, this, buffer, cx.clone())
 4322                .await
 4323        })
 4324    }
 4325
 4326    pub(super) fn new_remote(
 4327        buffer_store: Entity<BufferStore>,
 4328        worktree_store: Entity<WorktreeStore>,
 4329        languages: Arc<LanguageRegistry>,
 4330        upstream_client: AnyProtoClient,
 4331        project_id: u64,
 4332        cx: &mut Context<Self>,
 4333    ) -> Self {
 4334        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4335            .detach();
 4336        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4337            .detach();
 4338        subscribe_to_binary_statuses(&languages, cx).detach();
 4339        let _maintain_workspace_config = {
 4340            let (sender, receiver) = watch::channel();
 4341            (Self::maintain_workspace_config(receiver, cx), sender)
 4342        };
 4343        Self {
 4344            mode: LspStoreMode::Remote(RemoteLspStore {
 4345                upstream_client: Some(upstream_client),
 4346                upstream_project_id: project_id,
 4347            }),
 4348            downstream_client: None,
 4349            last_formatting_failure: None,
 4350            buffer_store,
 4351            worktree_store,
 4352            languages: languages.clone(),
 4353            language_server_statuses: Default::default(),
 4354            nonce: StdRng::from_os_rng().random(),
 4355            diagnostic_summaries: HashMap::default(),
 4356            lsp_server_capabilities: HashMap::default(),
 4357            semantic_token_config: SemanticTokenConfig::new(cx),
 4358            next_hint_id: Arc::default(),
 4359            lsp_data: HashMap::default(),
 4360            buffer_reload_tasks: HashMap::default(),
 4361            active_entry: None,
 4362
 4363            _maintain_workspace_config,
 4364            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4365        }
 4366    }
 4367
 4368    fn on_buffer_store_event(
 4369        &mut self,
 4370        _: Entity<BufferStore>,
 4371        event: &BufferStoreEvent,
 4372        cx: &mut Context<Self>,
 4373    ) {
 4374        match event {
 4375            BufferStoreEvent::BufferAdded(buffer) => {
 4376                self.on_buffer_added(buffer, cx).log_err();
 4377            }
 4378            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4379                let buffer_id = buffer.read(cx).remote_id();
 4380                if let Some(local) = self.as_local_mut()
 4381                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4382                {
 4383                    local.reset_buffer(buffer, old_file, cx);
 4384
 4385                    if local.registered_buffers.contains_key(&buffer_id) {
 4386                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4387                    }
 4388                }
 4389
 4390                self.detect_language_for_buffer(buffer, cx);
 4391                if let Some(local) = self.as_local_mut() {
 4392                    local.initialize_buffer(buffer, cx);
 4393                    if local.registered_buffers.contains_key(&buffer_id) {
 4394                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4395                    }
 4396                }
 4397            }
 4398            _ => {}
 4399        }
 4400    }
 4401
 4402    fn on_worktree_store_event(
 4403        &mut self,
 4404        _: Entity<WorktreeStore>,
 4405        event: &WorktreeStoreEvent,
 4406        cx: &mut Context<Self>,
 4407    ) {
 4408        match event {
 4409            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4410                if !worktree.read(cx).is_local() {
 4411                    return;
 4412                }
 4413                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4414                    worktree::Event::UpdatedEntries(changes) => {
 4415                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4416                    }
 4417                    worktree::Event::UpdatedGitRepositories(_)
 4418                    | worktree::Event::DeletedEntry(_)
 4419                    | worktree::Event::Deleted
 4420                    | worktree::Event::UpdatedRootRepoCommonDir { .. } => {}
 4421                })
 4422                .detach()
 4423            }
 4424            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4425            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4426                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4427            }
 4428            WorktreeStoreEvent::WorktreeUpdatedEntries(worktree_id, changes) => {
 4429                self.invalidate_diagnostic_summaries_for_removed_entries(*worktree_id, changes, cx);
 4430            }
 4431            WorktreeStoreEvent::WorktreeReleased(..)
 4432            | WorktreeStoreEvent::WorktreeOrderChanged
 4433            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4434            | WorktreeStoreEvent::WorktreeDeletedEntry(..)
 4435            | WorktreeStoreEvent::WorktreeUpdatedRootRepoCommonDir(..) => {}
 4436        }
 4437    }
 4438
 4439    fn on_prettier_store_event(
 4440        &mut self,
 4441        _: Entity<PrettierStore>,
 4442        event: &PrettierStoreEvent,
 4443        cx: &mut Context<Self>,
 4444    ) {
 4445        match event {
 4446            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4447                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4448            }
 4449            PrettierStoreEvent::LanguageServerAdded {
 4450                new_server_id,
 4451                name,
 4452                prettier_server,
 4453            } => {
 4454                self.register_supplementary_language_server(
 4455                    *new_server_id,
 4456                    name.clone(),
 4457                    prettier_server.clone(),
 4458                    cx,
 4459                );
 4460            }
 4461        }
 4462    }
 4463
 4464    fn on_toolchain_store_event(
 4465        &mut self,
 4466        _: Entity<LocalToolchainStore>,
 4467        event: &ToolchainStoreEvent,
 4468        _: &mut Context<Self>,
 4469    ) {
 4470        if let ToolchainStoreEvent::ToolchainActivated = event {
 4471            self.request_workspace_config_refresh()
 4472        }
 4473    }
 4474
 4475    fn request_workspace_config_refresh(&mut self) {
 4476        *self._maintain_workspace_config.1.borrow_mut() = ();
 4477    }
 4478
 4479    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4480        self.as_local().map(|local| local.prettier_store.clone())
 4481    }
 4482
 4483    fn on_buffer_event(
 4484        &mut self,
 4485        buffer: Entity<Buffer>,
 4486        event: &language::BufferEvent,
 4487        cx: &mut Context<Self>,
 4488    ) {
 4489        match event {
 4490            language::BufferEvent::Edited { .. } => {
 4491                self.on_buffer_edited(buffer, cx);
 4492            }
 4493
 4494            language::BufferEvent::Saved => {
 4495                self.on_buffer_saved(buffer, cx);
 4496            }
 4497
 4498            language::BufferEvent::Reloaded => {
 4499                self.on_buffer_reloaded(buffer, cx);
 4500            }
 4501
 4502            _ => {}
 4503        }
 4504    }
 4505
 4506    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4507        buffer
 4508            .read(cx)
 4509            .set_language_registry(self.languages.clone());
 4510
 4511        cx.subscribe(buffer, |this, buffer, event, cx| {
 4512            this.on_buffer_event(buffer, event, cx);
 4513        })
 4514        .detach();
 4515
 4516        self.parse_modeline(buffer, cx);
 4517        self.detect_language_for_buffer(buffer, cx);
 4518        if let Some(local) = self.as_local_mut() {
 4519            local.initialize_buffer(buffer, cx);
 4520        }
 4521
 4522        Ok(())
 4523    }
 4524
 4525    pub fn refresh_background_diagnostics_for_buffers(
 4526        &mut self,
 4527        buffers: HashSet<BufferId>,
 4528        cx: &mut Context<Self>,
 4529    ) -> Shared<Task<()>> {
 4530        let Some(local) = self.as_local_mut() else {
 4531            return Task::ready(()).shared();
 4532        };
 4533        for buffer in buffers {
 4534            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4535                local.buffers_to_refresh_queue.push_back(buffer);
 4536                if local.buffers_to_refresh_queue.len() == 1 {
 4537                    local._background_diagnostics_worker =
 4538                        Self::background_diagnostics_worker(cx).shared();
 4539                }
 4540            }
 4541        }
 4542
 4543        local._background_diagnostics_worker.clone()
 4544    }
 4545
 4546    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4547        let buffer_store = self.buffer_store.clone();
 4548        let local = self.as_local_mut()?;
 4549        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4550            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4551            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4552                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4553            }
 4554        }
 4555        None
 4556    }
 4557
 4558    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4559        cx.spawn(async move |this, cx| {
 4560            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4561                task.await.log_err();
 4562            }
 4563        })
 4564    }
 4565
 4566    fn on_buffer_reloaded(&mut self, buffer: Entity<Buffer>, cx: &mut Context<Self>) {
 4567        if self.parse_modeline(&buffer, cx) {
 4568            self.detect_language_for_buffer(&buffer, cx);
 4569        }
 4570
 4571        let buffer_id = buffer.read(cx).remote_id();
 4572        let task = self.pull_diagnostics_for_buffer(buffer, cx);
 4573        self.buffer_reload_tasks.insert(buffer_id, task);
 4574    }
 4575
 4576    pub(crate) fn register_buffer_with_language_servers(
 4577        &mut self,
 4578        buffer: &Entity<Buffer>,
 4579        only_register_servers: HashSet<LanguageServerSelector>,
 4580        ignore_refcounts: bool,
 4581        cx: &mut Context<Self>,
 4582    ) -> OpenLspBufferHandle {
 4583        let buffer_id = buffer.read(cx).remote_id();
 4584        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4585        if let Some(local) = self.as_local_mut() {
 4586            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4587            if !ignore_refcounts {
 4588                *refcount += 1;
 4589            }
 4590
 4591            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4592            // 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
 4593            // 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
 4594            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4595            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4596                return handle;
 4597            };
 4598            if !file.is_local() {
 4599                return handle;
 4600            }
 4601
 4602            if ignore_refcounts || *refcount == 1 {
 4603                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4604            }
 4605            if !ignore_refcounts {
 4606                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4607                    let refcount = {
 4608                        let local = lsp_store.as_local_mut().unwrap();
 4609                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4610                            debug_panic!("bad refcounting");
 4611                            return;
 4612                        };
 4613
 4614                        *refcount -= 1;
 4615                        *refcount
 4616                    };
 4617                    if refcount == 0 {
 4618                        lsp_store.lsp_data.remove(&buffer_id);
 4619                        lsp_store.buffer_reload_tasks.remove(&buffer_id);
 4620                        let local = lsp_store.as_local_mut().unwrap();
 4621                        local.registered_buffers.remove(&buffer_id);
 4622
 4623                        local.buffers_opened_in_servers.remove(&buffer_id);
 4624                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4625                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4626
 4627                            let buffer_abs_path = file.abs_path(cx);
 4628                            for (_, buffer_pull_diagnostics_result_ids) in
 4629                                &mut local.buffer_pull_diagnostics_result_ids
 4630                            {
 4631                                buffer_pull_diagnostics_result_ids.retain(
 4632                                    |_, buffer_result_ids| {
 4633                                        buffer_result_ids.remove(&buffer_abs_path);
 4634                                        !buffer_result_ids.is_empty()
 4635                                    },
 4636                                );
 4637                            }
 4638
 4639                            let diagnostic_updates = local
 4640                                .language_servers
 4641                                .keys()
 4642                                .cloned()
 4643                                .map(|server_id| DocumentDiagnosticsUpdate {
 4644                                    diagnostics: DocumentDiagnostics {
 4645                                        document_abs_path: buffer_abs_path.clone(),
 4646                                        version: None,
 4647                                        diagnostics: Vec::new(),
 4648                                    },
 4649                                    result_id: None,
 4650                                    registration_id: None,
 4651                                    server_id,
 4652                                    disk_based_sources: Cow::Borrowed(&[]),
 4653                                })
 4654                                .collect::<Vec<_>>();
 4655
 4656                            lsp_store
 4657                                .merge_diagnostic_entries(
 4658                                    diagnostic_updates,
 4659                                    |_, diagnostic, _| {
 4660                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4661                                    },
 4662                                    cx,
 4663                                )
 4664                                .context("Clearing diagnostics for the closed buffer")
 4665                                .log_err();
 4666                        }
 4667                    }
 4668                })
 4669                .detach();
 4670            }
 4671        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4672            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4673            cx.background_spawn(async move {
 4674                upstream_client
 4675                    .request(proto::RegisterBufferWithLanguageServers {
 4676                        project_id: upstream_project_id,
 4677                        buffer_id,
 4678                        only_servers: only_register_servers
 4679                            .into_iter()
 4680                            .map(|selector| {
 4681                                let selector = match selector {
 4682                                    LanguageServerSelector::Id(language_server_id) => {
 4683                                        proto::language_server_selector::Selector::ServerId(
 4684                                            language_server_id.to_proto(),
 4685                                        )
 4686                                    }
 4687                                    LanguageServerSelector::Name(language_server_name) => {
 4688                                        proto::language_server_selector::Selector::Name(
 4689                                            language_server_name.to_string(),
 4690                                        )
 4691                                    }
 4692                                };
 4693                                proto::LanguageServerSelector {
 4694                                    selector: Some(selector),
 4695                                }
 4696                            })
 4697                            .collect(),
 4698                    })
 4699                    .await
 4700            })
 4701            .detach();
 4702        } else {
 4703            // Our remote connection got closed
 4704        }
 4705        handle
 4706    }
 4707
 4708    fn maintain_buffer_languages(
 4709        languages: Arc<LanguageRegistry>,
 4710        cx: &mut Context<Self>,
 4711    ) -> Task<()> {
 4712        let mut subscription = languages.subscribe();
 4713        let mut prev_reload_count = languages.reload_count();
 4714        cx.spawn(async move |this, cx| {
 4715            while let Some(()) = subscription.next().await {
 4716                if let Some(this) = this.upgrade() {
 4717                    // If the language registry has been reloaded, then remove and
 4718                    // re-assign the languages on all open buffers.
 4719                    let reload_count = languages.reload_count();
 4720                    if reload_count > prev_reload_count {
 4721                        prev_reload_count = reload_count;
 4722                        this.update(cx, |this, cx| {
 4723                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4724                                for buffer in buffer_store.buffers() {
 4725                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4726                                    {
 4727                                        buffer.update(cx, |buffer, cx| {
 4728                                            buffer.set_language_async(None, cx)
 4729                                        });
 4730                                        if let Some(local) = this.as_local_mut() {
 4731                                            local.reset_buffer(&buffer, &f, cx);
 4732
 4733                                            if local
 4734                                                .registered_buffers
 4735                                                .contains_key(&buffer.read(cx).remote_id())
 4736                                                && let Some(file_url) =
 4737                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4738                                            {
 4739                                                local.unregister_buffer_from_language_servers(
 4740                                                    &buffer, &file_url, cx,
 4741                                                );
 4742                                            }
 4743                                        }
 4744                                    }
 4745                                }
 4746                            });
 4747                        });
 4748                    }
 4749
 4750                    this.update(cx, |this, cx| {
 4751                        let mut plain_text_buffers = Vec::new();
 4752                        let mut buffers_with_unknown_injections = Vec::new();
 4753                        for handle in this.buffer_store.read(cx).buffers() {
 4754                            let buffer = handle.read(cx);
 4755                            if buffer.language().is_none()
 4756                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4757                            {
 4758                                plain_text_buffers.push(handle);
 4759                            } else if buffer.contains_unknown_injections() {
 4760                                buffers_with_unknown_injections.push(handle);
 4761                            }
 4762                        }
 4763
 4764                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4765                        // and reused later in the invisible worktrees.
 4766                        plain_text_buffers.sort_by_key(|buffer| {
 4767                            Reverse(
 4768                                File::from_dyn(buffer.read(cx).file())
 4769                                    .map(|file| file.worktree.read(cx).is_visible()),
 4770                            )
 4771                        });
 4772
 4773                        for buffer in plain_text_buffers {
 4774                            this.detect_language_for_buffer(&buffer, cx);
 4775                            if let Some(local) = this.as_local_mut() {
 4776                                local.initialize_buffer(&buffer, cx);
 4777                                if local
 4778                                    .registered_buffers
 4779                                    .contains_key(&buffer.read(cx).remote_id())
 4780                                {
 4781                                    local.register_buffer_with_language_servers(
 4782                                        &buffer,
 4783                                        HashSet::default(),
 4784                                        cx,
 4785                                    );
 4786                                }
 4787                            }
 4788                        }
 4789
 4790                        for buffer in buffers_with_unknown_injections {
 4791                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4792                        }
 4793                    });
 4794                }
 4795            }
 4796        })
 4797    }
 4798
 4799    fn parse_modeline(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<Self>) -> bool {
 4800        let buffer = buffer_handle.read(cx);
 4801        let content = buffer.as_rope();
 4802
 4803        let modeline_settings = {
 4804            let settings_store = cx.global::<SettingsStore>();
 4805            let modeline_lines = settings_store
 4806                .raw_user_settings()
 4807                .and_then(|s| s.content.modeline_lines)
 4808                .or(settings_store.raw_default_settings().modeline_lines)
 4809                .unwrap_or(5);
 4810
 4811            const MAX_MODELINE_BYTES: usize = 1024;
 4812
 4813            let first_bytes =
 4814                content.clip_offset(content.len().min(MAX_MODELINE_BYTES), Bias::Left);
 4815            let mut first_lines = Vec::new();
 4816            let mut lines = content.chunks_in_range(0..first_bytes).lines();
 4817            for _ in 0..modeline_lines {
 4818                if let Some(line) = lines.next() {
 4819                    first_lines.push(line.to_string());
 4820                } else {
 4821                    break;
 4822                }
 4823            }
 4824            let first_lines_ref: Vec<_> = first_lines.iter().map(|line| line.as_str()).collect();
 4825
 4826            let last_start =
 4827                content.clip_offset(content.len().saturating_sub(MAX_MODELINE_BYTES), Bias::Left);
 4828            let mut last_lines = Vec::new();
 4829            let mut lines = content
 4830                .reversed_chunks_in_range(last_start..content.len())
 4831                .lines();
 4832            for _ in 0..modeline_lines {
 4833                if let Some(line) = lines.next() {
 4834                    last_lines.push(line.to_string());
 4835                } else {
 4836                    break;
 4837                }
 4838            }
 4839            let last_lines_ref: Vec<_> =
 4840                last_lines.iter().rev().map(|line| line.as_str()).collect();
 4841            modeline::parse_modeline(&first_lines_ref, &last_lines_ref)
 4842        };
 4843
 4844        log::debug!("Parsed modeline settings: {:?}", modeline_settings);
 4845
 4846        buffer_handle.update(cx, |buffer, _cx| buffer.set_modeline(modeline_settings))
 4847    }
 4848
 4849    fn detect_language_for_buffer(
 4850        &mut self,
 4851        buffer_handle: &Entity<Buffer>,
 4852        cx: &mut Context<Self>,
 4853    ) -> Option<language::AvailableLanguage> {
 4854        // If the buffer has a language, set it and start the language server if we haven't already.
 4855        let buffer = buffer_handle.read(cx);
 4856        let file = buffer.file()?;
 4857        let content = buffer.as_rope();
 4858        let modeline_settings = buffer.modeline().map(Arc::as_ref);
 4859
 4860        let available_language = if let Some(ModelineSettings {
 4861            mode: Some(mode_name),
 4862            ..
 4863        }) = modeline_settings
 4864        {
 4865            self.languages
 4866                .available_language_for_modeline_name(mode_name)
 4867        } else {
 4868            self.languages.language_for_file(file, Some(content), cx)
 4869        };
 4870        if let Some(available_language) = &available_language {
 4871            if let Some(Ok(Ok(new_language))) = self
 4872                .languages
 4873                .load_language(available_language)
 4874                .now_or_never()
 4875            {
 4876                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4877            }
 4878        } else {
 4879            cx.emit(LspStoreEvent::LanguageDetected {
 4880                buffer: buffer_handle.clone(),
 4881                new_language: None,
 4882            });
 4883        }
 4884
 4885        available_language
 4886    }
 4887
 4888    pub(crate) fn set_language_for_buffer(
 4889        &mut self,
 4890        buffer_entity: &Entity<Buffer>,
 4891        new_language: Arc<Language>,
 4892        cx: &mut Context<Self>,
 4893    ) {
 4894        let buffer = buffer_entity.read(cx);
 4895        let buffer_file = buffer.file().cloned();
 4896        let buffer_id = buffer.remote_id();
 4897        if let Some(local_store) = self.as_local_mut()
 4898            && local_store.registered_buffers.contains_key(&buffer_id)
 4899            && let Some(abs_path) =
 4900                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4901            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4902        {
 4903            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4904        }
 4905        buffer_entity.update(cx, |buffer, cx| {
 4906            if buffer
 4907                .language()
 4908                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4909            {
 4910                buffer.set_language_async(Some(new_language.clone()), cx);
 4911            }
 4912        });
 4913
 4914        let settings = LanguageSettings::resolve(
 4915            Some(&buffer_entity.read(cx)),
 4916            Some(&new_language.name()),
 4917            cx,
 4918        )
 4919        .into_owned();
 4920        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4921
 4922        let worktree_id = if let Some(file) = buffer_file {
 4923            let worktree = file.worktree.clone();
 4924
 4925            if let Some(local) = self.as_local_mut()
 4926                && local.registered_buffers.contains_key(&buffer_id)
 4927            {
 4928                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4929            }
 4930            Some(worktree.read(cx).id())
 4931        } else {
 4932            None
 4933        };
 4934
 4935        if settings.prettier.allowed
 4936            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4937        {
 4938            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4939            if let Some(prettier_store) = prettier_store {
 4940                prettier_store.update(cx, |prettier_store, cx| {
 4941                    prettier_store.install_default_prettier(
 4942                        worktree_id,
 4943                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4944                        cx,
 4945                    )
 4946                })
 4947            }
 4948        }
 4949
 4950        cx.emit(LspStoreEvent::LanguageDetected {
 4951            buffer: buffer_entity.clone(),
 4952            new_language: Some(new_language),
 4953        })
 4954    }
 4955
 4956    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4957        self.buffer_store.clone()
 4958    }
 4959
 4960    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4961        self.active_entry = active_entry;
 4962    }
 4963
 4964    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4965        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4966            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4967        {
 4968            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4969                summaries
 4970                    .iter()
 4971                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4972            });
 4973            if let Some(summary) = summaries.next() {
 4974                client
 4975                    .send(proto::UpdateDiagnosticSummary {
 4976                        project_id: downstream_project_id,
 4977                        worktree_id: worktree.id().to_proto(),
 4978                        summary: Some(summary),
 4979                        more_summaries: summaries.collect(),
 4980                    })
 4981                    .log_err();
 4982            }
 4983        }
 4984    }
 4985
 4986    fn is_capable_for_proto_request<R>(
 4987        &self,
 4988        buffer: &Entity<Buffer>,
 4989        request: &R,
 4990        cx: &App,
 4991    ) -> bool
 4992    where
 4993        R: LspCommand,
 4994    {
 4995        self.check_if_capable_for_proto_request(
 4996            buffer,
 4997            |capabilities| {
 4998                request.check_capabilities(AdapterServerCapabilities {
 4999                    server_capabilities: capabilities.clone(),
 5000                    code_action_kinds: None,
 5001                })
 5002            },
 5003            cx,
 5004        )
 5005    }
 5006
 5007    fn check_if_capable_for_proto_request<F>(
 5008        &self,
 5009        buffer: &Entity<Buffer>,
 5010        check: F,
 5011        cx: &App,
 5012    ) -> bool
 5013    where
 5014        F: FnMut(&lsp::ServerCapabilities) -> bool,
 5015    {
 5016        let Some(language) = buffer.read(cx).language().cloned() else {
 5017            return false;
 5018        };
 5019        let registered_language_servers = self
 5020            .languages
 5021            .lsp_adapters(&language.name())
 5022            .into_iter()
 5023            .map(|lsp_adapter| lsp_adapter.name())
 5024            .collect::<HashSet<_>>();
 5025        self.language_server_statuses
 5026            .iter()
 5027            .filter_map(|(server_id, server_status)| {
 5028                // Include servers that are either registered for this language OR
 5029                // available to be loaded (for SSH remote mode where adapters like
 5030                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 5031                // but only loaded on the server side)
 5032                let is_relevant = registered_language_servers.contains(&server_status.name)
 5033                    || self.languages.is_lsp_adapter_available(&server_status.name);
 5034                is_relevant.then_some(server_id)
 5035            })
 5036            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 5037            .any(check)
 5038    }
 5039
 5040    fn all_capable_for_proto_request<F>(
 5041        &self,
 5042        buffer: &Entity<Buffer>,
 5043        mut check: F,
 5044        cx: &App,
 5045    ) -> Vec<(lsp::LanguageServerId, lsp::LanguageServerName)>
 5046    where
 5047        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 5048    {
 5049        let Some(language) = buffer.read(cx).language().cloned() else {
 5050            return Vec::default();
 5051        };
 5052        let registered_language_servers = self
 5053            .languages
 5054            .lsp_adapters(&language.name())
 5055            .into_iter()
 5056            .map(|lsp_adapter| lsp_adapter.name())
 5057            .collect::<HashSet<_>>();
 5058        self.language_server_statuses
 5059            .iter()
 5060            .filter_map(|(server_id, server_status)| {
 5061                // Include servers that are either registered for this language OR
 5062                // available to be loaded (for SSH remote mode where adapters like
 5063                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 5064                // but only loaded on the server side)
 5065                let is_relevant = registered_language_servers.contains(&server_status.name)
 5066                    || self.languages.is_lsp_adapter_available(&server_status.name);
 5067                is_relevant.then_some((server_id, &server_status.name))
 5068            })
 5069            .filter_map(|(server_id, server_name)| {
 5070                self.lsp_server_capabilities
 5071                    .get(server_id)
 5072                    .map(|c| (server_id, server_name, c))
 5073            })
 5074            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 5075            .map(|(server_id, server_name, _)| (*server_id, server_name.clone()))
 5076            .collect()
 5077    }
 5078
 5079    pub fn request_lsp<R>(
 5080        &mut self,
 5081        buffer: Entity<Buffer>,
 5082        server: LanguageServerToQuery,
 5083        request: R,
 5084        cx: &mut Context<Self>,
 5085    ) -> Task<Result<R::Response>>
 5086    where
 5087        R: LspCommand,
 5088        <R::LspRequest as lsp::request::Request>::Result: Send,
 5089        <R::LspRequest as lsp::request::Request>::Params: Send,
 5090    {
 5091        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 5092            return self.send_lsp_proto_request(
 5093                buffer,
 5094                upstream_client,
 5095                upstream_project_id,
 5096                request,
 5097                cx,
 5098            );
 5099        }
 5100
 5101        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 5102            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 5103                local
 5104                    .language_servers_for_buffer(buffer, cx)
 5105                    .find(|(_, server)| {
 5106                        request.check_capabilities(server.adapter_server_capabilities())
 5107                    })
 5108                    .map(|(_, server)| server.clone())
 5109            }),
 5110            LanguageServerToQuery::Other(id) => self
 5111                .language_server_for_local_buffer(buffer, id, cx)
 5112                .and_then(|(_, server)| {
 5113                    request
 5114                        .check_capabilities(server.adapter_server_capabilities())
 5115                        .then(|| Arc::clone(server))
 5116                }),
 5117        }) else {
 5118            return Task::ready(Ok(Default::default()));
 5119        };
 5120
 5121        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 5122
 5123        let Some(file) = file else {
 5124            return Task::ready(Ok(Default::default()));
 5125        };
 5126
 5127        let lsp_params = match request.to_lsp_params_or_response(
 5128            &file.abs_path(cx),
 5129            buffer.read(cx),
 5130            &language_server,
 5131            cx,
 5132        ) {
 5133            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 5134            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 5135            Err(err) => {
 5136                let message = format!(
 5137                    "{} via {} failed: {}",
 5138                    request.display_name(),
 5139                    language_server.name(),
 5140                    err
 5141                );
 5142                // rust-analyzer likes to error with this when its still loading up
 5143                if !message.ends_with("content modified") {
 5144                    log::warn!("{message}");
 5145                }
 5146                return Task::ready(Err(anyhow!(message)));
 5147            }
 5148        };
 5149
 5150        let status = request.status();
 5151        let request_timeout = ProjectSettings::get_global(cx)
 5152            .global_lsp_settings
 5153            .get_request_timeout();
 5154
 5155        cx.spawn(async move |this, cx| {
 5156            let lsp_request = language_server.request::<R::LspRequest>(lsp_params, request_timeout);
 5157
 5158            let id = lsp_request.id();
 5159            let _cleanup = if status.is_some() {
 5160                cx.update(|cx| {
 5161                    this.update(cx, |this, cx| {
 5162                        this.on_lsp_work_start(
 5163                            language_server.server_id(),
 5164                            ProgressToken::Number(id),
 5165                            LanguageServerProgress {
 5166                                is_disk_based_diagnostics_progress: false,
 5167                                is_cancellable: false,
 5168                                title: None,
 5169                                message: status.clone(),
 5170                                percentage: None,
 5171                                last_update_at: cx.background_executor().now(),
 5172                            },
 5173                            cx,
 5174                        );
 5175                    })
 5176                })
 5177                .log_err();
 5178
 5179                Some(defer(|| {
 5180                    cx.update(|cx| {
 5181                        this.update(cx, |this, cx| {
 5182                            this.on_lsp_work_end(
 5183                                language_server.server_id(),
 5184                                ProgressToken::Number(id),
 5185                                cx,
 5186                            );
 5187                        })
 5188                    })
 5189                    .log_err();
 5190                }))
 5191            } else {
 5192                None
 5193            };
 5194
 5195            let result = lsp_request.await.into_response();
 5196
 5197            let response = result.map_err(|err| {
 5198                let message = format!(
 5199                    "{} via {} failed: {}",
 5200                    request.display_name(),
 5201                    language_server.name(),
 5202                    err
 5203                );
 5204                // rust-analyzer likes to error with this when its still loading up
 5205                if !message.ends_with("content modified") {
 5206                    log::warn!("{message}");
 5207                }
 5208                anyhow::anyhow!(message)
 5209            })?;
 5210
 5211            request
 5212                .response_from_lsp(
 5213                    response,
 5214                    this.upgrade().context("no app context")?,
 5215                    buffer,
 5216                    language_server.server_id(),
 5217                    cx.clone(),
 5218                )
 5219                .await
 5220        })
 5221    }
 5222
 5223    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 5224        let mut language_formatters_to_check = Vec::new();
 5225        for buffer in self.buffer_store.read(cx).buffers() {
 5226            let buffer = buffer.read(cx);
 5227            let settings = LanguageSettings::for_buffer(buffer, cx);
 5228            if buffer.language().is_some() {
 5229                let buffer_file = File::from_dyn(buffer.file());
 5230                language_formatters_to_check.push((
 5231                    buffer_file.map(|f| f.worktree_id(cx)),
 5232                    settings.into_owned(),
 5233                ));
 5234            }
 5235        }
 5236
 5237        self.request_workspace_config_refresh();
 5238
 5239        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 5240            prettier_store.update(cx, |prettier_store, cx| {
 5241                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 5242            })
 5243        }
 5244
 5245        let new_semantic_token_rules = crate::project_settings::ProjectSettings::get_global(cx)
 5246            .global_lsp_settings
 5247            .semantic_token_rules
 5248            .clone();
 5249        self.semantic_token_config
 5250            .update_rules(new_semantic_token_rules);
 5251        // Always clear cached stylizers so that changes to language-specific
 5252        // semantic token rules (e.g. from extension install/uninstall) are
 5253        // picked up. Stylizers are recreated lazily, so this is cheap.
 5254        self.semantic_token_config.clear_stylizers();
 5255
 5256        let new_global_semantic_tokens_mode =
 5257            all_language_settings(None, cx).defaults.semantic_tokens;
 5258        if self
 5259            .semantic_token_config
 5260            .update_global_mode(new_global_semantic_tokens_mode)
 5261        {
 5262            self.restart_all_language_servers(cx);
 5263        }
 5264
 5265        cx.notify();
 5266    }
 5267
 5268    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 5269        let buffer_store = self.buffer_store.clone();
 5270        let Some(local) = self.as_local_mut() else {
 5271            return;
 5272        };
 5273        let mut adapters = BTreeMap::default();
 5274        let get_adapter = {
 5275            let languages = local.languages.clone();
 5276            let environment = local.environment.clone();
 5277            let weak = local.weak.clone();
 5278            let worktree_store = local.worktree_store.clone();
 5279            let http_client = local.http_client.clone();
 5280            let fs = local.fs.clone();
 5281            move |worktree_id, cx: &mut App| {
 5282                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 5283                Some(LocalLspAdapterDelegate::new(
 5284                    languages.clone(),
 5285                    &environment,
 5286                    weak.clone(),
 5287                    &worktree,
 5288                    http_client.clone(),
 5289                    fs.clone(),
 5290                    cx,
 5291                ))
 5292            }
 5293        };
 5294
 5295        let mut messages_to_report = Vec::new();
 5296        let (new_tree, to_stop) = {
 5297            let mut rebase = local.lsp_tree.rebase();
 5298            let buffers = buffer_store
 5299                .read(cx)
 5300                .buffers()
 5301                .filter_map(|buffer| {
 5302                    let raw_buffer = buffer.read(cx);
 5303                    if !local
 5304                        .registered_buffers
 5305                        .contains_key(&raw_buffer.remote_id())
 5306                    {
 5307                        return None;
 5308                    }
 5309                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5310                    let language = raw_buffer.language().cloned()?;
 5311                    Some((file, language, raw_buffer.remote_id()))
 5312                })
 5313                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5314            for (file, language, buffer_id) in buffers {
 5315                let worktree_id = file.worktree_id(cx);
 5316                let Some(worktree) = local
 5317                    .worktree_store
 5318                    .read(cx)
 5319                    .worktree_for_id(worktree_id, cx)
 5320                else {
 5321                    continue;
 5322                };
 5323
 5324                if let Some((_, apply)) = local.reuse_existing_language_server(
 5325                    rebase.server_tree(),
 5326                    &worktree,
 5327                    &language.name(),
 5328                    cx,
 5329                ) {
 5330                    (apply)(rebase.server_tree());
 5331                } else if let Some(lsp_delegate) = adapters
 5332                    .entry(worktree_id)
 5333                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5334                    .clone()
 5335                {
 5336                    let delegate =
 5337                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5338                    let path = file
 5339                        .path()
 5340                        .parent()
 5341                        .map(Arc::from)
 5342                        .unwrap_or_else(|| file.path().clone());
 5343                    let worktree_path = ProjectPath { worktree_id, path };
 5344                    let abs_path = file.abs_path(cx);
 5345                    let nodes = rebase
 5346                        .walk(
 5347                            worktree_path,
 5348                            language.name(),
 5349                            language.manifest(),
 5350                            delegate.clone(),
 5351                            cx,
 5352                        )
 5353                        .collect::<Vec<_>>();
 5354                    for node in nodes {
 5355                        let server_id = node.server_id_or_init(|disposition| {
 5356                            let path = &disposition.path;
 5357                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5358                            let key = LanguageServerSeed {
 5359                                worktree_id,
 5360                                name: disposition.server_name.clone(),
 5361                                settings: LanguageServerSeedSettings {
 5362                                    binary: disposition.settings.binary.clone(),
 5363                                    initialization_options: disposition
 5364                                        .settings
 5365                                        .initialization_options
 5366                                        .clone(),
 5367                                },
 5368                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5369                                    path.worktree_id,
 5370                                    &path.path,
 5371                                    language.name(),
 5372                                ),
 5373                            };
 5374                            local.language_server_ids.remove(&key);
 5375
 5376                            let server_id = local.get_or_insert_language_server(
 5377                                &worktree,
 5378                                lsp_delegate.clone(),
 5379                                disposition,
 5380                                &language.name(),
 5381                                cx,
 5382                            );
 5383                            if let Some(state) = local.language_servers.get(&server_id)
 5384                                && let Ok(uri) = uri
 5385                            {
 5386                                state.add_workspace_folder(uri);
 5387                            };
 5388                            server_id
 5389                        });
 5390
 5391                        if let Some(language_server_id) = server_id {
 5392                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5393                                language_server_id,
 5394                                name: node.name(),
 5395                                message:
 5396                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5397                                        proto::RegisteredForBuffer {
 5398                                            buffer_abs_path: abs_path
 5399                                                .to_string_lossy()
 5400                                                .into_owned(),
 5401                                            buffer_id: buffer_id.to_proto(),
 5402                                        },
 5403                                    ),
 5404                            });
 5405                        }
 5406                    }
 5407                } else {
 5408                    continue;
 5409                }
 5410            }
 5411            rebase.finish()
 5412        };
 5413        for message in messages_to_report {
 5414            cx.emit(message);
 5415        }
 5416        local.lsp_tree = new_tree;
 5417        for (id, _) in to_stop {
 5418            self.stop_local_language_server(id, cx).detach();
 5419        }
 5420    }
 5421
 5422    pub fn apply_code_action(
 5423        &self,
 5424        buffer_handle: Entity<Buffer>,
 5425        mut action: CodeAction,
 5426        push_to_history: bool,
 5427        cx: &mut Context<Self>,
 5428    ) -> Task<Result<ProjectTransaction>> {
 5429        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5430            let request = proto::ApplyCodeAction {
 5431                project_id,
 5432                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5433                action: Some(Self::serialize_code_action(&action)),
 5434            };
 5435            let buffer_store = self.buffer_store();
 5436            cx.spawn(async move |_, cx| {
 5437                let response = upstream_client
 5438                    .request(request)
 5439                    .await?
 5440                    .transaction
 5441                    .context("missing transaction")?;
 5442
 5443                buffer_store
 5444                    .update(cx, |buffer_store, cx| {
 5445                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5446                    })
 5447                    .await
 5448            })
 5449        } else if self.mode.is_local() {
 5450            let Some((_, lang_server, request_timeout)) = buffer_handle.update(cx, |buffer, cx| {
 5451                let request_timeout = ProjectSettings::get_global(cx)
 5452                    .global_lsp_settings
 5453                    .get_request_timeout();
 5454                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5455                    .map(|(adapter, server)| (adapter.clone(), server.clone(), request_timeout))
 5456            }) else {
 5457                return Task::ready(Ok(ProjectTransaction::default()));
 5458            };
 5459
 5460            cx.spawn(async move |this, cx| {
 5461                LocalLspStore::try_resolve_code_action(&lang_server, &mut action, request_timeout)
 5462                    .await
 5463                    .context("resolving a code action")?;
 5464                if let Some(edit) = action.lsp_action.edit()
 5465                    && (edit.changes.is_some() || edit.document_changes.is_some())
 5466                {
 5467                    return LocalLspStore::deserialize_workspace_edit(
 5468                        this.upgrade().context("no app present")?,
 5469                        edit.clone(),
 5470                        push_to_history,
 5471                        lang_server.clone(),
 5472                        cx,
 5473                    )
 5474                    .await;
 5475                }
 5476
 5477                let Some(command) = action.lsp_action.command() else {
 5478                    return Ok(ProjectTransaction::default());
 5479                };
 5480
 5481                let server_capabilities = lang_server.capabilities();
 5482                let available_commands = server_capabilities
 5483                    .execute_command_provider
 5484                    .as_ref()
 5485                    .map(|options| options.commands.as_slice())
 5486                    .unwrap_or_default();
 5487
 5488                if !available_commands.contains(&command.command) {
 5489                    log::warn!(
 5490                        "Executing command {} not listed in the language server capabilities",
 5491                        command.command
 5492                    );
 5493                }
 5494
 5495                let request_timeout = cx.update(|app| {
 5496                    ProjectSettings::get_global(app)
 5497                        .global_lsp_settings
 5498                        .get_request_timeout()
 5499                });
 5500
 5501                this.update(cx, |this, _| {
 5502                    this.as_local_mut()
 5503                        .unwrap()
 5504                        .last_workspace_edits_by_language_server
 5505                        .remove(&lang_server.server_id());
 5506                })?;
 5507
 5508                let _result = lang_server
 5509                    .request::<lsp::request::ExecuteCommand>(
 5510                        lsp::ExecuteCommandParams {
 5511                            command: command.command.clone(),
 5512                            arguments: command.arguments.clone().unwrap_or_default(),
 5513                            ..lsp::ExecuteCommandParams::default()
 5514                        },
 5515                        request_timeout,
 5516                    )
 5517                    .await
 5518                    .into_response()
 5519                    .context("execute command")?;
 5520
 5521                return this.update(cx, |this, _| {
 5522                    this.as_local_mut()
 5523                        .unwrap()
 5524                        .last_workspace_edits_by_language_server
 5525                        .remove(&lang_server.server_id())
 5526                        .unwrap_or_default()
 5527                });
 5528            })
 5529        } else {
 5530            Task::ready(Err(anyhow!("no upstream client and not local")))
 5531        }
 5532    }
 5533
 5534    pub fn apply_code_action_kind(
 5535        &mut self,
 5536        buffers: HashSet<Entity<Buffer>>,
 5537        kind: CodeActionKind,
 5538        push_to_history: bool,
 5539        cx: &mut Context<Self>,
 5540    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5541        if self.as_local().is_some() {
 5542            cx.spawn(async move |lsp_store, cx| {
 5543                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5544                let result = LocalLspStore::execute_code_action_kind_locally(
 5545                    lsp_store.clone(),
 5546                    buffers,
 5547                    kind,
 5548                    push_to_history,
 5549                    cx,
 5550                )
 5551                .await;
 5552                lsp_store.update(cx, |lsp_store, _| {
 5553                    lsp_store.update_last_formatting_failure(&result);
 5554                })?;
 5555                result
 5556            })
 5557        } else if let Some((client, project_id)) = self.upstream_client() {
 5558            let buffer_store = self.buffer_store();
 5559            cx.spawn(async move |lsp_store, cx| {
 5560                let result = client
 5561                    .request(proto::ApplyCodeActionKind {
 5562                        project_id,
 5563                        kind: kind.as_str().to_owned(),
 5564                        buffer_ids: buffers
 5565                            .iter()
 5566                            .map(|buffer| {
 5567                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5568                            })
 5569                            .collect(),
 5570                    })
 5571                    .await
 5572                    .and_then(|result| result.transaction.context("missing transaction"));
 5573                lsp_store.update(cx, |lsp_store, _| {
 5574                    lsp_store.update_last_formatting_failure(&result);
 5575                })?;
 5576
 5577                let transaction_response = result?;
 5578                buffer_store
 5579                    .update(cx, |buffer_store, cx| {
 5580                        buffer_store.deserialize_project_transaction(
 5581                            transaction_response,
 5582                            push_to_history,
 5583                            cx,
 5584                        )
 5585                    })
 5586                    .await
 5587            })
 5588        } else {
 5589            Task::ready(Ok(ProjectTransaction::default()))
 5590        }
 5591    }
 5592
 5593    pub fn resolved_hint(
 5594        &mut self,
 5595        buffer_id: BufferId,
 5596        id: InlayId,
 5597        cx: &mut Context<Self>,
 5598    ) -> Option<ResolvedHint> {
 5599        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5600
 5601        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5602        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5603        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5604        let (server_id, resolve_data) = match &hint.resolve_state {
 5605            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5606            ResolveState::Resolving => {
 5607                return Some(ResolvedHint::Resolving(
 5608                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5609                ));
 5610            }
 5611            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5612        };
 5613
 5614        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5615        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5616        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5617            id,
 5618            cx.spawn(async move |lsp_store, cx| {
 5619                let resolved_hint = resolve_task.await;
 5620                lsp_store
 5621                    .update(cx, |lsp_store, _| {
 5622                        if let Some(old_inlay_hint) = lsp_store
 5623                            .lsp_data
 5624                            .get_mut(&buffer_id)
 5625                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5626                        {
 5627                            match resolved_hint {
 5628                                Ok(resolved_hint) => {
 5629                                    *old_inlay_hint = resolved_hint;
 5630                                }
 5631                                Err(e) => {
 5632                                    old_inlay_hint.resolve_state =
 5633                                        ResolveState::CanResolve(server_id, resolve_data);
 5634                                    log::error!("Inlay hint resolve failed: {e:#}");
 5635                                }
 5636                            }
 5637                        }
 5638                    })
 5639                    .ok();
 5640            })
 5641            .shared(),
 5642        );
 5643        debug_assert!(
 5644            previous_task.is_none(),
 5645            "Did not change hint's resolve state after spawning its resolve"
 5646        );
 5647        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5648        None
 5649    }
 5650
 5651    pub(crate) fn linked_edits(
 5652        &mut self,
 5653        buffer: &Entity<Buffer>,
 5654        position: Anchor,
 5655        cx: &mut Context<Self>,
 5656    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5657        let snapshot = buffer.read(cx).snapshot();
 5658        let scope = snapshot.language_scope_at(position);
 5659        let Some(server_id) = self
 5660            .as_local()
 5661            .and_then(|local| {
 5662                buffer.update(cx, |buffer, cx| {
 5663                    local
 5664                        .language_servers_for_buffer(buffer, cx)
 5665                        .filter(|(_, server)| {
 5666                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5667                        })
 5668                        .filter(|(adapter, _)| {
 5669                            scope
 5670                                .as_ref()
 5671                                .map(|scope| scope.language_allowed(&adapter.name))
 5672                                .unwrap_or(true)
 5673                        })
 5674                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5675                        .next()
 5676                })
 5677            })
 5678            .or_else(|| {
 5679                self.upstream_client()
 5680                    .is_some()
 5681                    .then_some(LanguageServerToQuery::FirstCapable)
 5682            })
 5683            .filter(|_| {
 5684                maybe!({
 5685                    buffer.read(cx).language_at(position)?;
 5686                    Some(
 5687                        LanguageSettings::for_buffer_at(&buffer.read(cx), position, cx)
 5688                            .linked_edits,
 5689                    )
 5690                }) == Some(true)
 5691            })
 5692        else {
 5693            return Task::ready(Ok(Vec::new()));
 5694        };
 5695
 5696        self.request_lsp(
 5697            buffer.clone(),
 5698            server_id,
 5699            LinkedEditingRange { position },
 5700            cx,
 5701        )
 5702    }
 5703
 5704    fn apply_on_type_formatting(
 5705        &mut self,
 5706        buffer: Entity<Buffer>,
 5707        position: Anchor,
 5708        trigger: String,
 5709        cx: &mut Context<Self>,
 5710    ) -> Task<Result<Option<Transaction>>> {
 5711        if let Some((client, project_id)) = self.upstream_client() {
 5712            if !self.check_if_capable_for_proto_request(
 5713                &buffer,
 5714                |capabilities| {
 5715                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5716                },
 5717                cx,
 5718            ) {
 5719                return Task::ready(Ok(None));
 5720            }
 5721            let request = proto::OnTypeFormatting {
 5722                project_id,
 5723                buffer_id: buffer.read(cx).remote_id().into(),
 5724                position: Some(serialize_anchor(&position)),
 5725                trigger,
 5726                version: serialize_version(&buffer.read(cx).version()),
 5727            };
 5728            cx.background_spawn(async move {
 5729                client
 5730                    .request(request)
 5731                    .await?
 5732                    .transaction
 5733                    .map(language::proto::deserialize_transaction)
 5734                    .transpose()
 5735            })
 5736        } else if let Some(local) = self.as_local_mut() {
 5737            let buffer_id = buffer.read(cx).remote_id();
 5738            local.buffers_being_formatted.insert(buffer_id);
 5739            cx.spawn(async move |this, cx| {
 5740                let _cleanup = defer({
 5741                    let this = this.clone();
 5742                    let mut cx = cx.clone();
 5743                    move || {
 5744                        this.update(&mut cx, |this, _| {
 5745                            if let Some(local) = this.as_local_mut() {
 5746                                local.buffers_being_formatted.remove(&buffer_id);
 5747                            }
 5748                        })
 5749                        .ok();
 5750                    }
 5751                });
 5752
 5753                buffer
 5754                    .update(cx, |buffer, _| {
 5755                        buffer.wait_for_edits(Some(position.timestamp()))
 5756                    })
 5757                    .await?;
 5758                this.update(cx, |this, cx| {
 5759                    let position = position.to_point_utf16(buffer.read(cx));
 5760                    this.on_type_format(buffer, position, trigger, false, cx)
 5761                })?
 5762                .await
 5763            })
 5764        } else {
 5765            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5766        }
 5767    }
 5768
 5769    pub fn on_type_format<T: ToPointUtf16>(
 5770        &mut self,
 5771        buffer: Entity<Buffer>,
 5772        position: T,
 5773        trigger: String,
 5774        push_to_history: bool,
 5775        cx: &mut Context<Self>,
 5776    ) -> Task<Result<Option<Transaction>>> {
 5777        let position = position.to_point_utf16(buffer.read(cx));
 5778        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5779    }
 5780
 5781    fn on_type_format_impl(
 5782        &mut self,
 5783        buffer: Entity<Buffer>,
 5784        position: PointUtf16,
 5785        trigger: String,
 5786        push_to_history: bool,
 5787        cx: &mut Context<Self>,
 5788    ) -> Task<Result<Option<Transaction>>> {
 5789        let options = buffer.update(cx, |buffer, cx| {
 5790            lsp_command::lsp_formatting_options(
 5791                LanguageSettings::for_buffer_at(buffer, position, cx).as_ref(),
 5792            )
 5793        });
 5794
 5795        cx.spawn(async move |this, cx| {
 5796            if let Some(waiter) =
 5797                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5798            {
 5799                waiter.await?;
 5800            }
 5801            cx.update(|cx| {
 5802                this.update(cx, |this, cx| {
 5803                    this.request_lsp(
 5804                        buffer.clone(),
 5805                        LanguageServerToQuery::FirstCapable,
 5806                        OnTypeFormatting {
 5807                            position,
 5808                            trigger,
 5809                            options,
 5810                            push_to_history,
 5811                        },
 5812                        cx,
 5813                    )
 5814                })
 5815            })?
 5816            .await
 5817        })
 5818    }
 5819
 5820    pub fn definitions(
 5821        &mut self,
 5822        buffer: &Entity<Buffer>,
 5823        position: PointUtf16,
 5824        cx: &mut Context<Self>,
 5825    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5826        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5827            let request = GetDefinitions { position };
 5828            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5829                return Task::ready(Ok(None));
 5830            }
 5831
 5832            let request_timeout = ProjectSettings::get_global(cx)
 5833                .global_lsp_settings
 5834                .get_request_timeout();
 5835
 5836            let request_task = upstream_client.request_lsp(
 5837                project_id,
 5838                None,
 5839                request_timeout,
 5840                cx.background_executor().clone(),
 5841                request.to_proto(project_id, buffer.read(cx)),
 5842            );
 5843            let buffer = buffer.clone();
 5844            cx.spawn(async move |weak_lsp_store, cx| {
 5845                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5846                    return Ok(None);
 5847                };
 5848                let Some(responses) = request_task.await? else {
 5849                    return Ok(None);
 5850                };
 5851                let actions = join_all(responses.payload.into_iter().map(|response| {
 5852                    GetDefinitions { position }.response_from_proto(
 5853                        response.response,
 5854                        lsp_store.clone(),
 5855                        buffer.clone(),
 5856                        cx.clone(),
 5857                    )
 5858                }))
 5859                .await;
 5860
 5861                Ok(Some(
 5862                    actions
 5863                        .into_iter()
 5864                        .collect::<Result<Vec<Vec<_>>>>()?
 5865                        .into_iter()
 5866                        .flatten()
 5867                        .dedup()
 5868                        .collect(),
 5869                ))
 5870            })
 5871        } else {
 5872            let definitions_task = self.request_multiple_lsp_locally(
 5873                buffer,
 5874                Some(position),
 5875                GetDefinitions { position },
 5876                cx,
 5877            );
 5878            cx.background_spawn(async move {
 5879                Ok(Some(
 5880                    definitions_task
 5881                        .await
 5882                        .into_iter()
 5883                        .flat_map(|(_, definitions)| definitions)
 5884                        .dedup()
 5885                        .collect(),
 5886                ))
 5887            })
 5888        }
 5889    }
 5890
 5891    pub fn declarations(
 5892        &mut self,
 5893        buffer: &Entity<Buffer>,
 5894        position: PointUtf16,
 5895        cx: &mut Context<Self>,
 5896    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5897        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5898            let request = GetDeclarations { position };
 5899            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5900                return Task::ready(Ok(None));
 5901            }
 5902            let request_timeout = ProjectSettings::get_global(cx)
 5903                .global_lsp_settings
 5904                .get_request_timeout();
 5905            let request_task = upstream_client.request_lsp(
 5906                project_id,
 5907                None,
 5908                request_timeout,
 5909                cx.background_executor().clone(),
 5910                request.to_proto(project_id, buffer.read(cx)),
 5911            );
 5912            let buffer = buffer.clone();
 5913            cx.spawn(async move |weak_lsp_store, cx| {
 5914                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5915                    return Ok(None);
 5916                };
 5917                let Some(responses) = request_task.await? else {
 5918                    return Ok(None);
 5919                };
 5920                let actions = join_all(responses.payload.into_iter().map(|response| {
 5921                    GetDeclarations { position }.response_from_proto(
 5922                        response.response,
 5923                        lsp_store.clone(),
 5924                        buffer.clone(),
 5925                        cx.clone(),
 5926                    )
 5927                }))
 5928                .await;
 5929
 5930                Ok(Some(
 5931                    actions
 5932                        .into_iter()
 5933                        .collect::<Result<Vec<Vec<_>>>>()?
 5934                        .into_iter()
 5935                        .flatten()
 5936                        .dedup()
 5937                        .collect(),
 5938                ))
 5939            })
 5940        } else {
 5941            let declarations_task = self.request_multiple_lsp_locally(
 5942                buffer,
 5943                Some(position),
 5944                GetDeclarations { position },
 5945                cx,
 5946            );
 5947            cx.background_spawn(async move {
 5948                Ok(Some(
 5949                    declarations_task
 5950                        .await
 5951                        .into_iter()
 5952                        .flat_map(|(_, declarations)| declarations)
 5953                        .dedup()
 5954                        .collect(),
 5955                ))
 5956            })
 5957        }
 5958    }
 5959
 5960    pub fn type_definitions(
 5961        &mut self,
 5962        buffer: &Entity<Buffer>,
 5963        position: PointUtf16,
 5964        cx: &mut Context<Self>,
 5965    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5966        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5967            let request = GetTypeDefinitions { position };
 5968            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5969                return Task::ready(Ok(None));
 5970            }
 5971            let request_timeout = ProjectSettings::get_global(cx)
 5972                .global_lsp_settings
 5973                .get_request_timeout();
 5974            let request_task = upstream_client.request_lsp(
 5975                project_id,
 5976                None,
 5977                request_timeout,
 5978                cx.background_executor().clone(),
 5979                request.to_proto(project_id, buffer.read(cx)),
 5980            );
 5981            let buffer = buffer.clone();
 5982            cx.spawn(async move |weak_lsp_store, cx| {
 5983                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5984                    return Ok(None);
 5985                };
 5986                let Some(responses) = request_task.await? else {
 5987                    return Ok(None);
 5988                };
 5989                let actions = join_all(responses.payload.into_iter().map(|response| {
 5990                    GetTypeDefinitions { position }.response_from_proto(
 5991                        response.response,
 5992                        lsp_store.clone(),
 5993                        buffer.clone(),
 5994                        cx.clone(),
 5995                    )
 5996                }))
 5997                .await;
 5998
 5999                Ok(Some(
 6000                    actions
 6001                        .into_iter()
 6002                        .collect::<Result<Vec<Vec<_>>>>()?
 6003                        .into_iter()
 6004                        .flatten()
 6005                        .dedup()
 6006                        .collect(),
 6007                ))
 6008            })
 6009        } else {
 6010            let type_definitions_task = self.request_multiple_lsp_locally(
 6011                buffer,
 6012                Some(position),
 6013                GetTypeDefinitions { position },
 6014                cx,
 6015            );
 6016            cx.background_spawn(async move {
 6017                Ok(Some(
 6018                    type_definitions_task
 6019                        .await
 6020                        .into_iter()
 6021                        .flat_map(|(_, type_definitions)| type_definitions)
 6022                        .dedup()
 6023                        .collect(),
 6024                ))
 6025            })
 6026        }
 6027    }
 6028
 6029    pub fn implementations(
 6030        &mut self,
 6031        buffer: &Entity<Buffer>,
 6032        position: PointUtf16,
 6033        cx: &mut Context<Self>,
 6034    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 6035        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6036            let request = GetImplementations { position };
 6037            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6038                return Task::ready(Ok(None));
 6039            }
 6040
 6041            let request_timeout = ProjectSettings::get_global(cx)
 6042                .global_lsp_settings
 6043                .get_request_timeout();
 6044            let request_task = upstream_client.request_lsp(
 6045                project_id,
 6046                None,
 6047                request_timeout,
 6048                cx.background_executor().clone(),
 6049                request.to_proto(project_id, buffer.read(cx)),
 6050            );
 6051            let buffer = buffer.clone();
 6052            cx.spawn(async move |weak_lsp_store, cx| {
 6053                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6054                    return Ok(None);
 6055                };
 6056                let Some(responses) = request_task.await? else {
 6057                    return Ok(None);
 6058                };
 6059                let actions = join_all(responses.payload.into_iter().map(|response| {
 6060                    GetImplementations { position }.response_from_proto(
 6061                        response.response,
 6062                        lsp_store.clone(),
 6063                        buffer.clone(),
 6064                        cx.clone(),
 6065                    )
 6066                }))
 6067                .await;
 6068
 6069                Ok(Some(
 6070                    actions
 6071                        .into_iter()
 6072                        .collect::<Result<Vec<Vec<_>>>>()?
 6073                        .into_iter()
 6074                        .flatten()
 6075                        .dedup()
 6076                        .collect(),
 6077                ))
 6078            })
 6079        } else {
 6080            let implementations_task = self.request_multiple_lsp_locally(
 6081                buffer,
 6082                Some(position),
 6083                GetImplementations { position },
 6084                cx,
 6085            );
 6086            cx.background_spawn(async move {
 6087                Ok(Some(
 6088                    implementations_task
 6089                        .await
 6090                        .into_iter()
 6091                        .flat_map(|(_, implementations)| implementations)
 6092                        .dedup()
 6093                        .collect(),
 6094                ))
 6095            })
 6096        }
 6097    }
 6098
 6099    pub fn references(
 6100        &mut self,
 6101        buffer: &Entity<Buffer>,
 6102        position: PointUtf16,
 6103        cx: &mut Context<Self>,
 6104    ) -> Task<Result<Option<Vec<Location>>>> {
 6105        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6106            let request = GetReferences { position };
 6107            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6108                return Task::ready(Ok(None));
 6109            }
 6110
 6111            let request_timeout = ProjectSettings::get_global(cx)
 6112                .global_lsp_settings
 6113                .get_request_timeout();
 6114            let request_task = upstream_client.request_lsp(
 6115                project_id,
 6116                None,
 6117                request_timeout,
 6118                cx.background_executor().clone(),
 6119                request.to_proto(project_id, buffer.read(cx)),
 6120            );
 6121            let buffer = buffer.clone();
 6122            cx.spawn(async move |weak_lsp_store, cx| {
 6123                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6124                    return Ok(None);
 6125                };
 6126                let Some(responses) = request_task.await? else {
 6127                    return Ok(None);
 6128                };
 6129
 6130                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 6131                    GetReferences { position }.response_from_proto(
 6132                        lsp_response.response,
 6133                        lsp_store.clone(),
 6134                        buffer.clone(),
 6135                        cx.clone(),
 6136                    )
 6137                }))
 6138                .await
 6139                .into_iter()
 6140                .collect::<Result<Vec<Vec<_>>>>()?
 6141                .into_iter()
 6142                .flatten()
 6143                .dedup()
 6144                .collect();
 6145                Ok(Some(locations))
 6146            })
 6147        } else {
 6148            let references_task = self.request_multiple_lsp_locally(
 6149                buffer,
 6150                Some(position),
 6151                GetReferences { position },
 6152                cx,
 6153            );
 6154            cx.background_spawn(async move {
 6155                Ok(Some(
 6156                    references_task
 6157                        .await
 6158                        .into_iter()
 6159                        .flat_map(|(_, references)| references)
 6160                        .dedup()
 6161                        .collect(),
 6162                ))
 6163            })
 6164        }
 6165    }
 6166
 6167    pub fn code_actions(
 6168        &mut self,
 6169        buffer: &Entity<Buffer>,
 6170        range: Range<Anchor>,
 6171        kinds: Option<Vec<CodeActionKind>>,
 6172        cx: &mut Context<Self>,
 6173    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6174        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6175            let request = GetCodeActions {
 6176                range: range.clone(),
 6177                kinds: kinds.clone(),
 6178            };
 6179            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6180                return Task::ready(Ok(None));
 6181            }
 6182            let request_timeout = ProjectSettings::get_global(cx)
 6183                .global_lsp_settings
 6184                .get_request_timeout();
 6185            let request_task = upstream_client.request_lsp(
 6186                project_id,
 6187                None,
 6188                request_timeout,
 6189                cx.background_executor().clone(),
 6190                request.to_proto(project_id, buffer.read(cx)),
 6191            );
 6192            let buffer = buffer.clone();
 6193            cx.spawn(async move |weak_lsp_store, cx| {
 6194                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6195                    return Ok(None);
 6196                };
 6197                let Some(responses) = request_task.await? else {
 6198                    return Ok(None);
 6199                };
 6200                let actions = join_all(responses.payload.into_iter().map(|response| {
 6201                    GetCodeActions {
 6202                        range: range.clone(),
 6203                        kinds: kinds.clone(),
 6204                    }
 6205                    .response_from_proto(
 6206                        response.response,
 6207                        lsp_store.clone(),
 6208                        buffer.clone(),
 6209                        cx.clone(),
 6210                    )
 6211                }))
 6212                .await;
 6213
 6214                Ok(Some(
 6215                    actions
 6216                        .into_iter()
 6217                        .collect::<Result<Vec<Vec<_>>>>()?
 6218                        .into_iter()
 6219                        .flatten()
 6220                        .collect(),
 6221                ))
 6222            })
 6223        } else {
 6224            let all_actions_task = self.request_multiple_lsp_locally(
 6225                buffer,
 6226                Some(range.start),
 6227                GetCodeActions { range, kinds },
 6228                cx,
 6229            );
 6230            cx.background_spawn(async move {
 6231                Ok(Some(
 6232                    all_actions_task
 6233                        .await
 6234                        .into_iter()
 6235                        .flat_map(|(_, actions)| actions)
 6236                        .collect(),
 6237                ))
 6238            })
 6239        }
 6240    }
 6241
 6242    #[inline(never)]
 6243    pub fn completions(
 6244        &self,
 6245        buffer: &Entity<Buffer>,
 6246        position: PointUtf16,
 6247        context: CompletionContext,
 6248        cx: &mut Context<Self>,
 6249    ) -> Task<Result<Vec<CompletionResponse>>> {
 6250        let language_registry = self.languages.clone();
 6251
 6252        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6253            let snapshot = buffer.read(cx).snapshot();
 6254            let offset = position.to_offset(&snapshot);
 6255            let scope = snapshot.language_scope_at(offset);
 6256            let capable_lsps = self.all_capable_for_proto_request(
 6257                buffer,
 6258                |server_name, capabilities| {
 6259                    capabilities.completion_provider.is_some()
 6260                        && scope
 6261                            .as_ref()
 6262                            .map(|scope| scope.language_allowed(server_name))
 6263                            .unwrap_or(true)
 6264                },
 6265                cx,
 6266            );
 6267            if capable_lsps.is_empty() {
 6268                return Task::ready(Ok(Vec::new()));
 6269            }
 6270
 6271            let language = buffer.read(cx).language().cloned();
 6272
 6273            let buffer = buffer.clone();
 6274
 6275            cx.spawn(async move |this, cx| {
 6276                let requests = join_all(
 6277                    capable_lsps
 6278                        .into_iter()
 6279                        .map(|(id, server_name)| {
 6280                            let request = GetCompletions {
 6281                                position,
 6282                                context: context.clone(),
 6283                                server_id: Some(id),
 6284                            };
 6285                            let buffer = buffer.clone();
 6286                            let language = language.clone();
 6287                            let lsp_adapter = language.as_ref().and_then(|language| {
 6288                                let adapters = language_registry.lsp_adapters(&language.name());
 6289                                adapters
 6290                                    .iter()
 6291                                    .find(|adapter| adapter.name() == server_name)
 6292                                    .or_else(|| adapters.first())
 6293                                    .cloned()
 6294                            });
 6295                            let upstream_client = upstream_client.clone();
 6296                            let response = this
 6297                                .update(cx, |this, cx| {
 6298                                    this.send_lsp_proto_request(
 6299                                        buffer,
 6300                                        upstream_client,
 6301                                        project_id,
 6302                                        request,
 6303                                        cx,
 6304                                    )
 6305                                })
 6306                                .log_err();
 6307                            async move {
 6308                                let response = response?.await.log_err()?;
 6309
 6310                                let completions = populate_labels_for_completions(
 6311                                    response.completions,
 6312                                    language,
 6313                                    lsp_adapter,
 6314                                )
 6315                                .await;
 6316
 6317                                Some(CompletionResponse {
 6318                                    completions,
 6319                                    display_options: CompletionDisplayOptions::default(),
 6320                                    is_incomplete: response.is_incomplete,
 6321                                })
 6322                            }
 6323                        })
 6324                        .collect::<Vec<_>>(),
 6325                );
 6326                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6327            })
 6328        } else if let Some(local) = self.as_local() {
 6329            let snapshot = buffer.read(cx).snapshot();
 6330            let offset = position.to_offset(&snapshot);
 6331            let scope = snapshot.language_scope_at(offset);
 6332            let language = snapshot.language().cloned();
 6333            let completion_settings = LanguageSettings::for_buffer(&buffer.read(cx), cx)
 6334                .completions
 6335                .clone();
 6336            if !completion_settings.lsp {
 6337                return Task::ready(Ok(Vec::new()));
 6338            }
 6339
 6340            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6341                local
 6342                    .language_servers_for_buffer(buffer, cx)
 6343                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6344                    .filter(|(adapter, _)| {
 6345                        scope
 6346                            .as_ref()
 6347                            .map(|scope| scope.language_allowed(&adapter.name))
 6348                            .unwrap_or(true)
 6349                    })
 6350                    .map(|(_, server)| server.server_id())
 6351                    .collect()
 6352            });
 6353
 6354            let buffer = buffer.clone();
 6355            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6356            let lsp_timeout = if lsp_timeout > 0 {
 6357                Some(Duration::from_millis(lsp_timeout))
 6358            } else {
 6359                None
 6360            };
 6361            cx.spawn(async move |this,  cx| {
 6362                let mut tasks = Vec::with_capacity(server_ids.len());
 6363                this.update(cx, |lsp_store, cx| {
 6364                    for server_id in server_ids {
 6365                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6366                        let lsp_timeout = lsp_timeout
 6367                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6368                        let mut timeout = cx.background_spawn(async move {
 6369                            match lsp_timeout {
 6370                                Some(lsp_timeout) => {
 6371                                    lsp_timeout.await;
 6372                                    true
 6373                                },
 6374                                None => false,
 6375                            }
 6376                        }).fuse();
 6377                        let mut lsp_request = lsp_store.request_lsp(
 6378                            buffer.clone(),
 6379                            LanguageServerToQuery::Other(server_id),
 6380                            GetCompletions {
 6381                                position,
 6382                                context: context.clone(),
 6383                                server_id: Some(server_id),
 6384                            },
 6385                            cx,
 6386                        ).fuse();
 6387                        let new_task = cx.background_spawn(async move {
 6388                            select_biased! {
 6389                                response = lsp_request => anyhow::Ok(Some(response?)),
 6390                                timeout_happened = timeout => {
 6391                                    if timeout_happened {
 6392                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6393                                        Ok(None)
 6394                                    } else {
 6395                                        let completions = lsp_request.await?;
 6396                                        Ok(Some(completions))
 6397                                    }
 6398                                },
 6399                            }
 6400                        });
 6401                        tasks.push((lsp_adapter, new_task));
 6402                    }
 6403                })?;
 6404
 6405                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6406                    let completion_response = task.await.ok()??;
 6407                    let completions = populate_labels_for_completions(
 6408                            completion_response.completions,
 6409                            language.clone(),
 6410                            lsp_adapter,
 6411                        )
 6412                        .await;
 6413                    Some(CompletionResponse {
 6414                        completions,
 6415                        display_options: CompletionDisplayOptions::default(),
 6416                        is_incomplete: completion_response.is_incomplete,
 6417                    })
 6418                });
 6419
 6420                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6421
 6422                Ok(responses.into_iter().flatten().collect())
 6423            })
 6424        } else {
 6425            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6426        }
 6427    }
 6428
 6429    pub fn resolve_completions(
 6430        &self,
 6431        buffer: Entity<Buffer>,
 6432        completion_indices: Vec<usize>,
 6433        completions: Rc<RefCell<Box<[Completion]>>>,
 6434        cx: &mut Context<Self>,
 6435    ) -> Task<Result<bool>> {
 6436        let client = self.upstream_client();
 6437        let buffer_id = buffer.read(cx).remote_id();
 6438        let buffer_snapshot = buffer.read(cx).snapshot();
 6439
 6440        if !self.check_if_capable_for_proto_request(
 6441            &buffer,
 6442            GetCompletions::can_resolve_completions,
 6443            cx,
 6444        ) {
 6445            return Task::ready(Ok(false));
 6446        }
 6447        cx.spawn(async move |lsp_store, cx| {
 6448            let request_timeout = cx.update(|app| {
 6449                ProjectSettings::get_global(app)
 6450                    .global_lsp_settings
 6451                    .get_request_timeout()
 6452            });
 6453
 6454            let mut did_resolve = false;
 6455            if let Some((client, project_id)) = client {
 6456                for completion_index in completion_indices {
 6457                    let server_id = {
 6458                        let completion = &completions.borrow()[completion_index];
 6459                        completion.source.server_id()
 6460                    };
 6461                    if let Some(server_id) = server_id {
 6462                        if Self::resolve_completion_remote(
 6463                            project_id,
 6464                            server_id,
 6465                            buffer_id,
 6466                            completions.clone(),
 6467                            completion_index,
 6468                            client.clone(),
 6469                        )
 6470                        .await
 6471                        .log_err()
 6472                        .is_some()
 6473                        {
 6474                            did_resolve = true;
 6475                        }
 6476                    } else {
 6477                        resolve_word_completion(
 6478                            &buffer_snapshot,
 6479                            &mut completions.borrow_mut()[completion_index],
 6480                        );
 6481                    }
 6482                }
 6483            } else {
 6484                for completion_index in completion_indices {
 6485                    let server_id = {
 6486                        let completion = &completions.borrow()[completion_index];
 6487                        completion.source.server_id()
 6488                    };
 6489                    if let Some(server_id) = server_id {
 6490                        let server_and_adapter = lsp_store
 6491                            .read_with(cx, |lsp_store, _| {
 6492                                let server = lsp_store.language_server_for_id(server_id)?;
 6493                                let adapter =
 6494                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6495                                Some((server, adapter))
 6496                            })
 6497                            .ok()
 6498                            .flatten();
 6499                        let Some((server, adapter)) = server_and_adapter else {
 6500                            continue;
 6501                        };
 6502
 6503                        let resolved = Self::resolve_completion_local(
 6504                            server,
 6505                            completions.clone(),
 6506                            completion_index,
 6507                            request_timeout,
 6508                        )
 6509                        .await
 6510                        .log_err()
 6511                        .is_some();
 6512                        if resolved {
 6513                            Self::regenerate_completion_labels(
 6514                                adapter,
 6515                                &buffer_snapshot,
 6516                                completions.clone(),
 6517                                completion_index,
 6518                            )
 6519                            .await
 6520                            .log_err();
 6521                            did_resolve = true;
 6522                        }
 6523                    } else {
 6524                        resolve_word_completion(
 6525                            &buffer_snapshot,
 6526                            &mut completions.borrow_mut()[completion_index],
 6527                        );
 6528                    }
 6529                }
 6530            }
 6531
 6532            Ok(did_resolve)
 6533        })
 6534    }
 6535
 6536    async fn resolve_completion_local(
 6537        server: Arc<lsp::LanguageServer>,
 6538        completions: Rc<RefCell<Box<[Completion]>>>,
 6539        completion_index: usize,
 6540        request_timeout: Duration,
 6541    ) -> Result<()> {
 6542        let server_id = server.server_id();
 6543        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6544            return Ok(());
 6545        }
 6546
 6547        let request = {
 6548            let completion = &completions.borrow()[completion_index];
 6549            match &completion.source {
 6550                CompletionSource::Lsp {
 6551                    lsp_completion,
 6552                    resolved,
 6553                    server_id: completion_server_id,
 6554                    ..
 6555                } => {
 6556                    if *resolved {
 6557                        return Ok(());
 6558                    }
 6559                    anyhow::ensure!(
 6560                        server_id == *completion_server_id,
 6561                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6562                    );
 6563                    server.request::<lsp::request::ResolveCompletionItem>(
 6564                        *lsp_completion.clone(),
 6565                        request_timeout,
 6566                    )
 6567                }
 6568                CompletionSource::BufferWord { .. }
 6569                | CompletionSource::Dap { .. }
 6570                | CompletionSource::Custom => {
 6571                    return Ok(());
 6572                }
 6573            }
 6574        };
 6575        let resolved_completion = request
 6576            .await
 6577            .into_response()
 6578            .context("resolve completion")?;
 6579
 6580        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6581        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6582
 6583        let mut completions = completions.borrow_mut();
 6584        let completion = &mut completions[completion_index];
 6585        if let CompletionSource::Lsp {
 6586            lsp_completion,
 6587            resolved,
 6588            server_id: completion_server_id,
 6589            ..
 6590        } = &mut completion.source
 6591        {
 6592            if *resolved {
 6593                return Ok(());
 6594            }
 6595            anyhow::ensure!(
 6596                server_id == *completion_server_id,
 6597                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6598            );
 6599            **lsp_completion = resolved_completion;
 6600            *resolved = true;
 6601        }
 6602        Ok(())
 6603    }
 6604
 6605    async fn regenerate_completion_labels(
 6606        adapter: Arc<CachedLspAdapter>,
 6607        snapshot: &BufferSnapshot,
 6608        completions: Rc<RefCell<Box<[Completion]>>>,
 6609        completion_index: usize,
 6610    ) -> Result<()> {
 6611        let completion_item = completions.borrow()[completion_index]
 6612            .source
 6613            .lsp_completion(true)
 6614            .map(Cow::into_owned);
 6615        if let Some(lsp_documentation) = completion_item
 6616            .as_ref()
 6617            .and_then(|completion_item| completion_item.documentation.clone())
 6618        {
 6619            let mut completions = completions.borrow_mut();
 6620            let completion = &mut completions[completion_index];
 6621            completion.documentation = Some(lsp_documentation.into());
 6622        } else {
 6623            let mut completions = completions.borrow_mut();
 6624            let completion = &mut completions[completion_index];
 6625            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6626        }
 6627
 6628        let mut new_label = match completion_item {
 6629            Some(completion_item) => {
 6630                // Some language servers always return `detail` lazily via resolve, regardless of
 6631                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6632                // See: https://github.com/yioneko/vtsls/issues/213
 6633                let language = snapshot.language();
 6634                match language {
 6635                    Some(language) => {
 6636                        adapter
 6637                            .labels_for_completions(
 6638                                std::slice::from_ref(&completion_item),
 6639                                language,
 6640                            )
 6641                            .await?
 6642                    }
 6643                    None => Vec::new(),
 6644                }
 6645                .pop()
 6646                .flatten()
 6647                .unwrap_or_else(|| {
 6648                    CodeLabel::fallback_for_completion(
 6649                        &completion_item,
 6650                        language.map(|language| language.as_ref()),
 6651                    )
 6652                })
 6653            }
 6654            None => CodeLabel::plain(
 6655                completions.borrow()[completion_index].new_text.clone(),
 6656                None,
 6657            ),
 6658        };
 6659        ensure_uniform_list_compatible_label(&mut new_label);
 6660
 6661        let mut completions = completions.borrow_mut();
 6662        let completion = &mut completions[completion_index];
 6663        if completion.label.filter_text() == new_label.filter_text() {
 6664            completion.label = new_label;
 6665        } else {
 6666            log::error!(
 6667                "Resolved completion changed display label from {} to {}. \
 6668                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6669                completion.label.text(),
 6670                new_label.text(),
 6671                completion.label.filter_text(),
 6672                new_label.filter_text()
 6673            );
 6674        }
 6675
 6676        Ok(())
 6677    }
 6678
 6679    async fn resolve_completion_remote(
 6680        project_id: u64,
 6681        server_id: LanguageServerId,
 6682        buffer_id: BufferId,
 6683        completions: Rc<RefCell<Box<[Completion]>>>,
 6684        completion_index: usize,
 6685        client: AnyProtoClient,
 6686    ) -> Result<()> {
 6687        let lsp_completion = {
 6688            let completion = &completions.borrow()[completion_index];
 6689            match &completion.source {
 6690                CompletionSource::Lsp {
 6691                    lsp_completion,
 6692                    resolved,
 6693                    server_id: completion_server_id,
 6694                    ..
 6695                } => {
 6696                    anyhow::ensure!(
 6697                        server_id == *completion_server_id,
 6698                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6699                    );
 6700                    if *resolved {
 6701                        return Ok(());
 6702                    }
 6703                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6704                }
 6705                CompletionSource::Custom
 6706                | CompletionSource::Dap { .. }
 6707                | CompletionSource::BufferWord { .. } => {
 6708                    return Ok(());
 6709                }
 6710            }
 6711        };
 6712        let request = proto::ResolveCompletionDocumentation {
 6713            project_id,
 6714            language_server_id: server_id.0 as u64,
 6715            lsp_completion,
 6716            buffer_id: buffer_id.into(),
 6717        };
 6718
 6719        let response = client
 6720            .request(request)
 6721            .await
 6722            .context("completion documentation resolve proto request")?;
 6723        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6724
 6725        let documentation = if response.documentation.is_empty() {
 6726            CompletionDocumentation::Undocumented
 6727        } else if response.documentation_is_markdown {
 6728            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6729        } else if response.documentation.lines().count() <= 1 {
 6730            CompletionDocumentation::SingleLine(response.documentation.into())
 6731        } else {
 6732            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6733        };
 6734
 6735        let mut completions = completions.borrow_mut();
 6736        let completion = &mut completions[completion_index];
 6737        completion.documentation = Some(documentation);
 6738        if let CompletionSource::Lsp {
 6739            insert_range,
 6740            lsp_completion,
 6741            resolved,
 6742            server_id: completion_server_id,
 6743            lsp_defaults: _,
 6744        } = &mut completion.source
 6745        {
 6746            let completion_insert_range = response
 6747                .old_insert_start
 6748                .and_then(deserialize_anchor)
 6749                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6750            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6751
 6752            if *resolved {
 6753                return Ok(());
 6754            }
 6755            anyhow::ensure!(
 6756                server_id == *completion_server_id,
 6757                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6758            );
 6759            **lsp_completion = resolved_lsp_completion;
 6760            *resolved = true;
 6761        }
 6762
 6763        let replace_range = response
 6764            .old_replace_start
 6765            .and_then(deserialize_anchor)
 6766            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6767        if let Some((old_replace_start, old_replace_end)) = replace_range
 6768            && !response.new_text.is_empty()
 6769        {
 6770            completion.new_text = response.new_text;
 6771            completion.replace_range = old_replace_start..old_replace_end;
 6772        }
 6773
 6774        Ok(())
 6775    }
 6776
 6777    pub fn apply_additional_edits_for_completion(
 6778        &self,
 6779        buffer_handle: Entity<Buffer>,
 6780        completions: Rc<RefCell<Box<[Completion]>>>,
 6781        completion_index: usize,
 6782        push_to_history: bool,
 6783        all_commit_ranges: Vec<Range<language::Anchor>>,
 6784        cx: &mut Context<Self>,
 6785    ) -> Task<Result<Option<Transaction>>> {
 6786        if let Some((client, project_id)) = self.upstream_client() {
 6787            let buffer = buffer_handle.read(cx);
 6788            let buffer_id = buffer.remote_id();
 6789            cx.spawn(async move |_, cx| {
 6790                let request = {
 6791                    let completion = completions.borrow()[completion_index].clone();
 6792                    proto::ApplyCompletionAdditionalEdits {
 6793                        project_id,
 6794                        buffer_id: buffer_id.into(),
 6795                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6796                            replace_range: completion.replace_range,
 6797                            new_text: completion.new_text,
 6798                            source: completion.source,
 6799                        })),
 6800                        all_commit_ranges: all_commit_ranges
 6801                            .iter()
 6802                            .cloned()
 6803                            .map(language::proto::serialize_anchor_range)
 6804                            .collect(),
 6805                    }
 6806                };
 6807
 6808                let Some(transaction) = client.request(request).await?.transaction else {
 6809                    return Ok(None);
 6810                };
 6811
 6812                let transaction = language::proto::deserialize_transaction(transaction)?;
 6813                buffer_handle
 6814                    .update(cx, |buffer, _| {
 6815                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6816                    })
 6817                    .await?;
 6818                if push_to_history {
 6819                    buffer_handle.update(cx, |buffer, _| {
 6820                        buffer.push_transaction(transaction.clone(), Instant::now());
 6821                        buffer.finalize_last_transaction();
 6822                    });
 6823                }
 6824                Ok(Some(transaction))
 6825            })
 6826        } else {
 6827            let request_timeout = ProjectSettings::get_global(cx)
 6828                .global_lsp_settings
 6829                .get_request_timeout();
 6830
 6831            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6832                let completion = &completions.borrow()[completion_index];
 6833                let server_id = completion.source.server_id()?;
 6834                Some(
 6835                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6836                        .1
 6837                        .clone(),
 6838                )
 6839            }) else {
 6840                return Task::ready(Ok(None));
 6841            };
 6842
 6843            cx.spawn(async move |this, cx| {
 6844                Self::resolve_completion_local(
 6845                    server.clone(),
 6846                    completions.clone(),
 6847                    completion_index,
 6848                    request_timeout,
 6849                )
 6850                .await
 6851                .context("resolving completion")?;
 6852                let completion = completions.borrow()[completion_index].clone();
 6853                let additional_text_edits = completion
 6854                    .source
 6855                    .lsp_completion(true)
 6856                    .as_ref()
 6857                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6858                if let Some(edits) = additional_text_edits {
 6859                    let edits = this
 6860                        .update(cx, |this, cx| {
 6861                            this.as_local_mut().unwrap().edits_from_lsp(
 6862                                &buffer_handle,
 6863                                edits,
 6864                                server.server_id(),
 6865                                None,
 6866                                cx,
 6867                            )
 6868                        })?
 6869                        .await?;
 6870
 6871                    buffer_handle.update(cx, |buffer, cx| {
 6872                        buffer.finalize_last_transaction();
 6873                        buffer.start_transaction();
 6874
 6875                        for (range, text) in edits {
 6876                            let primary = &completion.replace_range;
 6877
 6878                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6879                            // and the primary completion is just an insertion (empty range), then this is likely
 6880                            // an auto-import scenario and should not be considered overlapping
 6881                            // https://github.com/zed-industries/zed/issues/26136
 6882                            let is_file_start_auto_import = {
 6883                                let snapshot = buffer.snapshot();
 6884                                let primary_start_point = primary.start.to_point(&snapshot);
 6885                                let range_start_point = range.start.to_point(&snapshot);
 6886
 6887                                let result = primary_start_point.row == 0
 6888                                    && primary_start_point.column == 0
 6889                                    && range_start_point.row == 0
 6890                                    && range_start_point.column == 0;
 6891
 6892                                result
 6893                            };
 6894
 6895                            let has_overlap = if is_file_start_auto_import {
 6896                                false
 6897                            } else {
 6898                                all_commit_ranges.iter().any(|commit_range| {
 6899                                    let start_within =
 6900                                        commit_range.start.cmp(&range.start, buffer).is_le()
 6901                                            && commit_range.end.cmp(&range.start, buffer).is_ge();
 6902                                    let end_within =
 6903                                        range.start.cmp(&commit_range.end, buffer).is_le()
 6904                                            && range.end.cmp(&commit_range.end, buffer).is_ge();
 6905                                    start_within || end_within
 6906                                })
 6907                            };
 6908
 6909                            //Skip additional edits which overlap with the primary completion edit
 6910                            //https://github.com/zed-industries/zed/pull/1871
 6911                            if !has_overlap {
 6912                                buffer.edit([(range, text)], None, cx);
 6913                            }
 6914                        }
 6915
 6916                        let transaction = if buffer.end_transaction(cx).is_some() {
 6917                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6918                            if !push_to_history {
 6919                                buffer.forget_transaction(transaction.id);
 6920                            }
 6921                            Some(transaction)
 6922                        } else {
 6923                            None
 6924                        };
 6925                        Ok(transaction)
 6926                    })
 6927                } else {
 6928                    Ok(None)
 6929                }
 6930            })
 6931        }
 6932    }
 6933
 6934    pub fn pull_diagnostics(
 6935        &mut self,
 6936        buffer: Entity<Buffer>,
 6937        cx: &mut Context<Self>,
 6938    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6939        let buffer_id = buffer.read(cx).remote_id();
 6940
 6941        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6942            let mut suitable_capabilities = None;
 6943            // Are we capable for proto request?
 6944            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6945                &buffer,
 6946                |capabilities| {
 6947                    if let Some(caps) = &capabilities.diagnostic_provider {
 6948                        suitable_capabilities = Some(caps.clone());
 6949                        true
 6950                    } else {
 6951                        false
 6952                    }
 6953                },
 6954                cx,
 6955            );
 6956            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6957            let Some(dynamic_caps) = suitable_capabilities else {
 6958                return Task::ready(Ok(None));
 6959            };
 6960            assert!(any_server_has_diagnostics_provider);
 6961
 6962            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6963            let request = GetDocumentDiagnostics {
 6964                previous_result_id: None,
 6965                identifier,
 6966                registration_id: None,
 6967            };
 6968            let request_timeout = ProjectSettings::get_global(cx)
 6969                .global_lsp_settings
 6970                .get_request_timeout();
 6971            let request_task = client.request_lsp(
 6972                upstream_project_id,
 6973                None,
 6974                request_timeout,
 6975                cx.background_executor().clone(),
 6976                request.to_proto(upstream_project_id, buffer.read(cx)),
 6977            );
 6978            cx.background_spawn(async move {
 6979                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6980                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6981                // Do not attempt to further process the dummy responses here.
 6982                let _response = request_task.await?;
 6983                Ok(None)
 6984            })
 6985        } else {
 6986            let servers = buffer.update(cx, |buffer, cx| {
 6987                self.running_language_servers_for_local_buffer(buffer, cx)
 6988                    .map(|(_, server)| server.clone())
 6989                    .collect::<Vec<_>>()
 6990            });
 6991
 6992            let pull_diagnostics = servers
 6993                .into_iter()
 6994                .flat_map(|server| {
 6995                    let result = maybe!({
 6996                        let local = self.as_local()?;
 6997                        let server_id = server.server_id();
 6998                        let providers_with_identifiers = local
 6999                            .language_server_dynamic_registrations
 7000                            .get(&server_id)
 7001                            .into_iter()
 7002                            .flat_map(|registrations| registrations.diagnostics.clone())
 7003                            .collect::<Vec<_>>();
 7004                        Some(
 7005                            providers_with_identifiers
 7006                                .into_iter()
 7007                                .map(|(registration_id, dynamic_caps)| {
 7008                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 7009                                    let registration_id = registration_id.map(SharedString::from);
 7010                                    let result_id = self.result_id_for_buffer_pull(
 7011                                        server_id,
 7012                                        buffer_id,
 7013                                        &registration_id,
 7014                                        cx,
 7015                                    );
 7016                                    self.request_lsp(
 7017                                        buffer.clone(),
 7018                                        LanguageServerToQuery::Other(server_id),
 7019                                        GetDocumentDiagnostics {
 7020                                            previous_result_id: result_id,
 7021                                            registration_id,
 7022                                            identifier,
 7023                                        },
 7024                                        cx,
 7025                                    )
 7026                                })
 7027                                .collect::<Vec<_>>(),
 7028                        )
 7029                    });
 7030
 7031                    result.unwrap_or_default()
 7032                })
 7033                .collect::<Vec<_>>();
 7034
 7035            cx.background_spawn(async move {
 7036                let mut responses = Vec::new();
 7037                for diagnostics in join_all(pull_diagnostics).await {
 7038                    responses.extend(diagnostics?);
 7039                }
 7040                Ok(Some(responses))
 7041            })
 7042        }
 7043    }
 7044
 7045    pub fn applicable_inlay_chunks(
 7046        &mut self,
 7047        buffer: &Entity<Buffer>,
 7048        ranges: &[Range<text::Anchor>],
 7049        cx: &mut Context<Self>,
 7050    ) -> Vec<Range<BufferRow>> {
 7051        let buffer_snapshot = buffer.read(cx).snapshot();
 7052        let ranges = ranges
 7053            .iter()
 7054            .map(|range| range.to_point(&buffer_snapshot))
 7055            .collect::<Vec<_>>();
 7056
 7057        self.latest_lsp_data(buffer, cx)
 7058            .inlay_hints
 7059            .applicable_chunks(ranges.as_slice())
 7060            .map(|chunk| chunk.row_range())
 7061            .collect()
 7062    }
 7063
 7064    pub fn invalidate_inlay_hints<'a>(
 7065        &'a mut self,
 7066        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 7067    ) {
 7068        for buffer_id in for_buffers {
 7069            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 7070                lsp_data.inlay_hints.clear();
 7071            }
 7072        }
 7073    }
 7074
 7075    pub fn inlay_hints(
 7076        &mut self,
 7077        invalidate: InvalidationStrategy,
 7078        buffer: Entity<Buffer>,
 7079        ranges: Vec<Range<text::Anchor>>,
 7080        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 7081        cx: &mut Context<Self>,
 7082    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 7083        let next_hint_id = self.next_hint_id.clone();
 7084        let lsp_data = self.latest_lsp_data(&buffer, cx);
 7085        let query_version = lsp_data.buffer_version.clone();
 7086        let mut lsp_refresh_requested = false;
 7087        let for_server = if let InvalidationStrategy::RefreshRequested {
 7088            server_id,
 7089            request_id,
 7090        } = invalidate
 7091        {
 7092            let invalidated = lsp_data
 7093                .inlay_hints
 7094                .invalidate_for_server_refresh(server_id, request_id);
 7095            lsp_refresh_requested = invalidated;
 7096            Some(server_id)
 7097        } else {
 7098            None
 7099        };
 7100        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 7101        let known_chunks = known_chunks
 7102            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 7103            .map(|(_, known_chunks)| known_chunks)
 7104            .unwrap_or_default();
 7105
 7106        let buffer_snapshot = buffer.read(cx).snapshot();
 7107        let ranges = ranges
 7108            .iter()
 7109            .map(|range| range.to_point(&buffer_snapshot))
 7110            .collect::<Vec<_>>();
 7111
 7112        let mut hint_fetch_tasks = Vec::new();
 7113        let mut cached_inlay_hints = None;
 7114        let mut ranges_to_query = None;
 7115        let applicable_chunks = existing_inlay_hints
 7116            .applicable_chunks(ranges.as_slice())
 7117            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7118            .collect::<Vec<_>>();
 7119        if applicable_chunks.is_empty() {
 7120            return HashMap::default();
 7121        }
 7122
 7123        for row_chunk in applicable_chunks {
 7124            match (
 7125                existing_inlay_hints
 7126                    .cached_hints(&row_chunk)
 7127                    .filter(|_| !lsp_refresh_requested)
 7128                    .cloned(),
 7129                existing_inlay_hints
 7130                    .fetched_hints(&row_chunk)
 7131                    .as_ref()
 7132                    .filter(|_| !lsp_refresh_requested)
 7133                    .cloned(),
 7134            ) {
 7135                (None, None) => {
 7136                    let chunk_range = row_chunk.anchor_range();
 7137                    ranges_to_query
 7138                        .get_or_insert_with(Vec::new)
 7139                        .push((row_chunk, chunk_range));
 7140                }
 7141                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7142                (Some(cached_hints), None) => {
 7143                    for (server_id, cached_hints) in cached_hints {
 7144                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7145                            cached_inlay_hints
 7146                                .get_or_insert_with(HashMap::default)
 7147                                .entry(row_chunk.row_range())
 7148                                .or_insert_with(HashMap::default)
 7149                                .entry(server_id)
 7150                                .or_insert_with(Vec::new)
 7151                                .extend(cached_hints);
 7152                        }
 7153                    }
 7154                }
 7155                (Some(cached_hints), Some(fetched_hints)) => {
 7156                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7157                    for (server_id, cached_hints) in cached_hints {
 7158                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7159                            cached_inlay_hints
 7160                                .get_or_insert_with(HashMap::default)
 7161                                .entry(row_chunk.row_range())
 7162                                .or_insert_with(HashMap::default)
 7163                                .entry(server_id)
 7164                                .or_insert_with(Vec::new)
 7165                                .extend(cached_hints);
 7166                        }
 7167                    }
 7168                }
 7169            }
 7170        }
 7171
 7172        if hint_fetch_tasks.is_empty()
 7173            && ranges_to_query
 7174                .as_ref()
 7175                .is_none_or(|ranges| ranges.is_empty())
 7176            && let Some(cached_inlay_hints) = cached_inlay_hints
 7177        {
 7178            cached_inlay_hints
 7179                .into_iter()
 7180                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7181                .collect()
 7182        } else {
 7183            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7184                // When a server refresh was requested, other servers' cached hints
 7185                // are unaffected by the refresh and must be included in the result.
 7186                // Otherwise apply_fetched_hints (with should_invalidate()=true)
 7187                // removes all visible hints but only adds back the requesting
 7188                // server's new hints, permanently losing other servers' hints.
 7189                let other_servers_cached: CacheInlayHints = if lsp_refresh_requested {
 7190                    lsp_data
 7191                        .inlay_hints
 7192                        .cached_hints(&chunk)
 7193                        .cloned()
 7194                        .unwrap_or_default()
 7195                } else {
 7196                    HashMap::default()
 7197                };
 7198
 7199                let next_hint_id = next_hint_id.clone();
 7200                let buffer = buffer.clone();
 7201                let query_version = query_version.clone();
 7202                let new_inlay_hints = cx
 7203                    .spawn(async move |lsp_store, cx| {
 7204                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7205                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7206                        })?;
 7207                        new_fetch_task
 7208                            .await
 7209                            .and_then(|new_hints_by_server| {
 7210                                lsp_store.update(cx, |lsp_store, cx| {
 7211                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7212                                    let update_cache = lsp_data.buffer_version == query_version;
 7213                                    if new_hints_by_server.is_empty() {
 7214                                        if update_cache {
 7215                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7216                                        }
 7217                                        other_servers_cached
 7218                                    } else {
 7219                                        let mut result = other_servers_cached;
 7220                                        for (server_id, new_hints) in new_hints_by_server {
 7221                                            let new_hints = new_hints
 7222                                                .into_iter()
 7223                                                .map(|new_hint| {
 7224                                                    (
 7225                                                        InlayId::Hint(next_hint_id.fetch_add(
 7226                                                            1,
 7227                                                            atomic::Ordering::AcqRel,
 7228                                                        )),
 7229                                                        new_hint,
 7230                                                    )
 7231                                                })
 7232                                                .collect::<Vec<_>>();
 7233                                            if update_cache {
 7234                                                lsp_data.inlay_hints.insert_new_hints(
 7235                                                    chunk,
 7236                                                    server_id,
 7237                                                    new_hints.clone(),
 7238                                                );
 7239                                            }
 7240                                            result.insert(server_id, new_hints);
 7241                                        }
 7242                                        result
 7243                                    }
 7244                                })
 7245                            })
 7246                            .map_err(Arc::new)
 7247                    })
 7248                    .shared();
 7249
 7250                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7251                *fetch_task = Some(new_inlay_hints.clone());
 7252                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7253            }
 7254
 7255            cached_inlay_hints
 7256                .unwrap_or_default()
 7257                .into_iter()
 7258                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7259                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7260                    (
 7261                        chunk.row_range(),
 7262                        cx.spawn(async move |_, _| {
 7263                            hints_fetch.await.map_err(|e| {
 7264                                if e.error_code() != ErrorCode::Internal {
 7265                                    anyhow!(e.error_code())
 7266                                } else {
 7267                                    anyhow!("{e:#}")
 7268                                }
 7269                            })
 7270                        }),
 7271                    )
 7272                }))
 7273                .collect()
 7274        }
 7275    }
 7276
 7277    fn fetch_inlay_hints(
 7278        &mut self,
 7279        for_server: Option<LanguageServerId>,
 7280        buffer: &Entity<Buffer>,
 7281        range: Range<Anchor>,
 7282        cx: &mut Context<Self>,
 7283    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7284        let request = InlayHints {
 7285            range: range.clone(),
 7286        };
 7287        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7288            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7289                return Task::ready(Ok(HashMap::default()));
 7290            }
 7291            let request_timeout = ProjectSettings::get_global(cx)
 7292                .global_lsp_settings
 7293                .get_request_timeout();
 7294            let request_task = upstream_client.request_lsp(
 7295                project_id,
 7296                for_server.map(|id| id.to_proto()),
 7297                request_timeout,
 7298                cx.background_executor().clone(),
 7299                request.to_proto(project_id, buffer.read(cx)),
 7300            );
 7301            let buffer = buffer.clone();
 7302            cx.spawn(async move |weak_lsp_store, cx| {
 7303                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7304                    return Ok(HashMap::default());
 7305                };
 7306                let Some(responses) = request_task.await? else {
 7307                    return Ok(HashMap::default());
 7308                };
 7309
 7310                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7311                    let lsp_store = lsp_store.clone();
 7312                    let buffer = buffer.clone();
 7313                    let cx = cx.clone();
 7314                    let request = request.clone();
 7315                    async move {
 7316                        (
 7317                            LanguageServerId::from_proto(response.server_id),
 7318                            request
 7319                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7320                                .await,
 7321                        )
 7322                    }
 7323                }))
 7324                .await;
 7325
 7326                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7327                let mut has_errors = false;
 7328                let inlay_hints = inlay_hints
 7329                    .into_iter()
 7330                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7331                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7332                        Err(e) => {
 7333                            has_errors = true;
 7334                            log::error!("{e:#}");
 7335                            None
 7336                        }
 7337                    })
 7338                    .map(|(server_id, mut new_hints)| {
 7339                        new_hints.retain(|hint| {
 7340                            hint.position.is_valid(&buffer_snapshot)
 7341                                && range.start.is_valid(&buffer_snapshot)
 7342                                && range.end.is_valid(&buffer_snapshot)
 7343                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7344                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7345                        });
 7346                        (server_id, new_hints)
 7347                    })
 7348                    .collect::<HashMap<_, _>>();
 7349                anyhow::ensure!(
 7350                    !has_errors || !inlay_hints.is_empty(),
 7351                    "Failed to fetch inlay hints"
 7352                );
 7353                Ok(inlay_hints)
 7354            })
 7355        } else {
 7356            let inlay_hints_task = match for_server {
 7357                Some(server_id) => {
 7358                    let server_task = self.request_lsp(
 7359                        buffer.clone(),
 7360                        LanguageServerToQuery::Other(server_id),
 7361                        request,
 7362                        cx,
 7363                    );
 7364                    cx.background_spawn(async move {
 7365                        let mut responses = Vec::new();
 7366                        match server_task.await {
 7367                            Ok(response) => responses.push((server_id, response)),
 7368                            // rust-analyzer likes to error with this when its still loading up
 7369                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7370                            Err(e) => log::error!(
 7371                                "Error handling response for inlay hints request: {e:#}"
 7372                            ),
 7373                        }
 7374                        responses
 7375                    })
 7376                }
 7377                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7378            };
 7379            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7380            cx.background_spawn(async move {
 7381                Ok(inlay_hints_task
 7382                    .await
 7383                    .into_iter()
 7384                    .map(|(server_id, mut new_hints)| {
 7385                        new_hints.retain(|hint| {
 7386                            hint.position.is_valid(&buffer_snapshot)
 7387                                && range.start.is_valid(&buffer_snapshot)
 7388                                && range.end.is_valid(&buffer_snapshot)
 7389                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7390                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7391                        });
 7392                        (server_id, new_hints)
 7393                    })
 7394                    .collect())
 7395            })
 7396        }
 7397    }
 7398
 7399    fn diagnostic_registration_exists(
 7400        &self,
 7401        server_id: LanguageServerId,
 7402        registration_id: &Option<SharedString>,
 7403    ) -> bool {
 7404        let Some(local) = self.as_local() else {
 7405            return false;
 7406        };
 7407        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7408        else {
 7409            return false;
 7410        };
 7411        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7412        registrations.diagnostics.contains_key(&registration_key)
 7413    }
 7414
 7415    pub fn pull_diagnostics_for_buffer(
 7416        &mut self,
 7417        buffer: Entity<Buffer>,
 7418        cx: &mut Context<Self>,
 7419    ) -> Task<anyhow::Result<()>> {
 7420        let diagnostics = self.pull_diagnostics(buffer, cx);
 7421        cx.spawn(async move |lsp_store, cx| {
 7422            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7423                return Ok(());
 7424            };
 7425            lsp_store.update(cx, |lsp_store, cx| {
 7426                if lsp_store.as_local().is_none() {
 7427                    return;
 7428                }
 7429
 7430                let mut unchanged_buffers = HashMap::default();
 7431                let server_diagnostics_updates = diagnostics
 7432                    .into_iter()
 7433                    .filter_map(|diagnostics_set| match diagnostics_set {
 7434                        LspPullDiagnostics::Response {
 7435                            server_id,
 7436                            uri,
 7437                            diagnostics,
 7438                            registration_id,
 7439                        } => Some((server_id, uri, diagnostics, registration_id)),
 7440                        LspPullDiagnostics::Default => None,
 7441                    })
 7442                    .filter(|(server_id, _, _, registration_id)| {
 7443                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7444                    })
 7445                    .fold(
 7446                        HashMap::default(),
 7447                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7448                            let (result_id, diagnostics) = match diagnostics {
 7449                                PulledDiagnostics::Unchanged { result_id } => {
 7450                                    unchanged_buffers
 7451                                        .entry(new_registration_id.clone())
 7452                                        .or_insert_with(HashSet::default)
 7453                                        .insert(uri.clone());
 7454                                    (Some(result_id), Vec::new())
 7455                                }
 7456                                PulledDiagnostics::Changed {
 7457                                    result_id,
 7458                                    diagnostics,
 7459                                } => (result_id, diagnostics),
 7460                            };
 7461                            let disk_based_sources = Cow::Owned(
 7462                                lsp_store
 7463                                    .language_server_adapter_for_id(server_id)
 7464                                    .as_ref()
 7465                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7466                                    .unwrap_or(&[])
 7467                                    .to_vec(),
 7468                            );
 7469                            acc.entry(server_id)
 7470                                .or_insert_with(HashMap::default)
 7471                                .entry(new_registration_id.clone())
 7472                                .or_insert_with(Vec::new)
 7473                                .push(DocumentDiagnosticsUpdate {
 7474                                    server_id,
 7475                                    diagnostics: lsp::PublishDiagnosticsParams {
 7476                                        uri,
 7477                                        diagnostics,
 7478                                        version: None,
 7479                                    },
 7480                                    result_id: result_id.map(SharedString::new),
 7481                                    disk_based_sources,
 7482                                    registration_id: new_registration_id,
 7483                                });
 7484                            acc
 7485                        },
 7486                    );
 7487
 7488                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7489                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7490                        lsp_store
 7491                            .merge_lsp_diagnostics(
 7492                                DiagnosticSourceKind::Pulled,
 7493                                diagnostic_updates,
 7494                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7495                                    DiagnosticSourceKind::Pulled => {
 7496                                        old_diagnostic.registration_id != registration_id
 7497                                            || unchanged_buffers
 7498                                                .get(&old_diagnostic.registration_id)
 7499                                                .is_some_and(|unchanged_buffers| {
 7500                                                    unchanged_buffers.contains(&document_uri)
 7501                                                })
 7502                                    }
 7503                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7504                                        true
 7505                                    }
 7506                                },
 7507                                cx,
 7508                            )
 7509                            .log_err();
 7510                    }
 7511                }
 7512            })
 7513        })
 7514    }
 7515
 7516    pub fn signature_help<T: ToPointUtf16>(
 7517        &mut self,
 7518        buffer: &Entity<Buffer>,
 7519        position: T,
 7520        cx: &mut Context<Self>,
 7521    ) -> Task<Option<Vec<SignatureHelp>>> {
 7522        let position = position.to_point_utf16(buffer.read(cx));
 7523
 7524        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7525            let request = GetSignatureHelp { position };
 7526            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7527                return Task::ready(None);
 7528            }
 7529            let request_timeout = ProjectSettings::get_global(cx)
 7530                .global_lsp_settings
 7531                .get_request_timeout();
 7532            let request_task = client.request_lsp(
 7533                upstream_project_id,
 7534                None,
 7535                request_timeout,
 7536                cx.background_executor().clone(),
 7537                request.to_proto(upstream_project_id, buffer.read(cx)),
 7538            );
 7539            let buffer = buffer.clone();
 7540            cx.spawn(async move |weak_lsp_store, cx| {
 7541                let lsp_store = weak_lsp_store.upgrade()?;
 7542                let signatures = join_all(
 7543                    request_task
 7544                        .await
 7545                        .log_err()
 7546                        .flatten()
 7547                        .map(|response| response.payload)
 7548                        .unwrap_or_default()
 7549                        .into_iter()
 7550                        .map(|response| {
 7551                            let response = GetSignatureHelp { position }.response_from_proto(
 7552                                response.response,
 7553                                lsp_store.clone(),
 7554                                buffer.clone(),
 7555                                cx.clone(),
 7556                            );
 7557                            async move { response.await.log_err().flatten() }
 7558                        }),
 7559                )
 7560                .await
 7561                .into_iter()
 7562                .flatten()
 7563                .collect();
 7564                Some(signatures)
 7565            })
 7566        } else {
 7567            let all_actions_task = self.request_multiple_lsp_locally(
 7568                buffer,
 7569                Some(position),
 7570                GetSignatureHelp { position },
 7571                cx,
 7572            );
 7573            cx.background_spawn(async move {
 7574                Some(
 7575                    all_actions_task
 7576                        .await
 7577                        .into_iter()
 7578                        .flat_map(|(_, actions)| actions)
 7579                        .collect::<Vec<_>>(),
 7580                )
 7581            })
 7582        }
 7583    }
 7584
 7585    pub fn hover(
 7586        &mut self,
 7587        buffer: &Entity<Buffer>,
 7588        position: PointUtf16,
 7589        cx: &mut Context<Self>,
 7590    ) -> Task<Option<Vec<Hover>>> {
 7591        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7592            let request = GetHover { position };
 7593            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7594                return Task::ready(None);
 7595            }
 7596            let request_timeout = ProjectSettings::get_global(cx)
 7597                .global_lsp_settings
 7598                .get_request_timeout();
 7599            let request_task = client.request_lsp(
 7600                upstream_project_id,
 7601                None,
 7602                request_timeout,
 7603                cx.background_executor().clone(),
 7604                request.to_proto(upstream_project_id, buffer.read(cx)),
 7605            );
 7606            let buffer = buffer.clone();
 7607            cx.spawn(async move |weak_lsp_store, cx| {
 7608                let lsp_store = weak_lsp_store.upgrade()?;
 7609                let hovers = join_all(
 7610                    request_task
 7611                        .await
 7612                        .log_err()
 7613                        .flatten()
 7614                        .map(|response| response.payload)
 7615                        .unwrap_or_default()
 7616                        .into_iter()
 7617                        .map(|response| {
 7618                            let response = GetHover { position }.response_from_proto(
 7619                                response.response,
 7620                                lsp_store.clone(),
 7621                                buffer.clone(),
 7622                                cx.clone(),
 7623                            );
 7624                            async move {
 7625                                response
 7626                                    .await
 7627                                    .log_err()
 7628                                    .flatten()
 7629                                    .and_then(remove_empty_hover_blocks)
 7630                            }
 7631                        }),
 7632                )
 7633                .await
 7634                .into_iter()
 7635                .flatten()
 7636                .collect();
 7637                Some(hovers)
 7638            })
 7639        } else {
 7640            let all_actions_task = self.request_multiple_lsp_locally(
 7641                buffer,
 7642                Some(position),
 7643                GetHover { position },
 7644                cx,
 7645            );
 7646            cx.background_spawn(async move {
 7647                Some(
 7648                    all_actions_task
 7649                        .await
 7650                        .into_iter()
 7651                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7652                        .collect::<Vec<Hover>>(),
 7653                )
 7654            })
 7655        }
 7656    }
 7657
 7658    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7659        let language_registry = self.languages.clone();
 7660
 7661        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7662            let request = upstream_client.request(proto::GetProjectSymbols {
 7663                project_id: *project_id,
 7664                query: query.to_string(),
 7665            });
 7666            cx.foreground_executor().spawn(async move {
 7667                let response = request.await?;
 7668                let mut symbols = Vec::new();
 7669                let core_symbols = response
 7670                    .symbols
 7671                    .into_iter()
 7672                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7673                    .collect::<Vec<_>>();
 7674                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7675                    .await;
 7676                Ok(symbols)
 7677            })
 7678        } else if let Some(local) = self.as_local() {
 7679            struct WorkspaceSymbolsResult {
 7680                server_id: LanguageServerId,
 7681                lsp_adapter: Arc<CachedLspAdapter>,
 7682                worktree: WeakEntity<Worktree>,
 7683                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7684            }
 7685
 7686            let mut requests = Vec::new();
 7687            let mut requested_servers = BTreeSet::new();
 7688            let request_timeout = ProjectSettings::get_global(cx)
 7689                .global_lsp_settings
 7690                .get_request_timeout();
 7691
 7692            for (seed, state) in local.language_server_ids.iter() {
 7693                let Some(worktree_handle) = self
 7694                    .worktree_store
 7695                    .read(cx)
 7696                    .worktree_for_id(seed.worktree_id, cx)
 7697                else {
 7698                    continue;
 7699                };
 7700
 7701                let worktree = worktree_handle.read(cx);
 7702                if !worktree.is_visible() {
 7703                    continue;
 7704                }
 7705
 7706                if !requested_servers.insert(state.id) {
 7707                    continue;
 7708                }
 7709
 7710                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7711                    Some(LanguageServerState::Running {
 7712                        adapter, server, ..
 7713                    }) => (adapter.clone(), server),
 7714
 7715                    _ => continue,
 7716                };
 7717
 7718                let supports_workspace_symbol_request =
 7719                    match server.capabilities().workspace_symbol_provider {
 7720                        Some(OneOf::Left(supported)) => supported,
 7721                        Some(OneOf::Right(_)) => true,
 7722                        None => false,
 7723                    };
 7724
 7725                if !supports_workspace_symbol_request {
 7726                    continue;
 7727                }
 7728
 7729                let worktree_handle = worktree_handle.clone();
 7730                let server_id = server.server_id();
 7731                requests.push(
 7732                    server
 7733                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7734                            lsp::WorkspaceSymbolParams {
 7735                                query: query.to_string(),
 7736                                ..Default::default()
 7737                            },
 7738                            request_timeout,
 7739                        )
 7740                        .map(move |response| {
 7741                            let lsp_symbols = response
 7742                                .into_response()
 7743                                .context("workspace symbols request")
 7744                                .log_err()
 7745                                .flatten()
 7746                                .map(|symbol_response| match symbol_response {
 7747                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7748                                        flat_responses
 7749                                            .into_iter()
 7750                                            .map(|lsp_symbol| {
 7751                                                (
 7752                                                    lsp_symbol.name,
 7753                                                    lsp_symbol.kind,
 7754                                                    lsp_symbol.location,
 7755                                                    lsp_symbol.container_name,
 7756                                                )
 7757                                            })
 7758                                            .collect::<Vec<_>>()
 7759                                    }
 7760                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7761                                        nested_responses
 7762                                            .into_iter()
 7763                                            .filter_map(|lsp_symbol| {
 7764                                                let location = match lsp_symbol.location {
 7765                                                    OneOf::Left(location) => location,
 7766                                                    OneOf::Right(_) => {
 7767                                                        log::error!(
 7768                                                            "Unexpected: client capabilities \
 7769                                                            forbid symbol resolutions in \
 7770                                                            workspace.symbol.resolveSupport"
 7771                                                        );
 7772                                                        return None;
 7773                                                    }
 7774                                                };
 7775                                                Some((
 7776                                                    lsp_symbol.name,
 7777                                                    lsp_symbol.kind,
 7778                                                    location,
 7779                                                    lsp_symbol.container_name,
 7780                                                ))
 7781                                            })
 7782                                            .collect::<Vec<_>>()
 7783                                    }
 7784                                })
 7785                                .unwrap_or_default();
 7786
 7787                            WorkspaceSymbolsResult {
 7788                                server_id,
 7789                                lsp_adapter,
 7790                                worktree: worktree_handle.downgrade(),
 7791                                lsp_symbols,
 7792                            }
 7793                        }),
 7794                );
 7795            }
 7796
 7797            cx.spawn(async move |this, cx| {
 7798                let responses = futures::future::join_all(requests).await;
 7799                let this = match this.upgrade() {
 7800                    Some(this) => this,
 7801                    None => return Ok(Vec::new()),
 7802                };
 7803
 7804                let mut symbols = Vec::new();
 7805                for result in responses {
 7806                    let core_symbols = this.update(cx, |this, cx| {
 7807                        result
 7808                            .lsp_symbols
 7809                            .into_iter()
 7810                            .filter_map(
 7811                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7812                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7813                                    let source_worktree = result.worktree.upgrade()?;
 7814                                    let source_worktree_id = source_worktree.read(cx).id();
 7815
 7816                                    let path = if let Some((tree, rel_path)) =
 7817                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7818                                    {
 7819                                        let worktree_id = tree.read(cx).id();
 7820                                        SymbolLocation::InProject(ProjectPath {
 7821                                            worktree_id,
 7822                                            path: rel_path,
 7823                                        })
 7824                                    } else {
 7825                                        SymbolLocation::OutsideProject {
 7826                                            signature: this.symbol_signature(&abs_path),
 7827                                            abs_path: abs_path.into(),
 7828                                        }
 7829                                    };
 7830
 7831                                    Some(CoreSymbol {
 7832                                        source_language_server_id: result.server_id,
 7833                                        language_server_name: result.lsp_adapter.name.clone(),
 7834                                        source_worktree_id,
 7835                                        path,
 7836                                        kind: symbol_kind,
 7837                                        name: collapse_newlines(&symbol_name, ""),
 7838                                        range: range_from_lsp(symbol_location.range),
 7839                                        container_name: container_name
 7840                                            .map(|c| collapse_newlines(&c, "")),
 7841                                    })
 7842                                },
 7843                            )
 7844                            .collect::<Vec<_>>()
 7845                    });
 7846
 7847                    populate_labels_for_symbols(
 7848                        core_symbols,
 7849                        &language_registry,
 7850                        Some(result.lsp_adapter),
 7851                        &mut symbols,
 7852                    )
 7853                    .await;
 7854                }
 7855
 7856                Ok(symbols)
 7857            })
 7858        } else {
 7859            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7860        }
 7861    }
 7862
 7863    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7864        let mut summary = DiagnosticSummary::default();
 7865        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7866            summary.error_count += path_summary.error_count;
 7867            summary.warning_count += path_summary.warning_count;
 7868        }
 7869        summary
 7870    }
 7871
 7872    /// Returns the diagnostic summary for a specific project path.
 7873    pub fn diagnostic_summary_for_path(
 7874        &self,
 7875        project_path: &ProjectPath,
 7876        _: &App,
 7877    ) -> DiagnosticSummary {
 7878        if let Some(summaries) = self
 7879            .diagnostic_summaries
 7880            .get(&project_path.worktree_id)
 7881            .and_then(|map| map.get(&project_path.path))
 7882        {
 7883            let (error_count, warning_count) = summaries.iter().fold(
 7884                (0, 0),
 7885                |(error_count, warning_count), (_language_server_id, summary)| {
 7886                    (
 7887                        error_count + summary.error_count,
 7888                        warning_count + summary.warning_count,
 7889                    )
 7890                },
 7891            );
 7892
 7893            DiagnosticSummary {
 7894                error_count,
 7895                warning_count,
 7896            }
 7897        } else {
 7898            DiagnosticSummary::default()
 7899        }
 7900    }
 7901
 7902    pub fn diagnostic_summaries<'a>(
 7903        &'a self,
 7904        include_ignored: bool,
 7905        cx: &'a App,
 7906    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7907        self.worktree_store
 7908            .read(cx)
 7909            .visible_worktrees(cx)
 7910            .filter_map(|worktree| {
 7911                let worktree = worktree.read(cx);
 7912                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7913            })
 7914            .flat_map(move |(worktree, summaries)| {
 7915                let worktree_id = worktree.id();
 7916                summaries
 7917                    .iter()
 7918                    .filter(move |(path, _)| {
 7919                        include_ignored
 7920                            || worktree
 7921                                .entry_for_path(path.as_ref())
 7922                                .is_some_and(|entry| !entry.is_ignored)
 7923                    })
 7924                    .flat_map(move |(path, summaries)| {
 7925                        summaries.iter().map(move |(server_id, summary)| {
 7926                            (
 7927                                ProjectPath {
 7928                                    worktree_id,
 7929                                    path: path.clone(),
 7930                                },
 7931                                *server_id,
 7932                                *summary,
 7933                            )
 7934                        })
 7935                    })
 7936            })
 7937    }
 7938
 7939    pub fn on_buffer_edited(
 7940        &mut self,
 7941        buffer: Entity<Buffer>,
 7942        cx: &mut Context<Self>,
 7943    ) -> Option<()> {
 7944        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7945            Some(
 7946                self.as_local()?
 7947                    .language_servers_for_buffer(buffer, cx)
 7948                    .map(|i| i.1.clone())
 7949                    .collect(),
 7950            )
 7951        })?;
 7952
 7953        let buffer = buffer.read(cx);
 7954        let file = File::from_dyn(buffer.file())?;
 7955        let abs_path = file.as_local()?.abs_path(cx);
 7956        let uri = lsp::Uri::from_file_path(&abs_path)
 7957            .ok()
 7958            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7959            .log_err()?;
 7960        let next_snapshot = buffer.text_snapshot();
 7961        for language_server in language_servers {
 7962            let language_server = language_server.clone();
 7963
 7964            let buffer_snapshots = self
 7965                .as_local_mut()?
 7966                .buffer_snapshots
 7967                .get_mut(&buffer.remote_id())
 7968                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7969            let previous_snapshot = buffer_snapshots.last()?;
 7970
 7971            let build_incremental_change = || {
 7972                buffer
 7973                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7974                        previous_snapshot.snapshot.version(),
 7975                    )
 7976                    .map(|edit| {
 7977                        let edit_start = edit.new.start.0;
 7978                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7979                        let new_text = next_snapshot
 7980                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7981                            .collect();
 7982                        lsp::TextDocumentContentChangeEvent {
 7983                            range: Some(lsp::Range::new(
 7984                                point_to_lsp(edit_start),
 7985                                point_to_lsp(edit_end),
 7986                            )),
 7987                            range_length: None,
 7988                            text: new_text,
 7989                        }
 7990                    })
 7991                    .collect()
 7992            };
 7993
 7994            let document_sync_kind = language_server
 7995                .capabilities()
 7996                .text_document_sync
 7997                .as_ref()
 7998                .and_then(|sync| match sync {
 7999                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 8000                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 8001                });
 8002
 8003            let content_changes: Vec<_> = match document_sync_kind {
 8004                Some(lsp::TextDocumentSyncKind::FULL) => {
 8005                    vec![lsp::TextDocumentContentChangeEvent {
 8006                        range: None,
 8007                        range_length: None,
 8008                        text: next_snapshot.text(),
 8009                    }]
 8010                }
 8011                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8012                _ => {
 8013                    #[cfg(any(test, feature = "test-support"))]
 8014                    {
 8015                        build_incremental_change()
 8016                    }
 8017
 8018                    #[cfg(not(any(test, feature = "test-support")))]
 8019                    {
 8020                        continue;
 8021                    }
 8022                }
 8023            };
 8024
 8025            let next_version = previous_snapshot.version + 1;
 8026            buffer_snapshots.push(LspBufferSnapshot {
 8027                version: next_version,
 8028                snapshot: next_snapshot.clone(),
 8029            });
 8030
 8031            language_server
 8032                .notify::<lsp::notification::DidChangeTextDocument>(
 8033                    lsp::DidChangeTextDocumentParams {
 8034                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8035                            uri.clone(),
 8036                            next_version,
 8037                        ),
 8038                        content_changes,
 8039                    },
 8040                )
 8041                .ok();
 8042            self.pull_workspace_diagnostics(language_server.server_id());
 8043        }
 8044
 8045        None
 8046    }
 8047
 8048    pub fn on_buffer_saved(
 8049        &mut self,
 8050        buffer: Entity<Buffer>,
 8051        cx: &mut Context<Self>,
 8052    ) -> Option<()> {
 8053        let file = File::from_dyn(buffer.read(cx).file())?;
 8054        let worktree_id = file.worktree_id(cx);
 8055        let abs_path = file.as_local()?.abs_path(cx);
 8056        let text_document = lsp::TextDocumentIdentifier {
 8057            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8058        };
 8059        let local = self.as_local()?;
 8060
 8061        for server in local.language_servers_for_worktree(worktree_id) {
 8062            if let Some(include_text) = include_text(server.as_ref()) {
 8063                let text = if include_text {
 8064                    Some(buffer.read(cx).text())
 8065                } else {
 8066                    None
 8067                };
 8068                server
 8069                    .notify::<lsp::notification::DidSaveTextDocument>(
 8070                        lsp::DidSaveTextDocumentParams {
 8071                            text_document: text_document.clone(),
 8072                            text,
 8073                        },
 8074                    )
 8075                    .ok();
 8076            }
 8077        }
 8078
 8079        let language_servers = buffer.update(cx, |buffer, cx| {
 8080            local.language_server_ids_for_buffer(buffer, cx)
 8081        });
 8082        for language_server_id in language_servers {
 8083            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8084        }
 8085
 8086        None
 8087    }
 8088
 8089    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8090        maybe!(async move {
 8091            let mut refreshed_servers = HashSet::default();
 8092            let servers = lsp_store
 8093                .update(cx, |lsp_store, cx| {
 8094                    let local = lsp_store.as_local()?;
 8095
 8096                    let servers = local
 8097                        .language_server_ids
 8098                        .iter()
 8099                        .filter_map(|(seed, state)| {
 8100                            let worktree = lsp_store
 8101                                .worktree_store
 8102                                .read(cx)
 8103                                .worktree_for_id(seed.worktree_id, cx);
 8104                            let delegate: Arc<dyn LspAdapterDelegate> =
 8105                                worktree.map(|worktree| {
 8106                                    LocalLspAdapterDelegate::new(
 8107                                        local.languages.clone(),
 8108                                        &local.environment,
 8109                                        cx.weak_entity(),
 8110                                        &worktree,
 8111                                        local.http_client.clone(),
 8112                                        local.fs.clone(),
 8113                                        cx,
 8114                                    )
 8115                                })?;
 8116                            let server_id = state.id;
 8117
 8118                            let states = local.language_servers.get(&server_id)?;
 8119
 8120                            match states {
 8121                                LanguageServerState::Starting { .. } => None,
 8122                                LanguageServerState::Running {
 8123                                    adapter, server, ..
 8124                                } => {
 8125                                    let adapter = adapter.clone();
 8126                                    let server = server.clone();
 8127                                    refreshed_servers.insert(server.name());
 8128                                    let toolchain = seed.toolchain.clone();
 8129                                    Some(cx.spawn(async move |_, cx| {
 8130                                        let settings =
 8131                                            LocalLspStore::workspace_configuration_for_adapter(
 8132                                                adapter.adapter.clone(),
 8133                                                &delegate,
 8134                                                toolchain,
 8135                                                None,
 8136                                                cx,
 8137                                            )
 8138                                            .await
 8139                                            .ok()?;
 8140                                        server
 8141                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8142                                                lsp::DidChangeConfigurationParams { settings },
 8143                                            )
 8144                                            .ok()?;
 8145                                        Some(())
 8146                                    }))
 8147                                }
 8148                            }
 8149                        })
 8150                        .collect::<Vec<_>>();
 8151
 8152                    Some(servers)
 8153                })
 8154                .ok()
 8155                .flatten()?;
 8156
 8157            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8158            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8159            // to stop and unregister its language server wrapper.
 8160            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8161            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8162            let _: Vec<Option<()>> = join_all(servers).await;
 8163
 8164            Some(())
 8165        })
 8166        .await;
 8167    }
 8168
 8169    fn maintain_workspace_config(
 8170        external_refresh_requests: watch::Receiver<()>,
 8171        cx: &mut Context<Self>,
 8172    ) -> Task<Result<()>> {
 8173        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8174        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8175
 8176        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8177            *settings_changed_tx.borrow_mut() = ();
 8178        });
 8179
 8180        let mut joint_future =
 8181            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8182        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8183        // - 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).
 8184        // - 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.
 8185        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8186        // - 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,
 8187        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8188        cx.spawn(async move |this, cx| {
 8189            while let Some(()) = joint_future.next().await {
 8190                this.update(cx, |this, cx| {
 8191                    this.refresh_server_tree(cx);
 8192                })
 8193                .ok();
 8194
 8195                Self::refresh_workspace_configurations(&this, cx).await;
 8196            }
 8197
 8198            drop(settings_observation);
 8199            anyhow::Ok(())
 8200        })
 8201    }
 8202
 8203    pub fn running_language_servers_for_local_buffer<'a>(
 8204        &'a self,
 8205        buffer: &Buffer,
 8206        cx: &mut App,
 8207    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8208        let local = self.as_local();
 8209        let language_server_ids = local
 8210            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8211            .unwrap_or_default();
 8212
 8213        language_server_ids
 8214            .into_iter()
 8215            .filter_map(
 8216                move |server_id| match local?.language_servers.get(&server_id)? {
 8217                    LanguageServerState::Running {
 8218                        adapter, server, ..
 8219                    } => Some((adapter, server)),
 8220                    _ => None,
 8221                },
 8222            )
 8223    }
 8224
 8225    pub fn language_servers_for_local_buffer(
 8226        &self,
 8227        buffer: &Buffer,
 8228        cx: &mut App,
 8229    ) -> Vec<LanguageServerId> {
 8230        let local = self.as_local();
 8231        local
 8232            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8233            .unwrap_or_default()
 8234    }
 8235
 8236    pub fn language_server_for_local_buffer<'a>(
 8237        &'a self,
 8238        buffer: &'a Buffer,
 8239        server_id: LanguageServerId,
 8240        cx: &'a mut App,
 8241    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8242        self.as_local()?
 8243            .language_servers_for_buffer(buffer, cx)
 8244            .find(|(_, s)| s.server_id() == server_id)
 8245    }
 8246
 8247    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8248        self.diagnostic_summaries.remove(&id_to_remove);
 8249        if let Some(local) = self.as_local_mut() {
 8250            let to_remove = local.remove_worktree(id_to_remove, cx);
 8251            for server in to_remove {
 8252                self.language_server_statuses.remove(&server);
 8253            }
 8254        }
 8255    }
 8256
 8257    fn invalidate_diagnostic_summaries_for_removed_entries(
 8258        &mut self,
 8259        worktree_id: WorktreeId,
 8260        changes: &UpdatedEntriesSet,
 8261        cx: &mut Context<Self>,
 8262    ) {
 8263        let Some(summaries_for_tree) = self.diagnostic_summaries.get_mut(&worktree_id) else {
 8264            return;
 8265        };
 8266
 8267        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
 8268        let mut cleared_server_ids: HashSet<LanguageServerId> = HashSet::default();
 8269        let downstream = self.downstream_client.clone();
 8270
 8271        for (path, _, _) in changes
 8272            .iter()
 8273            .filter(|(_, _, change)| *change == PathChange::Removed)
 8274        {
 8275            if let Some(summaries_by_server_id) = summaries_for_tree.remove(path) {
 8276                for (server_id, _) in &summaries_by_server_id {
 8277                    cleared_server_ids.insert(*server_id);
 8278                    if let Some((client, project_id)) = &downstream {
 8279                        client
 8280                            .send(proto::UpdateDiagnosticSummary {
 8281                                project_id: *project_id,
 8282                                worktree_id: worktree_id.to_proto(),
 8283                                summary: Some(proto::DiagnosticSummary {
 8284                                    path: path.as_ref().to_proto(),
 8285                                    language_server_id: server_id.0 as u64,
 8286                                    error_count: 0,
 8287                                    warning_count: 0,
 8288                                }),
 8289                                more_summaries: Vec::new(),
 8290                            })
 8291                            .ok();
 8292                    }
 8293                }
 8294                cleared_paths.push(ProjectPath {
 8295                    worktree_id,
 8296                    path: path.clone(),
 8297                });
 8298            }
 8299        }
 8300
 8301        if !cleared_paths.is_empty() {
 8302            for server_id in cleared_server_ids {
 8303                cx.emit(LspStoreEvent::DiagnosticsUpdated {
 8304                    server_id,
 8305                    paths: cleared_paths.clone(),
 8306                });
 8307            }
 8308        }
 8309    }
 8310
 8311    pub fn shared(
 8312        &mut self,
 8313        project_id: u64,
 8314        downstream_client: AnyProtoClient,
 8315        _: &mut Context<Self>,
 8316    ) {
 8317        self.downstream_client = Some((downstream_client.clone(), project_id));
 8318
 8319        for (server_id, status) in &self.language_server_statuses {
 8320            if let Some(server) = self.language_server_for_id(*server_id) {
 8321                downstream_client
 8322                    .send(proto::StartLanguageServer {
 8323                        project_id,
 8324                        server: Some(proto::LanguageServer {
 8325                            id: server_id.to_proto(),
 8326                            name: status.name.to_string(),
 8327                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8328                        }),
 8329                        capabilities: serde_json::to_string(&server.capabilities())
 8330                            .expect("serializing server LSP capabilities"),
 8331                    })
 8332                    .log_err();
 8333            }
 8334        }
 8335    }
 8336
 8337    pub fn disconnected_from_host(&mut self) {
 8338        self.downstream_client.take();
 8339    }
 8340
 8341    pub fn disconnected_from_ssh_remote(&mut self) {
 8342        if let LspStoreMode::Remote(RemoteLspStore {
 8343            upstream_client, ..
 8344        }) = &mut self.mode
 8345        {
 8346            upstream_client.take();
 8347        }
 8348    }
 8349
 8350    pub(crate) fn set_language_server_statuses_from_proto(
 8351        &mut self,
 8352        project: WeakEntity<Project>,
 8353        language_servers: Vec<proto::LanguageServer>,
 8354        server_capabilities: Vec<String>,
 8355        cx: &mut Context<Self>,
 8356    ) {
 8357        let lsp_logs = cx
 8358            .try_global::<GlobalLogStore>()
 8359            .map(|lsp_store| lsp_store.0.clone());
 8360
 8361        self.language_server_statuses = language_servers
 8362            .into_iter()
 8363            .zip(server_capabilities)
 8364            .map(|(server, server_capabilities)| {
 8365                let server_id = LanguageServerId(server.id as usize);
 8366                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8367                    self.lsp_server_capabilities
 8368                        .insert(server_id, server_capabilities);
 8369                }
 8370
 8371                let name = LanguageServerName::from_proto(server.name);
 8372                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8373
 8374                if let Some(lsp_logs) = &lsp_logs {
 8375                    lsp_logs.update(cx, |lsp_logs, cx| {
 8376                        lsp_logs.add_language_server(
 8377                            // Only remote clients get their language servers set from proto
 8378                            LanguageServerKind::Remote {
 8379                                project: project.clone(),
 8380                            },
 8381                            server_id,
 8382                            Some(name.clone()),
 8383                            worktree,
 8384                            None,
 8385                            cx,
 8386                        );
 8387                    });
 8388                }
 8389
 8390                (
 8391                    server_id,
 8392                    LanguageServerStatus {
 8393                        name,
 8394                        server_version: None,
 8395                        server_readable_version: None,
 8396                        pending_work: Default::default(),
 8397                        has_pending_diagnostic_updates: false,
 8398                        progress_tokens: Default::default(),
 8399                        worktree,
 8400                        binary: None,
 8401                        configuration: None,
 8402                        workspace_folders: BTreeSet::new(),
 8403                        process_id: None,
 8404                    },
 8405                )
 8406            })
 8407            .collect();
 8408    }
 8409
 8410    #[cfg(feature = "test-support")]
 8411    pub fn update_diagnostic_entries(
 8412        &mut self,
 8413        server_id: LanguageServerId,
 8414        abs_path: PathBuf,
 8415        result_id: Option<SharedString>,
 8416        version: Option<i32>,
 8417        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8418        cx: &mut Context<Self>,
 8419    ) -> anyhow::Result<()> {
 8420        self.merge_diagnostic_entries(
 8421            vec![DocumentDiagnosticsUpdate {
 8422                diagnostics: DocumentDiagnostics {
 8423                    diagnostics,
 8424                    document_abs_path: abs_path,
 8425                    version,
 8426                },
 8427                result_id,
 8428                server_id,
 8429                disk_based_sources: Cow::Borrowed(&[]),
 8430                registration_id: None,
 8431            }],
 8432            |_, _, _| false,
 8433            cx,
 8434        )?;
 8435        Ok(())
 8436    }
 8437
 8438    pub fn merge_diagnostic_entries<'a>(
 8439        &mut self,
 8440        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8441        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8442        cx: &mut Context<Self>,
 8443    ) -> anyhow::Result<()> {
 8444        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8445        let mut updated_diagnostics_paths = HashMap::default();
 8446        for mut update in diagnostic_updates {
 8447            let abs_path = &update.diagnostics.document_abs_path;
 8448            let server_id = update.server_id;
 8449            let Some((worktree, relative_path)) =
 8450                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8451            else {
 8452                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8453                return Ok(());
 8454            };
 8455
 8456            let worktree_id = worktree.read(cx).id();
 8457            let project_path = ProjectPath {
 8458                worktree_id,
 8459                path: relative_path,
 8460            };
 8461
 8462            let document_uri = lsp::Uri::from_file_path(abs_path)
 8463                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8464            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8465                let snapshot = buffer_handle.read(cx).snapshot();
 8466                let buffer = buffer_handle.read(cx);
 8467                let reused_diagnostics = buffer
 8468                    .buffer_diagnostics(Some(server_id))
 8469                    .iter()
 8470                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8471                    .map(|v| {
 8472                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8473                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8474                        DiagnosticEntry {
 8475                            range: start..end,
 8476                            diagnostic: v.diagnostic.clone(),
 8477                        }
 8478                    })
 8479                    .collect::<Vec<_>>();
 8480
 8481                self.as_local_mut()
 8482                    .context("cannot merge diagnostics on a remote LspStore")?
 8483                    .update_buffer_diagnostics(
 8484                        &buffer_handle,
 8485                        server_id,
 8486                        Some(update.registration_id),
 8487                        update.result_id,
 8488                        update.diagnostics.version,
 8489                        update.diagnostics.diagnostics.clone(),
 8490                        reused_diagnostics.clone(),
 8491                        cx,
 8492                    )?;
 8493
 8494                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8495            } else if let Some(local) = self.as_local() {
 8496                let reused_diagnostics = local
 8497                    .diagnostics
 8498                    .get(&worktree_id)
 8499                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8500                    .and_then(|diagnostics_by_server_id| {
 8501                        diagnostics_by_server_id
 8502                            .binary_search_by_key(&server_id, |e| e.0)
 8503                            .ok()
 8504                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8505                    })
 8506                    .into_iter()
 8507                    .flatten()
 8508                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8509
 8510                update
 8511                    .diagnostics
 8512                    .diagnostics
 8513                    .extend(reused_diagnostics.cloned());
 8514            }
 8515
 8516            let updated = worktree.update(cx, |worktree, cx| {
 8517                self.update_worktree_diagnostics(
 8518                    worktree.id(),
 8519                    server_id,
 8520                    project_path.path.clone(),
 8521                    update.diagnostics.diagnostics,
 8522                    cx,
 8523                )
 8524            })?;
 8525            match updated {
 8526                ControlFlow::Continue(new_summary) => {
 8527                    if let Some((project_id, new_summary)) = new_summary {
 8528                        match &mut diagnostics_summary {
 8529                            Some(diagnostics_summary) => {
 8530                                diagnostics_summary
 8531                                    .more_summaries
 8532                                    .push(proto::DiagnosticSummary {
 8533                                        path: project_path.path.as_ref().to_proto(),
 8534                                        language_server_id: server_id.0 as u64,
 8535                                        error_count: new_summary.error_count,
 8536                                        warning_count: new_summary.warning_count,
 8537                                    })
 8538                            }
 8539                            None => {
 8540                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8541                                    project_id,
 8542                                    worktree_id: worktree_id.to_proto(),
 8543                                    summary: Some(proto::DiagnosticSummary {
 8544                                        path: project_path.path.as_ref().to_proto(),
 8545                                        language_server_id: server_id.0 as u64,
 8546                                        error_count: new_summary.error_count,
 8547                                        warning_count: new_summary.warning_count,
 8548                                    }),
 8549                                    more_summaries: Vec::new(),
 8550                                })
 8551                            }
 8552                        }
 8553                    }
 8554                    updated_diagnostics_paths
 8555                        .entry(server_id)
 8556                        .or_insert_with(Vec::new)
 8557                        .push(project_path);
 8558                }
 8559                ControlFlow::Break(()) => {}
 8560            }
 8561        }
 8562
 8563        if let Some((diagnostics_summary, (downstream_client, _))) =
 8564            diagnostics_summary.zip(self.downstream_client.as_ref())
 8565        {
 8566            downstream_client.send(diagnostics_summary).log_err();
 8567        }
 8568        for (server_id, paths) in updated_diagnostics_paths {
 8569            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8570        }
 8571        Ok(())
 8572    }
 8573
 8574    fn update_worktree_diagnostics(
 8575        &mut self,
 8576        worktree_id: WorktreeId,
 8577        server_id: LanguageServerId,
 8578        path_in_worktree: Arc<RelPath>,
 8579        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8580        _: &mut Context<Worktree>,
 8581    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8582        let local = match &mut self.mode {
 8583            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8584            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8585        };
 8586
 8587        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8588        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8589        let summaries_by_server_id = summaries_for_tree
 8590            .entry(path_in_worktree.clone())
 8591            .or_default();
 8592
 8593        let old_summary = summaries_by_server_id
 8594            .remove(&server_id)
 8595            .unwrap_or_default();
 8596
 8597        let new_summary = DiagnosticSummary::new(&diagnostics);
 8598        if diagnostics.is_empty() {
 8599            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8600            {
 8601                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8602                    diagnostics_by_server_id.remove(ix);
 8603                }
 8604                if diagnostics_by_server_id.is_empty() {
 8605                    diagnostics_for_tree.remove(&path_in_worktree);
 8606                }
 8607            }
 8608        } else {
 8609            summaries_by_server_id.insert(server_id, new_summary);
 8610            let diagnostics_by_server_id = diagnostics_for_tree
 8611                .entry(path_in_worktree.clone())
 8612                .or_default();
 8613            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8614                Ok(ix) => {
 8615                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8616                }
 8617                Err(ix) => {
 8618                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8619                }
 8620            }
 8621        }
 8622
 8623        if !old_summary.is_empty() || !new_summary.is_empty() {
 8624            if let Some((_, project_id)) = &self.downstream_client {
 8625                Ok(ControlFlow::Continue(Some((
 8626                    *project_id,
 8627                    proto::DiagnosticSummary {
 8628                        path: path_in_worktree.to_proto(),
 8629                        language_server_id: server_id.0 as u64,
 8630                        error_count: new_summary.error_count as u32,
 8631                        warning_count: new_summary.warning_count as u32,
 8632                    },
 8633                ))))
 8634            } else {
 8635                Ok(ControlFlow::Continue(None))
 8636            }
 8637        } else {
 8638            Ok(ControlFlow::Break(()))
 8639        }
 8640    }
 8641
 8642    pub fn open_buffer_for_symbol(
 8643        &mut self,
 8644        symbol: &Symbol,
 8645        cx: &mut Context<Self>,
 8646    ) -> Task<Result<Entity<Buffer>>> {
 8647        if let Some((client, project_id)) = self.upstream_client() {
 8648            let request = client.request(proto::OpenBufferForSymbol {
 8649                project_id,
 8650                symbol: Some(Self::serialize_symbol(symbol)),
 8651            });
 8652            cx.spawn(async move |this, cx| {
 8653                let response = request.await?;
 8654                let buffer_id = BufferId::new(response.buffer_id)?;
 8655                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8656                    .await
 8657            })
 8658        } else if let Some(local) = self.as_local() {
 8659            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8660                seed.worktree_id == symbol.source_worktree_id
 8661                    && state.id == symbol.source_language_server_id
 8662                    && symbol.language_server_name == seed.name
 8663            });
 8664            if !is_valid {
 8665                return Task::ready(Err(anyhow!(
 8666                    "language server for worktree and language not found"
 8667                )));
 8668            };
 8669
 8670            let symbol_abs_path = match &symbol.path {
 8671                SymbolLocation::InProject(project_path) => self
 8672                    .worktree_store
 8673                    .read(cx)
 8674                    .absolutize(&project_path, cx)
 8675                    .context("no such worktree"),
 8676                SymbolLocation::OutsideProject {
 8677                    abs_path,
 8678                    signature: _,
 8679                } => Ok(abs_path.to_path_buf()),
 8680            };
 8681            let symbol_abs_path = match symbol_abs_path {
 8682                Ok(abs_path) => abs_path,
 8683                Err(err) => return Task::ready(Err(err)),
 8684            };
 8685            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8686                uri
 8687            } else {
 8688                return Task::ready(Err(anyhow!("invalid symbol path")));
 8689            };
 8690
 8691            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8692        } else {
 8693            Task::ready(Err(anyhow!("no upstream client or local store")))
 8694        }
 8695    }
 8696
 8697    pub(crate) fn open_local_buffer_via_lsp(
 8698        &mut self,
 8699        abs_path: lsp::Uri,
 8700        language_server_id: LanguageServerId,
 8701        cx: &mut Context<Self>,
 8702    ) -> Task<Result<Entity<Buffer>>> {
 8703        let path_style = self.worktree_store.read(cx).path_style();
 8704        cx.spawn(async move |lsp_store, cx| {
 8705            // Escape percent-encoded string.
 8706            let current_scheme = abs_path.scheme().to_owned();
 8707            // Uri is immutable, so we can't modify the scheme
 8708
 8709            let abs_path = abs_path
 8710                .to_file_path_ext(path_style)
 8711                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8712            let p = abs_path.clone();
 8713            let yarn_worktree = lsp_store
 8714                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8715                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8716                        cx.spawn(async move |this, cx| {
 8717                            let t = this
 8718                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8719                                .ok()?;
 8720                            t.await
 8721                        })
 8722                    }),
 8723                    None => Task::ready(None),
 8724                })?
 8725                .await;
 8726            let (worktree_root_target, known_relative_path) =
 8727                if let Some((zip_root, relative_path)) = yarn_worktree {
 8728                    (zip_root, Some(relative_path))
 8729                } else {
 8730                    (Arc::<Path>::from(abs_path.as_path()), None)
 8731                };
 8732            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8733                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8734                    worktree_store.find_worktree(&worktree_root_target, cx)
 8735                })
 8736            })?;
 8737            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8738                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8739                (result.0, relative_path, None)
 8740            } else {
 8741                let worktree = lsp_store
 8742                    .update(cx, |lsp_store, cx| {
 8743                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8744                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8745                        })
 8746                    })?
 8747                    .await?;
 8748                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8749                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8750                    lsp_store
 8751                        .update(cx, |lsp_store, cx| {
 8752                            if let Some(local) = lsp_store.as_local_mut() {
 8753                                local.register_language_server_for_invisible_worktree(
 8754                                    &worktree,
 8755                                    language_server_id,
 8756                                    cx,
 8757                                )
 8758                            }
 8759                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8760                                Some(status) => status.worktree,
 8761                                None => None,
 8762                            }
 8763                        })
 8764                        .ok()
 8765                        .flatten()
 8766                        .zip(Some(worktree_root.clone()))
 8767                } else {
 8768                    None
 8769                };
 8770                let relative_path = if let Some(known_path) = known_relative_path {
 8771                    known_path
 8772                } else {
 8773                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8774                        .into_arc()
 8775                };
 8776                (worktree, relative_path, source_ws)
 8777            };
 8778            let project_path = ProjectPath {
 8779                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8780                path: relative_path,
 8781            };
 8782            let buffer = lsp_store
 8783                .update(cx, |lsp_store, cx| {
 8784                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8785                        buffer_store.open_buffer(project_path, cx)
 8786                    })
 8787                })?
 8788                .await?;
 8789            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8790            if let Some((source_ws, worktree_root)) = source_ws {
 8791                buffer.update(cx, |buffer, cx| {
 8792                    let settings = WorktreeSettings::get(
 8793                        Some(
 8794                            (&ProjectPath {
 8795                                worktree_id: source_ws,
 8796                                path: Arc::from(RelPath::empty()),
 8797                            })
 8798                                .into(),
 8799                        ),
 8800                        cx,
 8801                    );
 8802                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8803                    if is_read_only {
 8804                        buffer.set_capability(Capability::ReadOnly, cx);
 8805                    }
 8806                });
 8807            }
 8808            Ok(buffer)
 8809        })
 8810    }
 8811
 8812    fn local_lsp_servers_for_buffer(
 8813        &self,
 8814        buffer: &Entity<Buffer>,
 8815        cx: &mut Context<Self>,
 8816    ) -> Vec<LanguageServerId> {
 8817        let Some(local) = self.as_local() else {
 8818            return Vec::new();
 8819        };
 8820
 8821        let snapshot = buffer.read(cx).snapshot();
 8822
 8823        buffer.update(cx, |buffer, cx| {
 8824            local
 8825                .language_servers_for_buffer(buffer, cx)
 8826                .map(|(_, server)| server.server_id())
 8827                .filter(|server_id| {
 8828                    self.as_local().is_none_or(|local| {
 8829                        local
 8830                            .buffers_opened_in_servers
 8831                            .get(&snapshot.remote_id())
 8832                            .is_some_and(|servers| servers.contains(server_id))
 8833                    })
 8834                })
 8835                .collect()
 8836        })
 8837    }
 8838
 8839    fn request_multiple_lsp_locally<P, R>(
 8840        &mut self,
 8841        buffer: &Entity<Buffer>,
 8842        position: Option<P>,
 8843        request: R,
 8844        cx: &mut Context<Self>,
 8845    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8846    where
 8847        P: ToOffset,
 8848        R: LspCommand + Clone,
 8849        <R::LspRequest as lsp::request::Request>::Result: Send,
 8850        <R::LspRequest as lsp::request::Request>::Params: Send,
 8851    {
 8852        let Some(local) = self.as_local() else {
 8853            return Task::ready(Vec::new());
 8854        };
 8855
 8856        let snapshot = buffer.read(cx).snapshot();
 8857        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8858
 8859        let server_ids = buffer.update(cx, |buffer, cx| {
 8860            local
 8861                .language_servers_for_buffer(buffer, cx)
 8862                .filter(|(adapter, _)| {
 8863                    scope
 8864                        .as_ref()
 8865                        .map(|scope| scope.language_allowed(&adapter.name))
 8866                        .unwrap_or(true)
 8867                })
 8868                .map(|(_, server)| server.server_id())
 8869                .filter(|server_id| {
 8870                    self.as_local().is_none_or(|local| {
 8871                        local
 8872                            .buffers_opened_in_servers
 8873                            .get(&snapshot.remote_id())
 8874                            .is_some_and(|servers| servers.contains(server_id))
 8875                    })
 8876                })
 8877                .collect::<Vec<_>>()
 8878        });
 8879
 8880        let mut response_results = server_ids
 8881            .into_iter()
 8882            .map(|server_id| {
 8883                let task = self.request_lsp(
 8884                    buffer.clone(),
 8885                    LanguageServerToQuery::Other(server_id),
 8886                    request.clone(),
 8887                    cx,
 8888                );
 8889                async move { (server_id, task.await) }
 8890            })
 8891            .collect::<FuturesUnordered<_>>();
 8892
 8893        cx.background_spawn(async move {
 8894            let mut responses = Vec::with_capacity(response_results.len());
 8895            while let Some((server_id, response_result)) = response_results.next().await {
 8896                match response_result {
 8897                    Ok(response) => responses.push((server_id, response)),
 8898                    // rust-analyzer likes to error with this when its still loading up
 8899                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8900                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8901                }
 8902            }
 8903            responses
 8904        })
 8905    }
 8906
 8907    async fn handle_lsp_get_completions(
 8908        this: Entity<Self>,
 8909        envelope: TypedEnvelope<proto::GetCompletions>,
 8910        mut cx: AsyncApp,
 8911    ) -> Result<proto::GetCompletionsResponse> {
 8912        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8913
 8914        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8915        let buffer_handle = this.update(&mut cx, |this, cx| {
 8916            this.buffer_store.read(cx).get_existing(buffer_id)
 8917        })?;
 8918        let request = GetCompletions::from_proto(
 8919            envelope.payload,
 8920            this.clone(),
 8921            buffer_handle.clone(),
 8922            cx.clone(),
 8923        )
 8924        .await?;
 8925
 8926        let server_to_query = match request.server_id {
 8927            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8928            None => LanguageServerToQuery::FirstCapable,
 8929        };
 8930
 8931        let response = this
 8932            .update(&mut cx, |this, cx| {
 8933                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8934            })
 8935            .await?;
 8936        this.update(&mut cx, |this, cx| {
 8937            Ok(GetCompletions::response_to_proto(
 8938                response,
 8939                this,
 8940                sender_id,
 8941                &buffer_handle.read(cx).version(),
 8942                cx,
 8943            ))
 8944        })
 8945    }
 8946
 8947    async fn handle_lsp_command<T: LspCommand>(
 8948        this: Entity<Self>,
 8949        envelope: TypedEnvelope<T::ProtoRequest>,
 8950        mut cx: AsyncApp,
 8951    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8952    where
 8953        <T::LspRequest as lsp::request::Request>::Params: Send,
 8954        <T::LspRequest as lsp::request::Request>::Result: Send,
 8955    {
 8956        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8957        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8958        let buffer_handle = this.update(&mut cx, |this, cx| {
 8959            this.buffer_store.read(cx).get_existing(buffer_id)
 8960        })?;
 8961        let request = T::from_proto(
 8962            envelope.payload,
 8963            this.clone(),
 8964            buffer_handle.clone(),
 8965            cx.clone(),
 8966        )
 8967        .await?;
 8968        let response = this
 8969            .update(&mut cx, |this, cx| {
 8970                this.request_lsp(
 8971                    buffer_handle.clone(),
 8972                    LanguageServerToQuery::FirstCapable,
 8973                    request,
 8974                    cx,
 8975                )
 8976            })
 8977            .await?;
 8978        this.update(&mut cx, |this, cx| {
 8979            Ok(T::response_to_proto(
 8980                response,
 8981                this,
 8982                sender_id,
 8983                &buffer_handle.read(cx).version(),
 8984                cx,
 8985            ))
 8986        })
 8987    }
 8988
 8989    async fn handle_lsp_query(
 8990        lsp_store: Entity<Self>,
 8991        envelope: TypedEnvelope<proto::LspQuery>,
 8992        mut cx: AsyncApp,
 8993    ) -> Result<proto::Ack> {
 8994        use proto::lsp_query::Request;
 8995        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8996        let lsp_query = envelope.payload;
 8997        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8998        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8999        match lsp_query.request.context("invalid LSP query request")? {
 9000            Request::GetReferences(get_references) => {
 9001                let position = get_references.position.clone().and_then(deserialize_anchor);
 9002                Self::query_lsp_locally::<GetReferences>(
 9003                    lsp_store,
 9004                    server_id,
 9005                    sender_id,
 9006                    lsp_request_id,
 9007                    get_references,
 9008                    position,
 9009                    &mut cx,
 9010                )
 9011                .await?;
 9012            }
 9013            Request::GetDocumentColor(get_document_color) => {
 9014                Self::query_lsp_locally::<GetDocumentColor>(
 9015                    lsp_store,
 9016                    server_id,
 9017                    sender_id,
 9018                    lsp_request_id,
 9019                    get_document_color,
 9020                    None,
 9021                    &mut cx,
 9022                )
 9023                .await?;
 9024            }
 9025            Request::GetFoldingRanges(get_folding_ranges) => {
 9026                Self::query_lsp_locally::<GetFoldingRanges>(
 9027                    lsp_store,
 9028                    server_id,
 9029                    sender_id,
 9030                    lsp_request_id,
 9031                    get_folding_ranges,
 9032                    None,
 9033                    &mut cx,
 9034                )
 9035                .await?;
 9036            }
 9037            Request::GetDocumentSymbols(get_document_symbols) => {
 9038                Self::query_lsp_locally::<GetDocumentSymbols>(
 9039                    lsp_store,
 9040                    server_id,
 9041                    sender_id,
 9042                    lsp_request_id,
 9043                    get_document_symbols,
 9044                    None,
 9045                    &mut cx,
 9046                )
 9047                .await?;
 9048            }
 9049            Request::GetHover(get_hover) => {
 9050                let position = get_hover.position.clone().and_then(deserialize_anchor);
 9051                Self::query_lsp_locally::<GetHover>(
 9052                    lsp_store,
 9053                    server_id,
 9054                    sender_id,
 9055                    lsp_request_id,
 9056                    get_hover,
 9057                    position,
 9058                    &mut cx,
 9059                )
 9060                .await?;
 9061            }
 9062            Request::GetCodeActions(get_code_actions) => {
 9063                Self::query_lsp_locally::<GetCodeActions>(
 9064                    lsp_store,
 9065                    server_id,
 9066                    sender_id,
 9067                    lsp_request_id,
 9068                    get_code_actions,
 9069                    None,
 9070                    &mut cx,
 9071                )
 9072                .await?;
 9073            }
 9074            Request::GetSignatureHelp(get_signature_help) => {
 9075                let position = get_signature_help
 9076                    .position
 9077                    .clone()
 9078                    .and_then(deserialize_anchor);
 9079                Self::query_lsp_locally::<GetSignatureHelp>(
 9080                    lsp_store,
 9081                    server_id,
 9082                    sender_id,
 9083                    lsp_request_id,
 9084                    get_signature_help,
 9085                    position,
 9086                    &mut cx,
 9087                )
 9088                .await?;
 9089            }
 9090            Request::GetCodeLens(get_code_lens) => {
 9091                Self::query_lsp_locally::<GetCodeLens>(
 9092                    lsp_store,
 9093                    server_id,
 9094                    sender_id,
 9095                    lsp_request_id,
 9096                    get_code_lens,
 9097                    None,
 9098                    &mut cx,
 9099                )
 9100                .await?;
 9101            }
 9102            Request::GetDefinition(get_definition) => {
 9103                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9104                Self::query_lsp_locally::<GetDefinitions>(
 9105                    lsp_store,
 9106                    server_id,
 9107                    sender_id,
 9108                    lsp_request_id,
 9109                    get_definition,
 9110                    position,
 9111                    &mut cx,
 9112                )
 9113                .await?;
 9114            }
 9115            Request::GetDeclaration(get_declaration) => {
 9116                let position = get_declaration
 9117                    .position
 9118                    .clone()
 9119                    .and_then(deserialize_anchor);
 9120                Self::query_lsp_locally::<GetDeclarations>(
 9121                    lsp_store,
 9122                    server_id,
 9123                    sender_id,
 9124                    lsp_request_id,
 9125                    get_declaration,
 9126                    position,
 9127                    &mut cx,
 9128                )
 9129                .await?;
 9130            }
 9131            Request::GetTypeDefinition(get_type_definition) => {
 9132                let position = get_type_definition
 9133                    .position
 9134                    .clone()
 9135                    .and_then(deserialize_anchor);
 9136                Self::query_lsp_locally::<GetTypeDefinitions>(
 9137                    lsp_store,
 9138                    server_id,
 9139                    sender_id,
 9140                    lsp_request_id,
 9141                    get_type_definition,
 9142                    position,
 9143                    &mut cx,
 9144                )
 9145                .await?;
 9146            }
 9147            Request::GetImplementation(get_implementation) => {
 9148                let position = get_implementation
 9149                    .position
 9150                    .clone()
 9151                    .and_then(deserialize_anchor);
 9152                Self::query_lsp_locally::<GetImplementations>(
 9153                    lsp_store,
 9154                    server_id,
 9155                    sender_id,
 9156                    lsp_request_id,
 9157                    get_implementation,
 9158                    position,
 9159                    &mut cx,
 9160                )
 9161                .await?;
 9162            }
 9163            Request::InlayHints(inlay_hints) => {
 9164                let query_start = inlay_hints
 9165                    .start
 9166                    .clone()
 9167                    .and_then(deserialize_anchor)
 9168                    .context("invalid inlay hints range start")?;
 9169                let query_end = inlay_hints
 9170                    .end
 9171                    .clone()
 9172                    .and_then(deserialize_anchor)
 9173                    .context("invalid inlay hints range end")?;
 9174                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9175                    &lsp_store,
 9176                    server_id,
 9177                    lsp_request_id,
 9178                    &inlay_hints,
 9179                    query_start..query_end,
 9180                    &mut cx,
 9181                )
 9182                .await
 9183                .context("preparing inlay hints request")?;
 9184                Self::query_lsp_locally::<InlayHints>(
 9185                    lsp_store,
 9186                    server_id,
 9187                    sender_id,
 9188                    lsp_request_id,
 9189                    inlay_hints,
 9190                    None,
 9191                    &mut cx,
 9192                )
 9193                .await
 9194                .context("querying for inlay hints")?
 9195            }
 9196            //////////////////////////////
 9197            // Below are LSP queries that need to fetch more data,
 9198            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 9199            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9200                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 9201                    &lsp_store,
 9202                    &get_document_diagnostics,
 9203                    &mut cx,
 9204                )
 9205                .await?;
 9206                lsp_store.update(&mut cx, |lsp_store, cx| {
 9207                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9208                    let key = LspKey {
 9209                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9210                        server_queried: server_id,
 9211                    };
 9212                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9213                    ) {
 9214                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9215                            lsp_requests.clear();
 9216                        };
 9217                    }
 9218
 9219                    lsp_data.lsp_requests.entry(key).or_default().insert(
 9220                        lsp_request_id,
 9221                        cx.spawn(async move |lsp_store, cx| {
 9222                            let diagnostics_pull = lsp_store
 9223                                .update(cx, |lsp_store, cx| {
 9224                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9225                                })
 9226                                .ok();
 9227                            if let Some(diagnostics_pull) = diagnostics_pull {
 9228                                match diagnostics_pull.await {
 9229                                    Ok(()) => {}
 9230                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9231                                };
 9232                            }
 9233                        }),
 9234                    );
 9235                });
 9236            }
 9237            Request::SemanticTokens(semantic_tokens) => {
 9238                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 9239                    &lsp_store,
 9240                    &semantic_tokens,
 9241                    &mut cx,
 9242                )
 9243                .await?;
 9244                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9245                lsp_store.update(&mut cx, |lsp_store, cx| {
 9246                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9247                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9248                        let key = LspKey {
 9249                            request_type: TypeId::of::<SemanticTokensFull>(),
 9250                            server_queried: server_id,
 9251                        };
 9252                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9253                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9254                                lsp_requests.clear();
 9255                            };
 9256                        }
 9257
 9258                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9259                            lsp_request_id,
 9260                            cx.spawn(async move |lsp_store, cx| {
 9261                                let tokens_fetch = lsp_store
 9262                                    .update(cx, |lsp_store, cx| {
 9263                                        lsp_store
 9264                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9265                                    })
 9266                                    .ok();
 9267                                if let Some(tokens_fetch) = tokens_fetch {
 9268                                    let new_tokens = tokens_fetch.await;
 9269                                    if let Some(new_tokens) = new_tokens {
 9270                                        lsp_store
 9271                                            .update(cx, |lsp_store, cx| {
 9272                                                let response = new_tokens
 9273                                                    .into_iter()
 9274                                                    .map(|(server_id, response)| {
 9275                                                        (
 9276                                                            server_id.to_proto(),
 9277                                                            SemanticTokensFull::response_to_proto(
 9278                                                                response,
 9279                                                                lsp_store,
 9280                                                                sender_id,
 9281                                                                &buffer_version,
 9282                                                                cx,
 9283                                                            ),
 9284                                                        )
 9285                                                    })
 9286                                                    .collect::<HashMap<_, _>>();
 9287                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9288                                                    project_id,
 9289                                                    lsp_request_id,
 9290                                                    response,
 9291                                                ) {
 9292                                                    Ok(()) => {}
 9293                                                    Err(e) => {
 9294                                                        log::error!(
 9295                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9296                                                        )
 9297                                                    }
 9298                                                }
 9299                                            })
 9300                                            .ok();
 9301                                    }
 9302                                }
 9303                            }),
 9304                        );
 9305                    }
 9306                });
 9307            }
 9308        }
 9309        Ok(proto::Ack {})
 9310    }
 9311
 9312    async fn handle_lsp_query_response(
 9313        lsp_store: Entity<Self>,
 9314        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9315        cx: AsyncApp,
 9316    ) -> Result<()> {
 9317        lsp_store.read_with(&cx, |lsp_store, _| {
 9318            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9319                upstream_client.handle_lsp_response(envelope.clone());
 9320            }
 9321        });
 9322        Ok(())
 9323    }
 9324
 9325    async fn handle_apply_code_action(
 9326        this: Entity<Self>,
 9327        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9328        mut cx: AsyncApp,
 9329    ) -> Result<proto::ApplyCodeActionResponse> {
 9330        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9331        let action =
 9332            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9333        let apply_code_action = this.update(&mut cx, |this, cx| {
 9334            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9335            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9336            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9337        })?;
 9338
 9339        let project_transaction = apply_code_action.await?;
 9340        let project_transaction = this.update(&mut cx, |this, cx| {
 9341            this.buffer_store.update(cx, |buffer_store, cx| {
 9342                buffer_store.serialize_project_transaction_for_peer(
 9343                    project_transaction,
 9344                    sender_id,
 9345                    cx,
 9346                )
 9347            })
 9348        });
 9349        Ok(proto::ApplyCodeActionResponse {
 9350            transaction: Some(project_transaction),
 9351        })
 9352    }
 9353
 9354    async fn handle_register_buffer_with_language_servers(
 9355        this: Entity<Self>,
 9356        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9357        mut cx: AsyncApp,
 9358    ) -> Result<proto::Ack> {
 9359        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9360        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9361        this.update(&mut cx, |this, cx| {
 9362            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9363                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9364                    project_id: upstream_project_id,
 9365                    buffer_id: buffer_id.to_proto(),
 9366                    only_servers: envelope.payload.only_servers,
 9367                });
 9368            }
 9369
 9370            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9371                anyhow::bail!("buffer is not open");
 9372            };
 9373
 9374            let handle = this.register_buffer_with_language_servers(
 9375                &buffer,
 9376                envelope
 9377                    .payload
 9378                    .only_servers
 9379                    .into_iter()
 9380                    .filter_map(|selector| {
 9381                        Some(match selector.selector? {
 9382                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9383                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9384                            }
 9385                            proto::language_server_selector::Selector::Name(name) => {
 9386                                LanguageServerSelector::Name(LanguageServerName(
 9387                                    SharedString::from(name),
 9388                                ))
 9389                            }
 9390                        })
 9391                    })
 9392                    .collect(),
 9393                false,
 9394                cx,
 9395            );
 9396            // Pull diagnostics for the buffer even if it was already registered.
 9397            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9398            // but it's unclear if we need it.
 9399            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9400                .detach();
 9401            this.buffer_store().update(cx, |buffer_store, _| {
 9402                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9403            });
 9404
 9405            Ok(())
 9406        })?;
 9407        Ok(proto::Ack {})
 9408    }
 9409
 9410    async fn handle_rename_project_entry(
 9411        this: Entity<Self>,
 9412        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9413        mut cx: AsyncApp,
 9414    ) -> Result<proto::ProjectEntryResponse> {
 9415        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9416        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9417        let new_path =
 9418            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9419
 9420        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9421            .update(&mut cx, |this, cx| {
 9422                let (worktree, entry) = this
 9423                    .worktree_store
 9424                    .read(cx)
 9425                    .worktree_and_entry_for_id(entry_id, cx)?;
 9426                let new_worktree = this
 9427                    .worktree_store
 9428                    .read(cx)
 9429                    .worktree_for_id(new_worktree_id, cx)?;
 9430                Some((
 9431                    this.worktree_store.clone(),
 9432                    worktree,
 9433                    new_worktree,
 9434                    entry.clone(),
 9435                ))
 9436            })
 9437            .context("worktree not found")?;
 9438        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9439            (worktree.absolutize(&old_entry.path), worktree.id())
 9440        });
 9441        let new_abs_path =
 9442            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9443
 9444        let _transaction = Self::will_rename_entry(
 9445            this.downgrade(),
 9446            old_worktree_id,
 9447            &old_abs_path,
 9448            &new_abs_path,
 9449            old_entry.is_dir(),
 9450            cx.clone(),
 9451        )
 9452        .await;
 9453        let response = WorktreeStore::handle_rename_project_entry(
 9454            worktree_store,
 9455            envelope.payload,
 9456            cx.clone(),
 9457        )
 9458        .await;
 9459        this.read_with(&cx, |this, _| {
 9460            this.did_rename_entry(
 9461                old_worktree_id,
 9462                &old_abs_path,
 9463                &new_abs_path,
 9464                old_entry.is_dir(),
 9465            );
 9466        });
 9467        response
 9468    }
 9469
 9470    async fn handle_update_diagnostic_summary(
 9471        this: Entity<Self>,
 9472        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9473        mut cx: AsyncApp,
 9474    ) -> Result<()> {
 9475        this.update(&mut cx, |lsp_store, cx| {
 9476            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9477            let mut updated_diagnostics_paths = HashMap::default();
 9478            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9479            for message_summary in envelope
 9480                .payload
 9481                .summary
 9482                .into_iter()
 9483                .chain(envelope.payload.more_summaries)
 9484            {
 9485                let project_path = ProjectPath {
 9486                    worktree_id,
 9487                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9488                };
 9489                let path = project_path.path.clone();
 9490                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9491                let summary = DiagnosticSummary {
 9492                    error_count: message_summary.error_count as usize,
 9493                    warning_count: message_summary.warning_count as usize,
 9494                };
 9495
 9496                if summary.is_empty() {
 9497                    if let Some(worktree_summaries) =
 9498                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9499                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9500                    {
 9501                        summaries.remove(&server_id);
 9502                        if summaries.is_empty() {
 9503                            worktree_summaries.remove(&path);
 9504                        }
 9505                    }
 9506                } else {
 9507                    lsp_store
 9508                        .diagnostic_summaries
 9509                        .entry(worktree_id)
 9510                        .or_default()
 9511                        .entry(path)
 9512                        .or_default()
 9513                        .insert(server_id, summary);
 9514                }
 9515
 9516                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9517                    match &mut diagnostics_summary {
 9518                        Some(diagnostics_summary) => {
 9519                            diagnostics_summary
 9520                                .more_summaries
 9521                                .push(proto::DiagnosticSummary {
 9522                                    path: project_path.path.as_ref().to_proto(),
 9523                                    language_server_id: server_id.0 as u64,
 9524                                    error_count: summary.error_count as u32,
 9525                                    warning_count: summary.warning_count as u32,
 9526                                })
 9527                        }
 9528                        None => {
 9529                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9530                                project_id: *project_id,
 9531                                worktree_id: worktree_id.to_proto(),
 9532                                summary: Some(proto::DiagnosticSummary {
 9533                                    path: project_path.path.as_ref().to_proto(),
 9534                                    language_server_id: server_id.0 as u64,
 9535                                    error_count: summary.error_count as u32,
 9536                                    warning_count: summary.warning_count as u32,
 9537                                }),
 9538                                more_summaries: Vec::new(),
 9539                            })
 9540                        }
 9541                    }
 9542                }
 9543                updated_diagnostics_paths
 9544                    .entry(server_id)
 9545                    .or_insert_with(Vec::new)
 9546                    .push(project_path);
 9547            }
 9548
 9549            if let Some((diagnostics_summary, (downstream_client, _))) =
 9550                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9551            {
 9552                downstream_client.send(diagnostics_summary).log_err();
 9553            }
 9554            for (server_id, paths) in updated_diagnostics_paths {
 9555                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9556            }
 9557            Ok(())
 9558        })
 9559    }
 9560
 9561    async fn handle_start_language_server(
 9562        lsp_store: Entity<Self>,
 9563        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9564        mut cx: AsyncApp,
 9565    ) -> Result<()> {
 9566        let server = envelope.payload.server.context("invalid server")?;
 9567        let server_capabilities =
 9568            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9569                .with_context(|| {
 9570                    format!(
 9571                        "incorrect server capabilities {}",
 9572                        envelope.payload.capabilities
 9573                    )
 9574                })?;
 9575        lsp_store.update(&mut cx, |lsp_store, cx| {
 9576            let server_id = LanguageServerId(server.id as usize);
 9577            let server_name = LanguageServerName::from_proto(server.name.clone());
 9578            lsp_store
 9579                .lsp_server_capabilities
 9580                .insert(server_id, server_capabilities);
 9581            lsp_store.language_server_statuses.insert(
 9582                server_id,
 9583                LanguageServerStatus {
 9584                    name: server_name.clone(),
 9585                    server_version: None,
 9586                    server_readable_version: None,
 9587                    pending_work: Default::default(),
 9588                    has_pending_diagnostic_updates: false,
 9589                    progress_tokens: Default::default(),
 9590                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9591                    binary: None,
 9592                    configuration: None,
 9593                    workspace_folders: BTreeSet::new(),
 9594                    process_id: None,
 9595                },
 9596            );
 9597            cx.emit(LspStoreEvent::LanguageServerAdded(
 9598                server_id,
 9599                server_name,
 9600                server.worktree_id.map(WorktreeId::from_proto),
 9601            ));
 9602            cx.notify();
 9603        });
 9604        Ok(())
 9605    }
 9606
 9607    async fn handle_update_language_server(
 9608        lsp_store: Entity<Self>,
 9609        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9610        mut cx: AsyncApp,
 9611    ) -> Result<()> {
 9612        lsp_store.update(&mut cx, |lsp_store, cx| {
 9613            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9614
 9615            match envelope.payload.variant.context("invalid variant")? {
 9616                proto::update_language_server::Variant::WorkStart(payload) => {
 9617                    lsp_store.on_lsp_work_start(
 9618                        language_server_id,
 9619                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9620                            .context("invalid progress token value")?,
 9621                        LanguageServerProgress {
 9622                            title: payload.title,
 9623                            is_disk_based_diagnostics_progress: false,
 9624                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9625                            message: payload.message,
 9626                            percentage: payload.percentage.map(|p| p as usize),
 9627                            last_update_at: cx.background_executor().now(),
 9628                        },
 9629                        cx,
 9630                    );
 9631                }
 9632                proto::update_language_server::Variant::WorkProgress(payload) => {
 9633                    lsp_store.on_lsp_work_progress(
 9634                        language_server_id,
 9635                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9636                            .context("invalid progress token value")?,
 9637                        LanguageServerProgress {
 9638                            title: None,
 9639                            is_disk_based_diagnostics_progress: false,
 9640                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9641                            message: payload.message,
 9642                            percentage: payload.percentage.map(|p| p as usize),
 9643                            last_update_at: cx.background_executor().now(),
 9644                        },
 9645                        cx,
 9646                    );
 9647                }
 9648
 9649                proto::update_language_server::Variant::WorkEnd(payload) => {
 9650                    lsp_store.on_lsp_work_end(
 9651                        language_server_id,
 9652                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9653                            .context("invalid progress token value")?,
 9654                        cx,
 9655                    );
 9656                }
 9657
 9658                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9659                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9660                }
 9661
 9662                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9663                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9664                }
 9665
 9666                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9667                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9668                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9669                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9670                        language_server_id,
 9671                        name: envelope
 9672                            .payload
 9673                            .server_name
 9674                            .map(SharedString::new)
 9675                            .map(LanguageServerName),
 9676                        message: non_lsp,
 9677                    });
 9678                }
 9679            }
 9680
 9681            Ok(())
 9682        })
 9683    }
 9684
 9685    async fn handle_language_server_log(
 9686        this: Entity<Self>,
 9687        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9688        mut cx: AsyncApp,
 9689    ) -> Result<()> {
 9690        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9691        let log_type = envelope
 9692            .payload
 9693            .log_type
 9694            .map(LanguageServerLogType::from_proto)
 9695            .context("invalid language server log type")?;
 9696
 9697        let message = envelope.payload.message;
 9698
 9699        this.update(&mut cx, |_, cx| {
 9700            cx.emit(LspStoreEvent::LanguageServerLog(
 9701                language_server_id,
 9702                log_type,
 9703                message,
 9704            ));
 9705        });
 9706        Ok(())
 9707    }
 9708
 9709    async fn handle_lsp_ext_cancel_flycheck(
 9710        lsp_store: Entity<Self>,
 9711        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9712        cx: AsyncApp,
 9713    ) -> Result<proto::Ack> {
 9714        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9715        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9716            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9717                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9718            } else {
 9719                None
 9720            }
 9721        });
 9722        if let Some(task) = task {
 9723            task.context("handling lsp ext cancel flycheck")?;
 9724        }
 9725
 9726        Ok(proto::Ack {})
 9727    }
 9728
 9729    async fn handle_lsp_ext_run_flycheck(
 9730        lsp_store: Entity<Self>,
 9731        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9732        mut cx: AsyncApp,
 9733    ) -> Result<proto::Ack> {
 9734        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9735        lsp_store.update(&mut cx, |lsp_store, cx| {
 9736            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9737                let text_document = if envelope.payload.current_file_only {
 9738                    let buffer_id = envelope
 9739                        .payload
 9740                        .buffer_id
 9741                        .map(|id| BufferId::new(id))
 9742                        .transpose()?;
 9743                    buffer_id
 9744                        .and_then(|buffer_id| {
 9745                            lsp_store
 9746                                .buffer_store()
 9747                                .read(cx)
 9748                                .get(buffer_id)
 9749                                .and_then(|buffer| {
 9750                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9751                                })
 9752                                .map(|path| make_text_document_identifier(&path))
 9753                        })
 9754                        .transpose()?
 9755                } else {
 9756                    None
 9757                };
 9758                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9759                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9760                )?;
 9761            }
 9762            anyhow::Ok(())
 9763        })?;
 9764
 9765        Ok(proto::Ack {})
 9766    }
 9767
 9768    async fn handle_lsp_ext_clear_flycheck(
 9769        lsp_store: Entity<Self>,
 9770        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9771        cx: AsyncApp,
 9772    ) -> Result<proto::Ack> {
 9773        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9774        lsp_store.read_with(&cx, |lsp_store, _| {
 9775            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9776                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9777            } else {
 9778                None
 9779            }
 9780        });
 9781
 9782        Ok(proto::Ack {})
 9783    }
 9784
 9785    pub fn disk_based_diagnostics_started(
 9786        &mut self,
 9787        language_server_id: LanguageServerId,
 9788        cx: &mut Context<Self>,
 9789    ) {
 9790        if let Some(language_server_status) =
 9791            self.language_server_statuses.get_mut(&language_server_id)
 9792        {
 9793            language_server_status.has_pending_diagnostic_updates = true;
 9794        }
 9795
 9796        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9797        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9798            language_server_id,
 9799            name: self
 9800                .language_server_adapter_for_id(language_server_id)
 9801                .map(|adapter| adapter.name()),
 9802            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9803                Default::default(),
 9804            ),
 9805        })
 9806    }
 9807
 9808    pub fn disk_based_diagnostics_finished(
 9809        &mut self,
 9810        language_server_id: LanguageServerId,
 9811        cx: &mut Context<Self>,
 9812    ) {
 9813        if let Some(language_server_status) =
 9814            self.language_server_statuses.get_mut(&language_server_id)
 9815        {
 9816            language_server_status.has_pending_diagnostic_updates = false;
 9817        }
 9818
 9819        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9820        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9821            language_server_id,
 9822            name: self
 9823                .language_server_adapter_for_id(language_server_id)
 9824                .map(|adapter| adapter.name()),
 9825            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9826                Default::default(),
 9827            ),
 9828        })
 9829    }
 9830
 9831    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9832    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9833    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9834    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9835    // the language server might take some time to publish diagnostics.
 9836    fn simulate_disk_based_diagnostics_events_if_needed(
 9837        &mut self,
 9838        language_server_id: LanguageServerId,
 9839        cx: &mut Context<Self>,
 9840    ) {
 9841        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9842
 9843        let Some(LanguageServerState::Running {
 9844            simulate_disk_based_diagnostics_completion,
 9845            adapter,
 9846            ..
 9847        }) = self
 9848            .as_local_mut()
 9849            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9850        else {
 9851            return;
 9852        };
 9853
 9854        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9855            return;
 9856        }
 9857
 9858        let prev_task =
 9859            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9860                cx.background_executor()
 9861                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9862                    .await;
 9863
 9864                this.update(cx, |this, cx| {
 9865                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9866
 9867                    if let Some(LanguageServerState::Running {
 9868                        simulate_disk_based_diagnostics_completion,
 9869                        ..
 9870                    }) = this.as_local_mut().and_then(|local_store| {
 9871                        local_store.language_servers.get_mut(&language_server_id)
 9872                    }) {
 9873                        *simulate_disk_based_diagnostics_completion = None;
 9874                    }
 9875                })
 9876                .ok();
 9877            }));
 9878
 9879        if prev_task.is_none() {
 9880            self.disk_based_diagnostics_started(language_server_id, cx);
 9881        }
 9882    }
 9883
 9884    pub fn language_server_statuses(
 9885        &self,
 9886    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9887        self.language_server_statuses
 9888            .iter()
 9889            .map(|(key, value)| (*key, value))
 9890    }
 9891
 9892    pub(super) fn did_rename_entry(
 9893        &self,
 9894        worktree_id: WorktreeId,
 9895        old_path: &Path,
 9896        new_path: &Path,
 9897        is_dir: bool,
 9898    ) {
 9899        maybe!({
 9900            let local_store = self.as_local()?;
 9901
 9902            let old_uri = lsp::Uri::from_file_path(old_path)
 9903                .ok()
 9904                .map(|uri| uri.to_string())?;
 9905            let new_uri = lsp::Uri::from_file_path(new_path)
 9906                .ok()
 9907                .map(|uri| uri.to_string())?;
 9908
 9909            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9910                let Some(filter) = local_store
 9911                    .language_server_paths_watched_for_rename
 9912                    .get(&language_server.server_id())
 9913                else {
 9914                    continue;
 9915                };
 9916
 9917                if filter.should_send_did_rename(&old_uri, is_dir) {
 9918                    language_server
 9919                        .notify::<DidRenameFiles>(RenameFilesParams {
 9920                            files: vec![FileRename {
 9921                                old_uri: old_uri.clone(),
 9922                                new_uri: new_uri.clone(),
 9923                            }],
 9924                        })
 9925                        .ok();
 9926                }
 9927            }
 9928            Some(())
 9929        });
 9930    }
 9931
 9932    pub(super) fn will_rename_entry(
 9933        this: WeakEntity<Self>,
 9934        worktree_id: WorktreeId,
 9935        old_path: &Path,
 9936        new_path: &Path,
 9937        is_dir: bool,
 9938        cx: AsyncApp,
 9939    ) -> Task<ProjectTransaction> {
 9940        let old_uri = lsp::Uri::from_file_path(old_path)
 9941            .ok()
 9942            .map(|uri| uri.to_string());
 9943        let new_uri = lsp::Uri::from_file_path(new_path)
 9944            .ok()
 9945            .map(|uri| uri.to_string());
 9946        cx.spawn(async move |cx| {
 9947            let mut tasks = vec![];
 9948            this.update(cx, |this, cx| {
 9949                let local_store = this.as_local()?;
 9950                let old_uri = old_uri?;
 9951                let new_uri = new_uri?;
 9952                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9953                    let Some(filter) = local_store
 9954                        .language_server_paths_watched_for_rename
 9955                        .get(&language_server.server_id())
 9956                    else {
 9957                        continue;
 9958                    };
 9959
 9960                    if !filter.should_send_will_rename(&old_uri, is_dir) {
 9961                        continue;
 9962                    }
 9963                    let request_timeout = ProjectSettings::get_global(cx)
 9964                        .global_lsp_settings
 9965                        .get_request_timeout();
 9966
 9967                    let apply_edit = cx.spawn({
 9968                        let old_uri = old_uri.clone();
 9969                        let new_uri = new_uri.clone();
 9970                        let language_server = language_server.clone();
 9971                        async move |this, cx| {
 9972                            let edit = language_server
 9973                                .request::<WillRenameFiles>(
 9974                                    RenameFilesParams {
 9975                                        files: vec![FileRename { old_uri, new_uri }],
 9976                                    },
 9977                                    request_timeout,
 9978                                )
 9979                                .await
 9980                                .into_response()
 9981                                .context("will rename files")
 9982                                .log_err()
 9983                                .flatten()?;
 9984
 9985                            LocalLspStore::deserialize_workspace_edit(
 9986                                this.upgrade()?,
 9987                                edit,
 9988                                false,
 9989                                language_server.clone(),
 9990                                cx,
 9991                            )
 9992                            .await
 9993                            .ok()
 9994                        }
 9995                    });
 9996                    tasks.push(apply_edit);
 9997                }
 9998                Some(())
 9999            })
10000            .ok()
10001            .flatten();
10002            let mut merged_transaction = ProjectTransaction::default();
10003            for task in tasks {
10004                // Await on tasks sequentially so that the order of application of edits is deterministic
10005                // (at least with regards to the order of registration of language servers)
10006                if let Some(transaction) = task.await {
10007                    for (buffer, buffer_transaction) in transaction.0 {
10008                        merged_transaction.0.insert(buffer, buffer_transaction);
10009                    }
10010                }
10011            }
10012            merged_transaction
10013        })
10014    }
10015
10016    fn lsp_notify_abs_paths_changed(
10017        &mut self,
10018        server_id: LanguageServerId,
10019        changes: Vec<PathEvent>,
10020    ) {
10021        maybe!({
10022            let server = self.language_server_for_id(server_id)?;
10023            let changes = changes
10024                .into_iter()
10025                .filter_map(|event| {
10026                    let typ = match event.kind? {
10027                        PathEventKind::Created => lsp::FileChangeType::CREATED,
10028                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
10029                        PathEventKind::Changed | PathEventKind::Rescan => {
10030                            lsp::FileChangeType::CHANGED
10031                        }
10032                    };
10033                    Some(lsp::FileEvent {
10034                        uri: file_path_to_lsp_url(&event.path).log_err()?,
10035                        typ,
10036                    })
10037                })
10038                .collect::<Vec<_>>();
10039            if !changes.is_empty() {
10040                server
10041                    .notify::<lsp::notification::DidChangeWatchedFiles>(
10042                        lsp::DidChangeWatchedFilesParams { changes },
10043                    )
10044                    .ok();
10045            }
10046            Some(())
10047        });
10048    }
10049
10050    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
10051        self.as_local()?.language_server_for_id(id)
10052    }
10053
10054    fn on_lsp_progress(
10055        &mut self,
10056        progress_params: lsp::ProgressParams,
10057        language_server_id: LanguageServerId,
10058        disk_based_diagnostics_progress_token: Option<String>,
10059        cx: &mut Context<Self>,
10060    ) {
10061        match progress_params.value {
10062            lsp::ProgressParamsValue::WorkDone(progress) => {
10063                self.handle_work_done_progress(
10064                    progress,
10065                    language_server_id,
10066                    disk_based_diagnostics_progress_token,
10067                    ProgressToken::from_lsp(progress_params.token),
10068                    cx,
10069                );
10070            }
10071            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
10072                let registration_id = match progress_params.token {
10073                    lsp::NumberOrString::Number(_) => None,
10074                    lsp::NumberOrString::String(token) => token
10075                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
10076                        .map(|(_, id)| id.to_owned()),
10077                };
10078                if let Some(LanguageServerState::Running {
10079                    workspace_diagnostics_refresh_tasks,
10080                    ..
10081                }) = self
10082                    .as_local_mut()
10083                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
10084                    && let Some(workspace_diagnostics) =
10085                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
10086                {
10087                    workspace_diagnostics.progress_tx.try_send(()).ok();
10088                    self.apply_workspace_diagnostic_report(
10089                        language_server_id,
10090                        report,
10091                        registration_id.map(SharedString::from),
10092                        cx,
10093                    )
10094                }
10095            }
10096        }
10097    }
10098
10099    fn handle_work_done_progress(
10100        &mut self,
10101        progress: lsp::WorkDoneProgress,
10102        language_server_id: LanguageServerId,
10103        disk_based_diagnostics_progress_token: Option<String>,
10104        token: ProgressToken,
10105        cx: &mut Context<Self>,
10106    ) {
10107        let language_server_status =
10108            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10109                status
10110            } else {
10111                return;
10112            };
10113
10114        if !language_server_status.progress_tokens.contains(&token) {
10115            return;
10116        }
10117
10118        let is_disk_based_diagnostics_progress =
10119            if let (Some(disk_based_token), ProgressToken::String(token)) =
10120                (&disk_based_diagnostics_progress_token, &token)
10121            {
10122                token.starts_with(disk_based_token)
10123            } else {
10124                false
10125            };
10126
10127        match progress {
10128            lsp::WorkDoneProgress::Begin(report) => {
10129                if is_disk_based_diagnostics_progress {
10130                    self.disk_based_diagnostics_started(language_server_id, cx);
10131                }
10132                self.on_lsp_work_start(
10133                    language_server_id,
10134                    token.clone(),
10135                    LanguageServerProgress {
10136                        title: Some(report.title),
10137                        is_disk_based_diagnostics_progress,
10138                        is_cancellable: report.cancellable.unwrap_or(false),
10139                        message: report.message.clone(),
10140                        percentage: report.percentage.map(|p| p as usize),
10141                        last_update_at: cx.background_executor().now(),
10142                    },
10143                    cx,
10144                );
10145            }
10146            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10147                language_server_id,
10148                token,
10149                LanguageServerProgress {
10150                    title: None,
10151                    is_disk_based_diagnostics_progress,
10152                    is_cancellable: report.cancellable.unwrap_or(false),
10153                    message: report.message,
10154                    percentage: report.percentage.map(|p| p as usize),
10155                    last_update_at: cx.background_executor().now(),
10156                },
10157                cx,
10158            ),
10159            lsp::WorkDoneProgress::End(_) => {
10160                language_server_status.progress_tokens.remove(&token);
10161                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10162                if is_disk_based_diagnostics_progress {
10163                    self.disk_based_diagnostics_finished(language_server_id, cx);
10164                }
10165            }
10166        }
10167    }
10168
10169    fn on_lsp_work_start(
10170        &mut self,
10171        language_server_id: LanguageServerId,
10172        token: ProgressToken,
10173        progress: LanguageServerProgress,
10174        cx: &mut Context<Self>,
10175    ) {
10176        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10177            status.pending_work.insert(token.clone(), progress.clone());
10178            cx.notify();
10179        }
10180        cx.emit(LspStoreEvent::LanguageServerUpdate {
10181            language_server_id,
10182            name: self
10183                .language_server_adapter_for_id(language_server_id)
10184                .map(|adapter| adapter.name()),
10185            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10186                token: Some(token.to_proto()),
10187                title: progress.title,
10188                message: progress.message,
10189                percentage: progress.percentage.map(|p| p as u32),
10190                is_cancellable: Some(progress.is_cancellable),
10191            }),
10192        })
10193    }
10194
10195    fn on_lsp_work_progress(
10196        &mut self,
10197        language_server_id: LanguageServerId,
10198        token: ProgressToken,
10199        progress: LanguageServerProgress,
10200        cx: &mut Context<Self>,
10201    ) {
10202        let mut did_update = false;
10203        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10204            match status.pending_work.entry(token.clone()) {
10205                btree_map::Entry::Vacant(entry) => {
10206                    entry.insert(progress.clone());
10207                    did_update = true;
10208                }
10209                btree_map::Entry::Occupied(mut entry) => {
10210                    let entry = entry.get_mut();
10211                    if (progress.last_update_at - entry.last_update_at)
10212                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10213                    {
10214                        entry.last_update_at = progress.last_update_at;
10215                        if progress.message.is_some() {
10216                            entry.message = progress.message.clone();
10217                        }
10218                        if progress.percentage.is_some() {
10219                            entry.percentage = progress.percentage;
10220                        }
10221                        if progress.is_cancellable != entry.is_cancellable {
10222                            entry.is_cancellable = progress.is_cancellable;
10223                        }
10224                        did_update = true;
10225                    }
10226                }
10227            }
10228        }
10229
10230        if did_update {
10231            cx.emit(LspStoreEvent::LanguageServerUpdate {
10232                language_server_id,
10233                name: self
10234                    .language_server_adapter_for_id(language_server_id)
10235                    .map(|adapter| adapter.name()),
10236                message: proto::update_language_server::Variant::WorkProgress(
10237                    proto::LspWorkProgress {
10238                        token: Some(token.to_proto()),
10239                        message: progress.message,
10240                        percentage: progress.percentage.map(|p| p as u32),
10241                        is_cancellable: Some(progress.is_cancellable),
10242                    },
10243                ),
10244            })
10245        }
10246    }
10247
10248    fn on_lsp_work_end(
10249        &mut self,
10250        language_server_id: LanguageServerId,
10251        token: ProgressToken,
10252        cx: &mut Context<Self>,
10253    ) {
10254        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10255            if let Some(work) = status.pending_work.remove(&token)
10256                && !work.is_disk_based_diagnostics_progress
10257            {
10258                cx.emit(LspStoreEvent::RefreshInlayHints {
10259                    server_id: language_server_id,
10260                    request_id: None,
10261                });
10262            }
10263            cx.notify();
10264        }
10265
10266        cx.emit(LspStoreEvent::LanguageServerUpdate {
10267            language_server_id,
10268            name: self
10269                .language_server_adapter_for_id(language_server_id)
10270                .map(|adapter| adapter.name()),
10271            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10272                token: Some(token.to_proto()),
10273            }),
10274        })
10275    }
10276
10277    pub async fn handle_resolve_completion_documentation(
10278        this: Entity<Self>,
10279        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10280        mut cx: AsyncApp,
10281    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10282        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10283
10284        let completion = this
10285            .read_with(&cx, |this, cx| {
10286                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10287                let server = this
10288                    .language_server_for_id(id)
10289                    .with_context(|| format!("No language server {id}"))?;
10290
10291                let request_timeout = ProjectSettings::get_global(cx)
10292                    .global_lsp_settings
10293                    .get_request_timeout();
10294
10295                anyhow::Ok(cx.background_spawn(async move {
10296                    let can_resolve = server
10297                        .capabilities()
10298                        .completion_provider
10299                        .as_ref()
10300                        .and_then(|options| options.resolve_provider)
10301                        .unwrap_or(false);
10302                    if can_resolve {
10303                        server
10304                            .request::<lsp::request::ResolveCompletionItem>(
10305                                lsp_completion,
10306                                request_timeout,
10307                            )
10308                            .await
10309                            .into_response()
10310                            .context("resolve completion item")
10311                    } else {
10312                        anyhow::Ok(lsp_completion)
10313                    }
10314                }))
10315            })?
10316            .await?;
10317
10318        let mut documentation_is_markdown = false;
10319        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10320        let documentation = match completion.documentation {
10321            Some(lsp::Documentation::String(text)) => text,
10322
10323            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10324                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10325                value
10326            }
10327
10328            _ => String::new(),
10329        };
10330
10331        // If we have a new buffer_id, that means we're talking to a new client
10332        // and want to check for new text_edits in the completion too.
10333        let mut old_replace_start = None;
10334        let mut old_replace_end = None;
10335        let mut old_insert_start = None;
10336        let mut old_insert_end = None;
10337        let mut new_text = String::default();
10338        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10339            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10340                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10341                anyhow::Ok(buffer.read(cx).snapshot())
10342            })?;
10343
10344            if let Some(text_edit) = completion.text_edit.as_ref() {
10345                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10346
10347                if let Some(mut edit) = edit {
10348                    LineEnding::normalize(&mut edit.new_text);
10349
10350                    new_text = edit.new_text;
10351                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10352                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10353                    if let Some(insert_range) = edit.insert_range {
10354                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10355                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10356                    }
10357                }
10358            }
10359        }
10360
10361        Ok(proto::ResolveCompletionDocumentationResponse {
10362            documentation,
10363            documentation_is_markdown,
10364            old_replace_start,
10365            old_replace_end,
10366            new_text,
10367            lsp_completion,
10368            old_insert_start,
10369            old_insert_end,
10370        })
10371    }
10372
10373    async fn handle_on_type_formatting(
10374        this: Entity<Self>,
10375        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10376        mut cx: AsyncApp,
10377    ) -> Result<proto::OnTypeFormattingResponse> {
10378        let on_type_formatting = this.update(&mut cx, |this, cx| {
10379            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10380            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10381            let position = envelope
10382                .payload
10383                .position
10384                .and_then(deserialize_anchor)
10385                .context("invalid position")?;
10386            anyhow::Ok(this.apply_on_type_formatting(
10387                buffer,
10388                position,
10389                envelope.payload.trigger.clone(),
10390                cx,
10391            ))
10392        })?;
10393
10394        let transaction = on_type_formatting
10395            .await?
10396            .as_ref()
10397            .map(language::proto::serialize_transaction);
10398        Ok(proto::OnTypeFormattingResponse { transaction })
10399    }
10400
10401    async fn handle_pull_workspace_diagnostics(
10402        lsp_store: Entity<Self>,
10403        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10404        mut cx: AsyncApp,
10405    ) -> Result<proto::Ack> {
10406        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10407        lsp_store.update(&mut cx, |lsp_store, _| {
10408            lsp_store.pull_workspace_diagnostics(server_id);
10409        });
10410        Ok(proto::Ack {})
10411    }
10412
10413    async fn handle_open_buffer_for_symbol(
10414        this: Entity<Self>,
10415        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10416        mut cx: AsyncApp,
10417    ) -> Result<proto::OpenBufferForSymbolResponse> {
10418        let peer_id = envelope.original_sender_id().unwrap_or_default();
10419        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10420        let symbol = Self::deserialize_symbol(symbol)?;
10421        this.read_with(&cx, |this, _| {
10422            if let SymbolLocation::OutsideProject {
10423                abs_path,
10424                signature,
10425            } = &symbol.path
10426            {
10427                let new_signature = this.symbol_signature(&abs_path);
10428                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10429            }
10430            Ok(())
10431        })?;
10432        let buffer = this
10433            .update(&mut cx, |this, cx| {
10434                this.open_buffer_for_symbol(
10435                    &Symbol {
10436                        language_server_name: symbol.language_server_name,
10437                        source_worktree_id: symbol.source_worktree_id,
10438                        source_language_server_id: symbol.source_language_server_id,
10439                        path: symbol.path,
10440                        name: symbol.name,
10441                        kind: symbol.kind,
10442                        range: symbol.range,
10443                        label: CodeLabel::default(),
10444                        container_name: symbol.container_name,
10445                    },
10446                    cx,
10447                )
10448            })
10449            .await?;
10450
10451        this.update(&mut cx, |this, cx| {
10452            let is_private = buffer
10453                .read(cx)
10454                .file()
10455                .map(|f| f.is_private())
10456                .unwrap_or_default();
10457            if is_private {
10458                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10459            } else {
10460                this.buffer_store
10461                    .update(cx, |buffer_store, cx| {
10462                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10463                    })
10464                    .detach_and_log_err(cx);
10465                let buffer_id = buffer.read(cx).remote_id().to_proto();
10466                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10467            }
10468        })
10469    }
10470
10471    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10472        let mut hasher = Sha256::new();
10473        hasher.update(abs_path.to_string_lossy().as_bytes());
10474        hasher.update(self.nonce.to_be_bytes());
10475        hasher.finalize().as_slice().try_into().unwrap()
10476    }
10477
10478    pub async fn handle_get_project_symbols(
10479        this: Entity<Self>,
10480        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10481        mut cx: AsyncApp,
10482    ) -> Result<proto::GetProjectSymbolsResponse> {
10483        let symbols = this
10484            .update(&mut cx, |this, cx| {
10485                this.symbols(&envelope.payload.query, cx)
10486            })
10487            .await?;
10488
10489        Ok(proto::GetProjectSymbolsResponse {
10490            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10491        })
10492    }
10493
10494    pub async fn handle_restart_language_servers(
10495        this: Entity<Self>,
10496        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10497        mut cx: AsyncApp,
10498    ) -> Result<proto::Ack> {
10499        this.update(&mut cx, |lsp_store, cx| {
10500            let buffers =
10501                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10502            lsp_store.restart_language_servers_for_buffers(
10503                buffers,
10504                envelope
10505                    .payload
10506                    .only_servers
10507                    .into_iter()
10508                    .filter_map(|selector| {
10509                        Some(match selector.selector? {
10510                            proto::language_server_selector::Selector::ServerId(server_id) => {
10511                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10512                            }
10513                            proto::language_server_selector::Selector::Name(name) => {
10514                                LanguageServerSelector::Name(LanguageServerName(
10515                                    SharedString::from(name),
10516                                ))
10517                            }
10518                        })
10519                    })
10520                    .collect(),
10521                cx,
10522            );
10523        });
10524
10525        Ok(proto::Ack {})
10526    }
10527
10528    pub async fn handle_stop_language_servers(
10529        lsp_store: Entity<Self>,
10530        envelope: TypedEnvelope<proto::StopLanguageServers>,
10531        mut cx: AsyncApp,
10532    ) -> Result<proto::Ack> {
10533        lsp_store.update(&mut cx, |lsp_store, cx| {
10534            if envelope.payload.all
10535                && envelope.payload.also_servers.is_empty()
10536                && envelope.payload.buffer_ids.is_empty()
10537            {
10538                lsp_store.stop_all_language_servers(cx);
10539            } else {
10540                let buffers =
10541                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10542                lsp_store
10543                    .stop_language_servers_for_buffers(
10544                        buffers,
10545                        envelope
10546                            .payload
10547                            .also_servers
10548                            .into_iter()
10549                            .filter_map(|selector| {
10550                                Some(match selector.selector? {
10551                                    proto::language_server_selector::Selector::ServerId(
10552                                        server_id,
10553                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10554                                        server_id,
10555                                    )),
10556                                    proto::language_server_selector::Selector::Name(name) => {
10557                                        LanguageServerSelector::Name(LanguageServerName(
10558                                            SharedString::from(name),
10559                                        ))
10560                                    }
10561                                })
10562                            })
10563                            .collect(),
10564                        cx,
10565                    )
10566                    .detach_and_log_err(cx);
10567            }
10568        });
10569
10570        Ok(proto::Ack {})
10571    }
10572
10573    pub async fn handle_cancel_language_server_work(
10574        lsp_store: Entity<Self>,
10575        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10576        mut cx: AsyncApp,
10577    ) -> Result<proto::Ack> {
10578        lsp_store.update(&mut cx, |lsp_store, cx| {
10579            if let Some(work) = envelope.payload.work {
10580                match work {
10581                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10582                        let buffers =
10583                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10584                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10585                    }
10586                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10587                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10588                        let token = work
10589                            .token
10590                            .map(|token| {
10591                                ProgressToken::from_proto(token)
10592                                    .context("invalid work progress token")
10593                            })
10594                            .transpose()?;
10595                        lsp_store.cancel_language_server_work(server_id, token, cx);
10596                    }
10597                }
10598            }
10599            anyhow::Ok(())
10600        })?;
10601
10602        Ok(proto::Ack {})
10603    }
10604
10605    fn buffer_ids_to_buffers(
10606        &mut self,
10607        buffer_ids: impl Iterator<Item = u64>,
10608        cx: &mut Context<Self>,
10609    ) -> Vec<Entity<Buffer>> {
10610        buffer_ids
10611            .into_iter()
10612            .flat_map(|buffer_id| {
10613                self.buffer_store
10614                    .read(cx)
10615                    .get(BufferId::new(buffer_id).log_err()?)
10616            })
10617            .collect::<Vec<_>>()
10618    }
10619
10620    async fn handle_apply_additional_edits_for_completion(
10621        this: Entity<Self>,
10622        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10623        mut cx: AsyncApp,
10624    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10625        let (buffer, completion, all_commit_ranges) = this.update(&mut cx, |this, cx| {
10626            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10627            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10628            let completion = Self::deserialize_completion(
10629                envelope.payload.completion.context("invalid completion")?,
10630            )?;
10631            let all_commit_ranges = envelope
10632                .payload
10633                .all_commit_ranges
10634                .into_iter()
10635                .map(language::proto::deserialize_anchor_range)
10636                .collect::<Result<Vec<_>, _>>()?;
10637            anyhow::Ok((buffer, completion, all_commit_ranges))
10638        })?;
10639
10640        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10641            this.apply_additional_edits_for_completion(
10642                buffer,
10643                Rc::new(RefCell::new(Box::new([Completion {
10644                    replace_range: completion.replace_range,
10645                    new_text: completion.new_text,
10646                    source: completion.source,
10647                    documentation: None,
10648                    label: CodeLabel::default(),
10649                    match_start: None,
10650                    snippet_deduplication_key: None,
10651                    insert_text_mode: None,
10652                    icon_path: None,
10653                    confirm: None,
10654                }]))),
10655                0,
10656                false,
10657                all_commit_ranges,
10658                cx,
10659            )
10660        });
10661
10662        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10663            transaction: apply_additional_edits
10664                .await?
10665                .as_ref()
10666                .map(language::proto::serialize_transaction),
10667        })
10668    }
10669
10670    pub fn last_formatting_failure(&self) -> Option<&str> {
10671        self.last_formatting_failure.as_deref()
10672    }
10673
10674    pub fn reset_last_formatting_failure(&mut self) {
10675        self.last_formatting_failure = None;
10676    }
10677
10678    pub fn environment_for_buffer(
10679        &self,
10680        buffer: &Entity<Buffer>,
10681        cx: &mut Context<Self>,
10682    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10683        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10684            environment.update(cx, |env, cx| {
10685                env.buffer_environment(buffer, &self.worktree_store, cx)
10686            })
10687        } else {
10688            Task::ready(None).shared()
10689        }
10690    }
10691
10692    pub fn format(
10693        &mut self,
10694        buffers: HashSet<Entity<Buffer>>,
10695        target: LspFormatTarget,
10696        push_to_history: bool,
10697        trigger: FormatTrigger,
10698        cx: &mut Context<Self>,
10699    ) -> Task<anyhow::Result<ProjectTransaction>> {
10700        let logger = zlog::scoped!("format");
10701        if self.as_local().is_some() {
10702            zlog::trace!(logger => "Formatting locally");
10703            let logger = zlog::scoped!(logger => "local");
10704            let buffers = buffers
10705                .into_iter()
10706                .map(|buffer_handle| {
10707                    let buffer = buffer_handle.read(cx);
10708                    let buffer_abs_path = File::from_dyn(buffer.file())
10709                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10710
10711                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10712                })
10713                .collect::<Vec<_>>();
10714
10715            cx.spawn(async move |lsp_store, cx| {
10716                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10717
10718                for (handle, abs_path, id) in buffers {
10719                    let env = lsp_store
10720                        .update(cx, |lsp_store, cx| {
10721                            lsp_store.environment_for_buffer(&handle, cx)
10722                        })?
10723                        .await;
10724
10725                    let ranges = match &target {
10726                        LspFormatTarget::Buffers => None,
10727                        LspFormatTarget::Ranges(ranges) => {
10728                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10729                        }
10730                    };
10731
10732                    formattable_buffers.push(FormattableBuffer {
10733                        handle,
10734                        abs_path,
10735                        env,
10736                        ranges,
10737                    });
10738                }
10739                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10740
10741                let format_timer = zlog::time!(logger => "Formatting buffers");
10742                let result = LocalLspStore::format_locally(
10743                    lsp_store.clone(),
10744                    formattable_buffers,
10745                    push_to_history,
10746                    trigger,
10747                    logger,
10748                    cx,
10749                )
10750                .await;
10751                format_timer.end();
10752
10753                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10754
10755                lsp_store.update(cx, |lsp_store, _| {
10756                    lsp_store.update_last_formatting_failure(&result);
10757                })?;
10758
10759                result
10760            })
10761        } else if let Some((client, project_id)) = self.upstream_client() {
10762            zlog::trace!(logger => "Formatting remotely");
10763            let logger = zlog::scoped!(logger => "remote");
10764
10765            let buffer_ranges = match &target {
10766                LspFormatTarget::Buffers => Vec::new(),
10767                LspFormatTarget::Ranges(ranges) => ranges
10768                    .iter()
10769                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10770                        buffer_id: buffer_id.to_proto(),
10771                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10772                    })
10773                    .collect(),
10774            };
10775
10776            let buffer_store = self.buffer_store();
10777            cx.spawn(async move |lsp_store, cx| {
10778                zlog::trace!(logger => "Sending remote format request");
10779                let request_timer = zlog::time!(logger => "remote format request");
10780                let result = client
10781                    .request(proto::FormatBuffers {
10782                        project_id,
10783                        trigger: trigger as i32,
10784                        buffer_ids: buffers
10785                            .iter()
10786                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10787                            .collect(),
10788                        buffer_ranges,
10789                    })
10790                    .await
10791                    .and_then(|result| result.transaction.context("missing transaction"));
10792                request_timer.end();
10793
10794                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10795
10796                lsp_store.update(cx, |lsp_store, _| {
10797                    lsp_store.update_last_formatting_failure(&result);
10798                })?;
10799
10800                let transaction_response = result?;
10801                let _timer = zlog::time!(logger => "deserializing project transaction");
10802                buffer_store
10803                    .update(cx, |buffer_store, cx| {
10804                        buffer_store.deserialize_project_transaction(
10805                            transaction_response,
10806                            push_to_history,
10807                            cx,
10808                        )
10809                    })
10810                    .await
10811            })
10812        } else {
10813            zlog::trace!(logger => "Not formatting");
10814            Task::ready(Ok(ProjectTransaction::default()))
10815        }
10816    }
10817
10818    async fn handle_format_buffers(
10819        this: Entity<Self>,
10820        envelope: TypedEnvelope<proto::FormatBuffers>,
10821        mut cx: AsyncApp,
10822    ) -> Result<proto::FormatBuffersResponse> {
10823        let sender_id = envelope.original_sender_id().unwrap_or_default();
10824        let format = this.update(&mut cx, |this, cx| {
10825            let mut buffers = HashSet::default();
10826            for buffer_id in &envelope.payload.buffer_ids {
10827                let buffer_id = BufferId::new(*buffer_id)?;
10828                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10829            }
10830
10831            let target = if envelope.payload.buffer_ranges.is_empty() {
10832                LspFormatTarget::Buffers
10833            } else {
10834                let mut ranges_map = BTreeMap::new();
10835                for buffer_range in &envelope.payload.buffer_ranges {
10836                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10837                    let ranges: Result<Vec<_>> = buffer_range
10838                        .ranges
10839                        .iter()
10840                        .map(|range| {
10841                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10842                        })
10843                        .collect();
10844                    ranges_map.insert(buffer_id, ranges?);
10845                }
10846                LspFormatTarget::Ranges(ranges_map)
10847            };
10848
10849            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10850            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10851        })?;
10852
10853        let project_transaction = format.await?;
10854        let project_transaction = this.update(&mut cx, |this, cx| {
10855            this.buffer_store.update(cx, |buffer_store, cx| {
10856                buffer_store.serialize_project_transaction_for_peer(
10857                    project_transaction,
10858                    sender_id,
10859                    cx,
10860                )
10861            })
10862        });
10863        Ok(proto::FormatBuffersResponse {
10864            transaction: Some(project_transaction),
10865        })
10866    }
10867
10868    async fn handle_apply_code_action_kind(
10869        this: Entity<Self>,
10870        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10871        mut cx: AsyncApp,
10872    ) -> Result<proto::ApplyCodeActionKindResponse> {
10873        let sender_id = envelope.original_sender_id().unwrap_or_default();
10874        let format = this.update(&mut cx, |this, cx| {
10875            let mut buffers = HashSet::default();
10876            for buffer_id in &envelope.payload.buffer_ids {
10877                let buffer_id = BufferId::new(*buffer_id)?;
10878                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10879            }
10880            let kind = match envelope.payload.kind.as_str() {
10881                "" => CodeActionKind::EMPTY,
10882                "quickfix" => CodeActionKind::QUICKFIX,
10883                "refactor" => CodeActionKind::REFACTOR,
10884                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10885                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10886                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10887                "source" => CodeActionKind::SOURCE,
10888                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10889                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10890                _ => anyhow::bail!(
10891                    "Invalid code action kind {}",
10892                    envelope.payload.kind.as_str()
10893                ),
10894            };
10895            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10896        })?;
10897
10898        let project_transaction = format.await?;
10899        let project_transaction = this.update(&mut cx, |this, cx| {
10900            this.buffer_store.update(cx, |buffer_store, cx| {
10901                buffer_store.serialize_project_transaction_for_peer(
10902                    project_transaction,
10903                    sender_id,
10904                    cx,
10905                )
10906            })
10907        });
10908        Ok(proto::ApplyCodeActionKindResponse {
10909            transaction: Some(project_transaction),
10910        })
10911    }
10912
10913    async fn shutdown_language_server(
10914        server_state: Option<LanguageServerState>,
10915        name: LanguageServerName,
10916        cx: &mut AsyncApp,
10917    ) {
10918        let server = match server_state {
10919            Some(LanguageServerState::Starting { startup, .. }) => {
10920                let mut timer = cx
10921                    .background_executor()
10922                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10923                    .fuse();
10924
10925                select! {
10926                    server = startup.fuse() => server,
10927                    () = timer => {
10928                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10929                        None
10930                    },
10931                }
10932            }
10933
10934            Some(LanguageServerState::Running { server, .. }) => Some(server),
10935
10936            None => None,
10937        };
10938
10939        let Some(server) = server else { return };
10940        if let Some(shutdown) = server.shutdown() {
10941            shutdown.await;
10942        }
10943    }
10944
10945    // Returns a list of all of the worktrees which no longer have a language server and the root path
10946    // for the stopped server
10947    fn stop_local_language_server(
10948        &mut self,
10949        server_id: LanguageServerId,
10950        cx: &mut Context<Self>,
10951    ) -> Task<()> {
10952        let local = match &mut self.mode {
10953            LspStoreMode::Local(local) => local,
10954            _ => {
10955                return Task::ready(());
10956            }
10957        };
10958
10959        // Remove this server ID from all entries in the given worktree.
10960        local
10961            .language_server_ids
10962            .retain(|_, state| state.id != server_id);
10963        self.buffer_store.update(cx, |buffer_store, cx| {
10964            for buffer in buffer_store.buffers() {
10965                buffer.update(cx, |buffer, cx| {
10966                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10967                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10968                });
10969            }
10970        });
10971
10972        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
10973        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10974            summaries.retain(|path, summaries_by_server_id| {
10975                if summaries_by_server_id.remove(&server_id).is_some() {
10976                    if let Some((client, project_id)) = self.downstream_client.clone() {
10977                        client
10978                            .send(proto::UpdateDiagnosticSummary {
10979                                project_id,
10980                                worktree_id: worktree_id.to_proto(),
10981                                summary: Some(proto::DiagnosticSummary {
10982                                    path: path.as_ref().to_proto(),
10983                                    language_server_id: server_id.0 as u64,
10984                                    error_count: 0,
10985                                    warning_count: 0,
10986                                }),
10987                                more_summaries: Vec::new(),
10988                            })
10989                            .log_err();
10990                    }
10991                    cleared_paths.push(ProjectPath {
10992                        worktree_id: *worktree_id,
10993                        path: path.clone(),
10994                    });
10995                    !summaries_by_server_id.is_empty()
10996                } else {
10997                    true
10998                }
10999            });
11000        }
11001        if !cleared_paths.is_empty() {
11002            cx.emit(LspStoreEvent::DiagnosticsUpdated {
11003                server_id,
11004                paths: cleared_paths,
11005            });
11006        }
11007
11008        let local = self.as_local_mut().unwrap();
11009        for diagnostics in local.diagnostics.values_mut() {
11010            diagnostics.retain(|_, diagnostics_by_server_id| {
11011                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
11012                    diagnostics_by_server_id.remove(ix);
11013                    !diagnostics_by_server_id.is_empty()
11014                } else {
11015                    true
11016                }
11017            });
11018        }
11019        local.language_server_watched_paths.remove(&server_id);
11020
11021        let server_state = local.language_servers.remove(&server_id);
11022        self.cleanup_lsp_data(server_id);
11023        let name = self
11024            .language_server_statuses
11025            .remove(&server_id)
11026            .map(|status| status.name)
11027            .or_else(|| {
11028                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
11029                    Some(adapter.name())
11030                } else {
11031                    None
11032                }
11033            });
11034
11035        if let Some(name) = name {
11036            log::info!("stopping language server {name}");
11037            self.languages
11038                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
11039            cx.notify();
11040
11041            return cx.spawn(async move |lsp_store, cx| {
11042                Self::shutdown_language_server(server_state, name.clone(), cx).await;
11043                lsp_store
11044                    .update(cx, |lsp_store, cx| {
11045                        lsp_store
11046                            .languages
11047                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
11048                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11049                        cx.notify();
11050                    })
11051                    .ok();
11052            });
11053        }
11054
11055        if server_state.is_some() {
11056            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11057        }
11058        Task::ready(())
11059    }
11060
11061    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
11062        self.shutdown_all_language_servers(cx).detach();
11063    }
11064
11065    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
11066        if let Some((client, project_id)) = self.upstream_client() {
11067            let request = client.request(proto::StopLanguageServers {
11068                project_id,
11069                buffer_ids: Vec::new(),
11070                also_servers: Vec::new(),
11071                all: true,
11072            });
11073            cx.background_spawn(async move {
11074                request.await.ok();
11075            })
11076        } else {
11077            let Some(local) = self.as_local_mut() else {
11078                return Task::ready(());
11079            };
11080            let language_servers_to_stop = local
11081                .language_server_ids
11082                .values()
11083                .map(|state| state.id)
11084                .collect();
11085            local.lsp_tree.remove_nodes(&language_servers_to_stop);
11086            let tasks = language_servers_to_stop
11087                .into_iter()
11088                .map(|server| self.stop_local_language_server(server, cx))
11089                .collect::<Vec<_>>();
11090            cx.background_spawn(async move {
11091                futures::future::join_all(tasks).await;
11092            })
11093        }
11094    }
11095
11096    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
11097        let buffers = self.buffer_store.read(cx).buffers().collect();
11098        self.restart_language_servers_for_buffers(buffers, HashSet::default(), cx);
11099    }
11100
11101    pub fn restart_language_servers_for_buffers(
11102        &mut self,
11103        buffers: Vec<Entity<Buffer>>,
11104        only_restart_servers: HashSet<LanguageServerSelector>,
11105        cx: &mut Context<Self>,
11106    ) {
11107        if let Some((client, project_id)) = self.upstream_client() {
11108            let request = client.request(proto::RestartLanguageServers {
11109                project_id,
11110                buffer_ids: buffers
11111                    .into_iter()
11112                    .map(|b| b.read(cx).remote_id().to_proto())
11113                    .collect(),
11114                only_servers: only_restart_servers
11115                    .into_iter()
11116                    .map(|selector| {
11117                        let selector = match selector {
11118                            LanguageServerSelector::Id(language_server_id) => {
11119                                proto::language_server_selector::Selector::ServerId(
11120                                    language_server_id.to_proto(),
11121                                )
11122                            }
11123                            LanguageServerSelector::Name(language_server_name) => {
11124                                proto::language_server_selector::Selector::Name(
11125                                    language_server_name.to_string(),
11126                                )
11127                            }
11128                        };
11129                        proto::LanguageServerSelector {
11130                            selector: Some(selector),
11131                        }
11132                    })
11133                    .collect(),
11134                all: false,
11135            });
11136            cx.background_spawn(request).detach_and_log_err(cx);
11137        } else {
11138            let stop_task = if only_restart_servers.is_empty() {
11139                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11140            } else {
11141                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11142            };
11143            cx.spawn(async move |lsp_store, cx| {
11144                stop_task.await;
11145                lsp_store.update(cx, |lsp_store, cx| {
11146                    for buffer in buffers {
11147                        lsp_store.register_buffer_with_language_servers(
11148                            &buffer,
11149                            only_restart_servers.clone(),
11150                            true,
11151                            cx,
11152                        );
11153                    }
11154                })
11155            })
11156            .detach();
11157        }
11158    }
11159
11160    pub fn stop_language_servers_for_buffers(
11161        &mut self,
11162        buffers: Vec<Entity<Buffer>>,
11163        also_stop_servers: HashSet<LanguageServerSelector>,
11164        cx: &mut Context<Self>,
11165    ) -> Task<Result<()>> {
11166        if let Some((client, project_id)) = self.upstream_client() {
11167            let request = client.request(proto::StopLanguageServers {
11168                project_id,
11169                buffer_ids: buffers
11170                    .into_iter()
11171                    .map(|b| b.read(cx).remote_id().to_proto())
11172                    .collect(),
11173                also_servers: also_stop_servers
11174                    .into_iter()
11175                    .map(|selector| {
11176                        let selector = match selector {
11177                            LanguageServerSelector::Id(language_server_id) => {
11178                                proto::language_server_selector::Selector::ServerId(
11179                                    language_server_id.to_proto(),
11180                                )
11181                            }
11182                            LanguageServerSelector::Name(language_server_name) => {
11183                                proto::language_server_selector::Selector::Name(
11184                                    language_server_name.to_string(),
11185                                )
11186                            }
11187                        };
11188                        proto::LanguageServerSelector {
11189                            selector: Some(selector),
11190                        }
11191                    })
11192                    .collect(),
11193                all: false,
11194            });
11195            cx.background_spawn(async move {
11196                let _ = request.await?;
11197                Ok(())
11198            })
11199        } else {
11200            let task =
11201                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11202            cx.background_spawn(async move {
11203                task.await;
11204                Ok(())
11205            })
11206        }
11207    }
11208
11209    fn stop_local_language_servers_for_buffers(
11210        &mut self,
11211        buffers: &[Entity<Buffer>],
11212        also_stop_servers: HashSet<LanguageServerSelector>,
11213        cx: &mut Context<Self>,
11214    ) -> Task<()> {
11215        let Some(local) = self.as_local_mut() else {
11216            return Task::ready(());
11217        };
11218        let mut language_server_names_to_stop = BTreeSet::default();
11219        let mut language_servers_to_stop = also_stop_servers
11220            .into_iter()
11221            .flat_map(|selector| match selector {
11222                LanguageServerSelector::Id(id) => Some(id),
11223                LanguageServerSelector::Name(name) => {
11224                    language_server_names_to_stop.insert(name);
11225                    None
11226                }
11227            })
11228            .collect::<BTreeSet<_>>();
11229
11230        let mut covered_worktrees = HashSet::default();
11231        for buffer in buffers {
11232            buffer.update(cx, |buffer, cx| {
11233                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11234                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11235                    && covered_worktrees.insert(worktree_id)
11236                {
11237                    language_server_names_to_stop.retain(|name| {
11238                        let old_ids_count = language_servers_to_stop.len();
11239                        let all_language_servers_with_this_name = local
11240                            .language_server_ids
11241                            .iter()
11242                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11243                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11244                        old_ids_count == language_servers_to_stop.len()
11245                    });
11246                }
11247            });
11248        }
11249        for name in language_server_names_to_stop {
11250            language_servers_to_stop.extend(
11251                local
11252                    .language_server_ids
11253                    .iter()
11254                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11255            );
11256        }
11257
11258        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11259        let tasks = language_servers_to_stop
11260            .into_iter()
11261            .map(|server| self.stop_local_language_server(server, cx))
11262            .collect::<Vec<_>>();
11263
11264        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11265    }
11266
11267    #[cfg(any(test, feature = "test-support"))]
11268    pub fn update_diagnostics(
11269        &mut self,
11270        server_id: LanguageServerId,
11271        diagnostics: lsp::PublishDiagnosticsParams,
11272        result_id: Option<SharedString>,
11273        source_kind: DiagnosticSourceKind,
11274        disk_based_sources: &[String],
11275        cx: &mut Context<Self>,
11276    ) -> Result<()> {
11277        self.merge_lsp_diagnostics(
11278            source_kind,
11279            vec![DocumentDiagnosticsUpdate {
11280                diagnostics,
11281                result_id,
11282                server_id,
11283                disk_based_sources: Cow::Borrowed(disk_based_sources),
11284                registration_id: None,
11285            }],
11286            |_, _, _| false,
11287            cx,
11288        )
11289    }
11290
11291    pub fn merge_lsp_diagnostics(
11292        &mut self,
11293        source_kind: DiagnosticSourceKind,
11294        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11295        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11296        cx: &mut Context<Self>,
11297    ) -> Result<()> {
11298        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11299        let updates = lsp_diagnostics
11300            .into_iter()
11301            .filter_map(|update| {
11302                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11303                Some(DocumentDiagnosticsUpdate {
11304                    diagnostics: self.lsp_to_document_diagnostics(
11305                        abs_path,
11306                        source_kind,
11307                        update.server_id,
11308                        update.diagnostics,
11309                        &update.disk_based_sources,
11310                        update.registration_id.clone(),
11311                    ),
11312                    result_id: update.result_id,
11313                    server_id: update.server_id,
11314                    disk_based_sources: update.disk_based_sources,
11315                    registration_id: update.registration_id,
11316                })
11317            })
11318            .collect();
11319        self.merge_diagnostic_entries(updates, merge, cx)?;
11320        Ok(())
11321    }
11322
11323    fn lsp_to_document_diagnostics(
11324        &mut self,
11325        document_abs_path: PathBuf,
11326        source_kind: DiagnosticSourceKind,
11327        server_id: LanguageServerId,
11328        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11329        disk_based_sources: &[String],
11330        registration_id: Option<SharedString>,
11331    ) -> DocumentDiagnostics {
11332        let mut diagnostics = Vec::default();
11333        let mut primary_diagnostic_group_ids = HashMap::default();
11334        let mut sources_by_group_id = HashMap::default();
11335        let mut supporting_diagnostics = HashMap::default();
11336
11337        let adapter = self.language_server_adapter_for_id(server_id);
11338
11339        // Ensure that primary diagnostics are always the most severe
11340        lsp_diagnostics
11341            .diagnostics
11342            .sort_by_key(|item| item.severity);
11343
11344        for diagnostic in &lsp_diagnostics.diagnostics {
11345            let source = diagnostic.source.as_ref();
11346            let range = range_from_lsp(diagnostic.range);
11347            let is_supporting = diagnostic
11348                .related_information
11349                .as_ref()
11350                .is_some_and(|infos| {
11351                    infos.iter().any(|info| {
11352                        primary_diagnostic_group_ids.contains_key(&(
11353                            source,
11354                            diagnostic.code.clone(),
11355                            range_from_lsp(info.location.range),
11356                        ))
11357                    })
11358                });
11359
11360            let is_unnecessary = diagnostic
11361                .tags
11362                .as_ref()
11363                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11364
11365            let underline = self
11366                .language_server_adapter_for_id(server_id)
11367                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11368
11369            if is_supporting {
11370                supporting_diagnostics.insert(
11371                    (source, diagnostic.code.clone(), range),
11372                    (diagnostic.severity, is_unnecessary),
11373                );
11374            } else {
11375                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11376                let is_disk_based =
11377                    source.is_some_and(|source| disk_based_sources.contains(source));
11378
11379                sources_by_group_id.insert(group_id, source);
11380                primary_diagnostic_group_ids
11381                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11382
11383                diagnostics.push(DiagnosticEntry {
11384                    range,
11385                    diagnostic: Diagnostic {
11386                        source: diagnostic.source.clone(),
11387                        source_kind,
11388                        code: diagnostic.code.clone(),
11389                        code_description: diagnostic
11390                            .code_description
11391                            .as_ref()
11392                            .and_then(|d| d.href.clone()),
11393                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11394                        markdown: adapter.as_ref().and_then(|adapter| {
11395                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11396                        }),
11397                        message: diagnostic.message.trim().to_string(),
11398                        group_id,
11399                        is_primary: true,
11400                        is_disk_based,
11401                        is_unnecessary,
11402                        underline,
11403                        data: diagnostic.data.clone(),
11404                        registration_id: registration_id.clone(),
11405                    },
11406                });
11407                if let Some(infos) = &diagnostic.related_information {
11408                    for info in infos {
11409                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11410                            let range = range_from_lsp(info.location.range);
11411                            diagnostics.push(DiagnosticEntry {
11412                                range,
11413                                diagnostic: Diagnostic {
11414                                    source: diagnostic.source.clone(),
11415                                    source_kind,
11416                                    code: diagnostic.code.clone(),
11417                                    code_description: diagnostic
11418                                        .code_description
11419                                        .as_ref()
11420                                        .and_then(|d| d.href.clone()),
11421                                    severity: DiagnosticSeverity::INFORMATION,
11422                                    markdown: adapter.as_ref().and_then(|adapter| {
11423                                        adapter.diagnostic_message_to_markdown(&info.message)
11424                                    }),
11425                                    message: info.message.trim().to_string(),
11426                                    group_id,
11427                                    is_primary: false,
11428                                    is_disk_based,
11429                                    is_unnecessary: false,
11430                                    underline,
11431                                    data: diagnostic.data.clone(),
11432                                    registration_id: registration_id.clone(),
11433                                },
11434                            });
11435                        }
11436                    }
11437                }
11438            }
11439        }
11440
11441        for entry in &mut diagnostics {
11442            let diagnostic = &mut entry.diagnostic;
11443            if !diagnostic.is_primary {
11444                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11445                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11446                    source,
11447                    diagnostic.code.clone(),
11448                    entry.range.clone(),
11449                )) {
11450                    if let Some(severity) = severity {
11451                        diagnostic.severity = severity;
11452                    }
11453                    diagnostic.is_unnecessary = is_unnecessary;
11454                }
11455            }
11456        }
11457
11458        DocumentDiagnostics {
11459            diagnostics,
11460            document_abs_path,
11461            version: lsp_diagnostics.version,
11462        }
11463    }
11464
11465    fn insert_newly_running_language_server(
11466        &mut self,
11467        adapter: Arc<CachedLspAdapter>,
11468        language_server: Arc<LanguageServer>,
11469        server_id: LanguageServerId,
11470        key: LanguageServerSeed,
11471        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11472        cx: &mut Context<Self>,
11473    ) {
11474        let Some(local) = self.as_local_mut() else {
11475            return;
11476        };
11477        // If the language server for this key doesn't match the server id, don't store the
11478        // server. Which will cause it to be dropped, killing the process
11479        if local
11480            .language_server_ids
11481            .get(&key)
11482            .map(|state| state.id != server_id)
11483            .unwrap_or(false)
11484        {
11485            return;
11486        }
11487
11488        // Update language_servers collection with Running variant of LanguageServerState
11489        // indicating that the server is up and running and ready
11490        let workspace_folders = workspace_folders.lock().clone();
11491        language_server.set_workspace_folders(workspace_folders);
11492
11493        let workspace_diagnostics_refresh_tasks = language_server
11494            .capabilities()
11495            .diagnostic_provider
11496            .and_then(|provider| {
11497                local
11498                    .language_server_dynamic_registrations
11499                    .entry(server_id)
11500                    .or_default()
11501                    .diagnostics
11502                    .entry(None)
11503                    .or_insert(provider.clone());
11504                let workspace_refresher =
11505                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11506
11507                Some((None, workspace_refresher))
11508            })
11509            .into_iter()
11510            .collect();
11511        local.language_servers.insert(
11512            server_id,
11513            LanguageServerState::Running {
11514                workspace_diagnostics_refresh_tasks,
11515                adapter: adapter.clone(),
11516                server: language_server.clone(),
11517                simulate_disk_based_diagnostics_completion: None,
11518            },
11519        );
11520        local
11521            .languages
11522            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11523        if let Some(file_ops_caps) = language_server
11524            .capabilities()
11525            .workspace
11526            .as_ref()
11527            .and_then(|ws| ws.file_operations.as_ref())
11528        {
11529            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11530            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11531            if did_rename_caps.or(will_rename_caps).is_some() {
11532                let watcher = RenamePathsWatchedForServer::default()
11533                    .with_did_rename_patterns(did_rename_caps)
11534                    .with_will_rename_patterns(will_rename_caps);
11535                local
11536                    .language_server_paths_watched_for_rename
11537                    .insert(server_id, watcher);
11538            }
11539        }
11540
11541        self.language_server_statuses.insert(
11542            server_id,
11543            LanguageServerStatus {
11544                name: language_server.name(),
11545                server_version: language_server.version(),
11546                server_readable_version: language_server.readable_version(),
11547                pending_work: Default::default(),
11548                has_pending_diagnostic_updates: false,
11549                progress_tokens: Default::default(),
11550                worktree: Some(key.worktree_id),
11551                binary: Some(language_server.binary().clone()),
11552                configuration: Some(language_server.configuration().clone()),
11553                workspace_folders: language_server.workspace_folders(),
11554                process_id: language_server.process_id(),
11555            },
11556        );
11557
11558        cx.emit(LspStoreEvent::LanguageServerAdded(
11559            server_id,
11560            language_server.name(),
11561            Some(key.worktree_id),
11562        ));
11563
11564        let server_capabilities = language_server.capabilities();
11565        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11566            downstream_client
11567                .send(proto::StartLanguageServer {
11568                    project_id: *project_id,
11569                    server: Some(proto::LanguageServer {
11570                        id: server_id.to_proto(),
11571                        name: language_server.name().to_string(),
11572                        worktree_id: Some(key.worktree_id.to_proto()),
11573                    }),
11574                    capabilities: serde_json::to_string(&server_capabilities)
11575                        .expect("serializing server LSP capabilities"),
11576                })
11577                .log_err();
11578        }
11579        self.lsp_server_capabilities
11580            .insert(server_id, server_capabilities);
11581
11582        // Tell the language server about every open buffer in the worktree that matches the language.
11583        // Also check for buffers in worktrees that reused this server
11584        let mut worktrees_using_server = vec![key.worktree_id];
11585        if let Some(local) = self.as_local() {
11586            // Find all worktrees that have this server in their language server tree
11587            for (worktree_id, servers) in &local.lsp_tree.instances {
11588                if *worktree_id != key.worktree_id {
11589                    for server_map in servers.roots.values() {
11590                        if server_map
11591                            .values()
11592                            .any(|(node, _)| node.id() == Some(server_id))
11593                        {
11594                            worktrees_using_server.push(*worktree_id);
11595                        }
11596                    }
11597                }
11598            }
11599        }
11600
11601        let mut buffer_paths_registered = Vec::new();
11602        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11603            let mut lsp_adapters = HashMap::default();
11604            for buffer_handle in buffer_store.buffers() {
11605                let buffer = buffer_handle.read(cx);
11606                let file = match File::from_dyn(buffer.file()) {
11607                    Some(file) => file,
11608                    None => continue,
11609                };
11610                let language = match buffer.language() {
11611                    Some(language) => language,
11612                    None => continue,
11613                };
11614
11615                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11616                    || !lsp_adapters
11617                        .entry(language.name())
11618                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11619                        .iter()
11620                        .any(|a| a.name == key.name)
11621                {
11622                    continue;
11623                }
11624                // didOpen
11625                let file = match file.as_local() {
11626                    Some(file) => file,
11627                    None => continue,
11628                };
11629
11630                let local = self.as_local_mut().unwrap();
11631
11632                let buffer_id = buffer.remote_id();
11633                if local.registered_buffers.contains_key(&buffer_id) {
11634                    let abs_path = file.abs_path(cx);
11635                    let uri = match lsp::Uri::from_file_path(&abs_path) {
11636                        Ok(uri) => uri,
11637                        Err(()) => {
11638                            log::error!("failed to convert path to URI: {:?}", abs_path);
11639                            continue;
11640                        }
11641                    };
11642
11643                    let versions = local
11644                        .buffer_snapshots
11645                        .entry(buffer_id)
11646                        .or_default()
11647                        .entry(server_id)
11648                        .and_modify(|_| {
11649                            assert!(
11650                            false,
11651                            "There should not be an existing snapshot for a newly inserted buffer"
11652                        )
11653                        })
11654                        .or_insert_with(|| {
11655                            vec![LspBufferSnapshot {
11656                                version: 0,
11657                                snapshot: buffer.text_snapshot(),
11658                            }]
11659                        });
11660
11661                    let snapshot = versions.last().unwrap();
11662                    let version = snapshot.version;
11663                    let initial_snapshot = &snapshot.snapshot;
11664                    language_server.register_buffer(
11665                        uri,
11666                        adapter.language_id(&language.name()),
11667                        version,
11668                        initial_snapshot.text(),
11669                    );
11670                    buffer_paths_registered.push((buffer_id, abs_path));
11671                    local
11672                        .buffers_opened_in_servers
11673                        .entry(buffer_id)
11674                        .or_default()
11675                        .insert(server_id);
11676                }
11677                buffer_handle.update(cx, |buffer, cx| {
11678                    buffer.set_completion_triggers(
11679                        server_id,
11680                        language_server
11681                            .capabilities()
11682                            .completion_provider
11683                            .as_ref()
11684                            .and_then(|provider| {
11685                                provider
11686                                    .trigger_characters
11687                                    .as_ref()
11688                                    .map(|characters| characters.iter().cloned().collect())
11689                            })
11690                            .unwrap_or_default(),
11691                        cx,
11692                    )
11693                });
11694            }
11695        });
11696
11697        for (buffer_id, abs_path) in buffer_paths_registered {
11698            cx.emit(LspStoreEvent::LanguageServerUpdate {
11699                language_server_id: server_id,
11700                name: Some(adapter.name()),
11701                message: proto::update_language_server::Variant::RegisteredForBuffer(
11702                    proto::RegisteredForBuffer {
11703                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11704                        buffer_id: buffer_id.to_proto(),
11705                    },
11706                ),
11707            });
11708        }
11709
11710        cx.notify();
11711    }
11712
11713    pub fn language_servers_running_disk_based_diagnostics(
11714        &self,
11715    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11716        self.language_server_statuses
11717            .iter()
11718            .filter_map(|(id, status)| {
11719                if status.has_pending_diagnostic_updates {
11720                    Some(*id)
11721                } else {
11722                    None
11723                }
11724            })
11725    }
11726
11727    pub(crate) fn cancel_language_server_work_for_buffers(
11728        &mut self,
11729        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11730        cx: &mut Context<Self>,
11731    ) {
11732        if let Some((client, project_id)) = self.upstream_client() {
11733            let request = client.request(proto::CancelLanguageServerWork {
11734                project_id,
11735                work: Some(proto::cancel_language_server_work::Work::Buffers(
11736                    proto::cancel_language_server_work::Buffers {
11737                        buffer_ids: buffers
11738                            .into_iter()
11739                            .map(|b| b.read(cx).remote_id().to_proto())
11740                            .collect(),
11741                    },
11742                )),
11743            });
11744            cx.background_spawn(request).detach_and_log_err(cx);
11745        } else if let Some(local) = self.as_local() {
11746            let servers = buffers
11747                .into_iter()
11748                .flat_map(|buffer| {
11749                    buffer.update(cx, |buffer, cx| {
11750                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11751                    })
11752                })
11753                .collect::<HashSet<_>>();
11754            for server_id in servers {
11755                self.cancel_language_server_work(server_id, None, cx);
11756            }
11757        }
11758    }
11759
11760    pub(crate) fn cancel_language_server_work(
11761        &mut self,
11762        server_id: LanguageServerId,
11763        token_to_cancel: Option<ProgressToken>,
11764        cx: &mut Context<Self>,
11765    ) {
11766        if let Some(local) = self.as_local() {
11767            let status = self.language_server_statuses.get(&server_id);
11768            let server = local.language_servers.get(&server_id);
11769            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11770            {
11771                for (token, progress) in &status.pending_work {
11772                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11773                        && token != token_to_cancel
11774                    {
11775                        continue;
11776                    }
11777                    if progress.is_cancellable {
11778                        server
11779                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11780                                WorkDoneProgressCancelParams {
11781                                    token: token.to_lsp(),
11782                                },
11783                            )
11784                            .ok();
11785                    }
11786                }
11787            }
11788        } else if let Some((client, project_id)) = self.upstream_client() {
11789            let request = client.request(proto::CancelLanguageServerWork {
11790                project_id,
11791                work: Some(
11792                    proto::cancel_language_server_work::Work::LanguageServerWork(
11793                        proto::cancel_language_server_work::LanguageServerWork {
11794                            language_server_id: server_id.to_proto(),
11795                            token: token_to_cancel.map(|token| token.to_proto()),
11796                        },
11797                    ),
11798                ),
11799            });
11800            cx.background_spawn(request).detach_and_log_err(cx);
11801        }
11802    }
11803
11804    fn register_supplementary_language_server(
11805        &mut self,
11806        id: LanguageServerId,
11807        name: LanguageServerName,
11808        server: Arc<LanguageServer>,
11809        cx: &mut Context<Self>,
11810    ) {
11811        if let Some(local) = self.as_local_mut() {
11812            local
11813                .supplementary_language_servers
11814                .insert(id, (name.clone(), server));
11815            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11816        }
11817    }
11818
11819    fn unregister_supplementary_language_server(
11820        &mut self,
11821        id: LanguageServerId,
11822        cx: &mut Context<Self>,
11823    ) {
11824        if let Some(local) = self.as_local_mut() {
11825            local.supplementary_language_servers.remove(&id);
11826            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11827        }
11828    }
11829
11830    pub(crate) fn supplementary_language_servers(
11831        &self,
11832    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11833        self.as_local().into_iter().flat_map(|local| {
11834            local
11835                .supplementary_language_servers
11836                .iter()
11837                .map(|(id, (name, _))| (*id, name.clone()))
11838        })
11839    }
11840
11841    pub fn language_server_adapter_for_id(
11842        &self,
11843        id: LanguageServerId,
11844    ) -> Option<Arc<CachedLspAdapter>> {
11845        self.as_local()
11846            .and_then(|local| local.language_servers.get(&id))
11847            .and_then(|language_server_state| match language_server_state {
11848                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11849                _ => None,
11850            })
11851    }
11852
11853    pub(super) fn update_local_worktree_language_servers(
11854        &mut self,
11855        worktree_handle: &Entity<Worktree>,
11856        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11857        cx: &mut Context<Self>,
11858    ) {
11859        if changes.is_empty() {
11860            return;
11861        }
11862
11863        let Some(local) = self.as_local() else { return };
11864
11865        local.prettier_store.update(cx, |prettier_store, cx| {
11866            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11867        });
11868
11869        let worktree_id = worktree_handle.read(cx).id();
11870        let mut language_server_ids = local
11871            .language_server_ids
11872            .iter()
11873            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11874            .collect::<Vec<_>>();
11875        language_server_ids.sort();
11876        language_server_ids.dedup();
11877
11878        // let abs_path = worktree_handle.read(cx).abs_path();
11879        for server_id in &language_server_ids {
11880            if let Some(LanguageServerState::Running { server, .. }) =
11881                local.language_servers.get(server_id)
11882                && let Some(watched_paths) = local
11883                    .language_server_watched_paths
11884                    .get(server_id)
11885                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11886            {
11887                let params = lsp::DidChangeWatchedFilesParams {
11888                    changes: changes
11889                        .iter()
11890                        .filter_map(|(path, _, change)| {
11891                            if !watched_paths.is_match(path.as_std_path()) {
11892                                return None;
11893                            }
11894                            let typ = match change {
11895                                PathChange::Loaded => return None,
11896                                PathChange::Added => lsp::FileChangeType::CREATED,
11897                                PathChange::Removed => lsp::FileChangeType::DELETED,
11898                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11899                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11900                            };
11901                            let uri = lsp::Uri::from_file_path(
11902                                worktree_handle.read(cx).absolutize(&path),
11903                            )
11904                            .ok()?;
11905                            Some(lsp::FileEvent { uri, typ })
11906                        })
11907                        .collect(),
11908                };
11909                if !params.changes.is_empty() {
11910                    server
11911                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11912                        .ok();
11913                }
11914            }
11915        }
11916        for (path, _, _) in changes {
11917            if let Some(file_name) = path.file_name()
11918                && local.watched_manifest_filenames.contains(file_name)
11919            {
11920                self.request_workspace_config_refresh();
11921                break;
11922            }
11923        }
11924    }
11925
11926    pub fn wait_for_remote_buffer(
11927        &mut self,
11928        id: BufferId,
11929        cx: &mut Context<Self>,
11930    ) -> Task<Result<Entity<Buffer>>> {
11931        self.buffer_store.update(cx, |buffer_store, cx| {
11932            buffer_store.wait_for_remote_buffer(id, cx)
11933        })
11934    }
11935
11936    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11937        let mut result = proto::Symbol {
11938            language_server_name: symbol.language_server_name.0.to_string(),
11939            source_worktree_id: symbol.source_worktree_id.to_proto(),
11940            language_server_id: symbol.source_language_server_id.to_proto(),
11941            name: symbol.name.clone(),
11942            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11943            start: Some(proto::PointUtf16 {
11944                row: symbol.range.start.0.row,
11945                column: symbol.range.start.0.column,
11946            }),
11947            end: Some(proto::PointUtf16 {
11948                row: symbol.range.end.0.row,
11949                column: symbol.range.end.0.column,
11950            }),
11951            worktree_id: Default::default(),
11952            path: Default::default(),
11953            signature: Default::default(),
11954            container_name: symbol.container_name.clone(),
11955        };
11956        match &symbol.path {
11957            SymbolLocation::InProject(path) => {
11958                result.worktree_id = path.worktree_id.to_proto();
11959                result.path = path.path.to_proto();
11960            }
11961            SymbolLocation::OutsideProject {
11962                abs_path,
11963                signature,
11964            } => {
11965                result.path = abs_path.to_string_lossy().into_owned();
11966                result.signature = signature.to_vec();
11967            }
11968        }
11969        result
11970    }
11971
11972    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11973        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11974        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11975        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11976
11977        let path = if serialized_symbol.signature.is_empty() {
11978            SymbolLocation::InProject(ProjectPath {
11979                worktree_id,
11980                path: RelPath::from_proto(&serialized_symbol.path)
11981                    .context("invalid symbol path")?,
11982            })
11983        } else {
11984            SymbolLocation::OutsideProject {
11985                abs_path: Path::new(&serialized_symbol.path).into(),
11986                signature: serialized_symbol
11987                    .signature
11988                    .try_into()
11989                    .map_err(|_| anyhow!("invalid signature"))?,
11990            }
11991        };
11992
11993        let start = serialized_symbol.start.context("invalid start")?;
11994        let end = serialized_symbol.end.context("invalid end")?;
11995        Ok(CoreSymbol {
11996            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11997            source_worktree_id,
11998            source_language_server_id: LanguageServerId::from_proto(
11999                serialized_symbol.language_server_id,
12000            ),
12001            path,
12002            name: serialized_symbol.name,
12003            range: Unclipped(PointUtf16::new(start.row, start.column))
12004                ..Unclipped(PointUtf16::new(end.row, end.column)),
12005            kind,
12006            container_name: serialized_symbol.container_name,
12007        })
12008    }
12009
12010    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
12011        let mut serialized_completion = proto::Completion {
12012            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
12013            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
12014            new_text: completion.new_text.clone(),
12015            ..proto::Completion::default()
12016        };
12017        match &completion.source {
12018            CompletionSource::Lsp {
12019                insert_range,
12020                server_id,
12021                lsp_completion,
12022                lsp_defaults,
12023                resolved,
12024            } => {
12025                let (old_insert_start, old_insert_end) = insert_range
12026                    .as_ref()
12027                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
12028                    .unzip();
12029
12030                serialized_completion.old_insert_start = old_insert_start;
12031                serialized_completion.old_insert_end = old_insert_end;
12032                serialized_completion.source = proto::completion::Source::Lsp as i32;
12033                serialized_completion.server_id = server_id.0 as u64;
12034                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
12035                serialized_completion.lsp_defaults = lsp_defaults
12036                    .as_deref()
12037                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
12038                serialized_completion.resolved = *resolved;
12039            }
12040            CompletionSource::BufferWord {
12041                word_range,
12042                resolved,
12043            } => {
12044                serialized_completion.source = proto::completion::Source::BufferWord as i32;
12045                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
12046                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
12047                serialized_completion.resolved = *resolved;
12048            }
12049            CompletionSource::Custom => {
12050                serialized_completion.source = proto::completion::Source::Custom as i32;
12051                serialized_completion.resolved = true;
12052            }
12053            CompletionSource::Dap { sort_text } => {
12054                serialized_completion.source = proto::completion::Source::Dap as i32;
12055                serialized_completion.sort_text = Some(sort_text.clone());
12056            }
12057        }
12058
12059        serialized_completion
12060    }
12061
12062    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
12063        let old_replace_start = completion
12064            .old_replace_start
12065            .and_then(deserialize_anchor)
12066            .context("invalid old start")?;
12067        let old_replace_end = completion
12068            .old_replace_end
12069            .and_then(deserialize_anchor)
12070            .context("invalid old end")?;
12071        let insert_range = {
12072            match completion.old_insert_start.zip(completion.old_insert_end) {
12073                Some((start, end)) => {
12074                    let start = deserialize_anchor(start).context("invalid insert old start")?;
12075                    let end = deserialize_anchor(end).context("invalid insert old end")?;
12076                    Some(start..end)
12077                }
12078                None => None,
12079            }
12080        };
12081        Ok(CoreCompletion {
12082            replace_range: old_replace_start..old_replace_end,
12083            new_text: completion.new_text,
12084            source: match proto::completion::Source::from_i32(completion.source) {
12085                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
12086                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
12087                    insert_range,
12088                    server_id: LanguageServerId::from_proto(completion.server_id),
12089                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
12090                    lsp_defaults: completion
12091                        .lsp_defaults
12092                        .as_deref()
12093                        .map(serde_json::from_slice)
12094                        .transpose()?,
12095                    resolved: completion.resolved,
12096                },
12097                Some(proto::completion::Source::BufferWord) => {
12098                    let word_range = completion
12099                        .buffer_word_start
12100                        .and_then(deserialize_anchor)
12101                        .context("invalid buffer word start")?
12102                        ..completion
12103                            .buffer_word_end
12104                            .and_then(deserialize_anchor)
12105                            .context("invalid buffer word end")?;
12106                    CompletionSource::BufferWord {
12107                        word_range,
12108                        resolved: completion.resolved,
12109                    }
12110                }
12111                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12112                    sort_text: completion
12113                        .sort_text
12114                        .context("expected sort text to exist")?,
12115                },
12116                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12117            },
12118        })
12119    }
12120
12121    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12122        let (kind, lsp_action) = match &action.lsp_action {
12123            LspAction::Action(code_action) => (
12124                proto::code_action::Kind::Action as i32,
12125                serde_json::to_vec(code_action).unwrap(),
12126            ),
12127            LspAction::Command(command) => (
12128                proto::code_action::Kind::Command as i32,
12129                serde_json::to_vec(command).unwrap(),
12130            ),
12131            LspAction::CodeLens(code_lens) => (
12132                proto::code_action::Kind::CodeLens as i32,
12133                serde_json::to_vec(code_lens).unwrap(),
12134            ),
12135        };
12136
12137        proto::CodeAction {
12138            server_id: action.server_id.0 as u64,
12139            start: Some(serialize_anchor(&action.range.start)),
12140            end: Some(serialize_anchor(&action.range.end)),
12141            lsp_action,
12142            kind,
12143            resolved: action.resolved,
12144        }
12145    }
12146
12147    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12148        let start = action
12149            .start
12150            .and_then(deserialize_anchor)
12151            .context("invalid start")?;
12152        let end = action
12153            .end
12154            .and_then(deserialize_anchor)
12155            .context("invalid end")?;
12156        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12157            Some(proto::code_action::Kind::Action) => {
12158                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12159            }
12160            Some(proto::code_action::Kind::Command) => {
12161                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12162            }
12163            Some(proto::code_action::Kind::CodeLens) => {
12164                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12165            }
12166            None => anyhow::bail!("Unknown action kind {}", action.kind),
12167        };
12168        Ok(CodeAction {
12169            server_id: LanguageServerId(action.server_id as usize),
12170            range: start..end,
12171            resolved: action.resolved,
12172            lsp_action,
12173        })
12174    }
12175
12176    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12177        match &formatting_result {
12178            Ok(_) => self.last_formatting_failure = None,
12179            Err(error) => {
12180                let error_string = format!("{error:#}");
12181                log::error!("Formatting failed: {error_string}");
12182                self.last_formatting_failure
12183                    .replace(error_string.lines().join(" "));
12184            }
12185        }
12186    }
12187
12188    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12189        self.lsp_server_capabilities.remove(&for_server);
12190        self.semantic_token_config.remove_server_data(for_server);
12191        for lsp_data in self.lsp_data.values_mut() {
12192            lsp_data.remove_server_data(for_server);
12193        }
12194        if let Some(local) = self.as_local_mut() {
12195            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12196            local
12197                .workspace_pull_diagnostics_result_ids
12198                .remove(&for_server);
12199            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12200                buffer_servers.remove(&for_server);
12201            }
12202        }
12203    }
12204
12205    pub fn result_id_for_buffer_pull(
12206        &self,
12207        server_id: LanguageServerId,
12208        buffer_id: BufferId,
12209        registration_id: &Option<SharedString>,
12210        cx: &App,
12211    ) -> Option<SharedString> {
12212        let abs_path = self
12213            .buffer_store
12214            .read(cx)
12215            .get(buffer_id)
12216            .and_then(|b| File::from_dyn(b.read(cx).file()))
12217            .map(|f| f.abs_path(cx))?;
12218        self.as_local()?
12219            .buffer_pull_diagnostics_result_ids
12220            .get(&server_id)?
12221            .get(registration_id)?
12222            .get(&abs_path)?
12223            .clone()
12224    }
12225
12226    /// Gets all result_ids for a workspace diagnostics pull request.
12227    /// 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.
12228    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12229    pub fn result_ids_for_workspace_refresh(
12230        &self,
12231        server_id: LanguageServerId,
12232        registration_id: &Option<SharedString>,
12233    ) -> HashMap<PathBuf, SharedString> {
12234        let Some(local) = self.as_local() else {
12235            return HashMap::default();
12236        };
12237        local
12238            .workspace_pull_diagnostics_result_ids
12239            .get(&server_id)
12240            .into_iter()
12241            .filter_map(|diagnostics| diagnostics.get(registration_id))
12242            .flatten()
12243            .filter_map(|(abs_path, result_id)| {
12244                let result_id = local
12245                    .buffer_pull_diagnostics_result_ids
12246                    .get(&server_id)
12247                    .and_then(|buffer_ids_result_ids| {
12248                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12249                    })
12250                    .cloned()
12251                    .flatten()
12252                    .or_else(|| result_id.clone())?;
12253                Some((abs_path.clone(), result_id))
12254            })
12255            .collect()
12256    }
12257
12258    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12259        if let Some(LanguageServerState::Running {
12260            workspace_diagnostics_refresh_tasks,
12261            ..
12262        }) = self
12263            .as_local_mut()
12264            .and_then(|local| local.language_servers.get_mut(&server_id))
12265        {
12266            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12267                diagnostics.refresh_tx.try_send(()).ok();
12268            }
12269        }
12270    }
12271
12272    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12273    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12274    /// which requires refreshing both workspace and document diagnostics.
12275    pub fn pull_document_diagnostics_for_server(
12276        &mut self,
12277        server_id: LanguageServerId,
12278        source_buffer_id: Option<BufferId>,
12279        cx: &mut Context<Self>,
12280    ) -> Shared<Task<()>> {
12281        let Some(local) = self.as_local_mut() else {
12282            return Task::ready(()).shared();
12283        };
12284        let mut buffers_to_refresh = HashSet::default();
12285        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12286            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12287                buffers_to_refresh.insert(*buffer_id);
12288            }
12289        }
12290
12291        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12292    }
12293
12294    pub fn pull_document_diagnostics_for_buffer_edit(
12295        &mut self,
12296        buffer_id: BufferId,
12297        cx: &mut Context<Self>,
12298    ) {
12299        let Some(local) = self.as_local_mut() else {
12300            return;
12301        };
12302        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12303        else {
12304            return;
12305        };
12306        for server_id in languages_servers {
12307            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12308        }
12309    }
12310
12311    fn apply_workspace_diagnostic_report(
12312        &mut self,
12313        server_id: LanguageServerId,
12314        report: lsp::WorkspaceDiagnosticReportResult,
12315        registration_id: Option<SharedString>,
12316        cx: &mut Context<Self>,
12317    ) {
12318        let mut workspace_diagnostics =
12319            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12320                report,
12321                server_id,
12322                registration_id,
12323            );
12324        workspace_diagnostics.retain(|d| match &d.diagnostics {
12325            LspPullDiagnostics::Response {
12326                server_id,
12327                registration_id,
12328                ..
12329            } => self.diagnostic_registration_exists(*server_id, registration_id),
12330            LspPullDiagnostics::Default => false,
12331        });
12332        let mut unchanged_buffers = HashMap::default();
12333        let workspace_diagnostics_updates = workspace_diagnostics
12334            .into_iter()
12335            .filter_map(
12336                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12337                    LspPullDiagnostics::Response {
12338                        server_id,
12339                        uri,
12340                        diagnostics,
12341                        registration_id,
12342                    } => Some((
12343                        server_id,
12344                        uri,
12345                        diagnostics,
12346                        workspace_diagnostics.version,
12347                        registration_id,
12348                    )),
12349                    LspPullDiagnostics::Default => None,
12350                },
12351            )
12352            .fold(
12353                HashMap::default(),
12354                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12355                    let (result_id, diagnostics) = match diagnostics {
12356                        PulledDiagnostics::Unchanged { result_id } => {
12357                            unchanged_buffers
12358                                .entry(new_registration_id.clone())
12359                                .or_insert_with(HashSet::default)
12360                                .insert(uri.clone());
12361                            (Some(result_id), Vec::new())
12362                        }
12363                        PulledDiagnostics::Changed {
12364                            result_id,
12365                            diagnostics,
12366                        } => (result_id, diagnostics),
12367                    };
12368                    let disk_based_sources = Cow::Owned(
12369                        self.language_server_adapter_for_id(server_id)
12370                            .as_ref()
12371                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12372                            .unwrap_or(&[])
12373                            .to_vec(),
12374                    );
12375
12376                    let Some(abs_path) = uri.to_file_path().ok() else {
12377                        return acc;
12378                    };
12379                    let Some((worktree, relative_path)) =
12380                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12381                    else {
12382                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12383                        return acc;
12384                    };
12385                    let worktree_id = worktree.read(cx).id();
12386                    let project_path = ProjectPath {
12387                        worktree_id,
12388                        path: relative_path,
12389                    };
12390                    if let Some(local_lsp_store) = self.as_local_mut() {
12391                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12392                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12393                    }
12394                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12395                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12396                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12397                        acc.entry(server_id)
12398                            .or_insert_with(HashMap::default)
12399                            .entry(new_registration_id.clone())
12400                            .or_insert_with(Vec::new)
12401                            .push(DocumentDiagnosticsUpdate {
12402                                server_id,
12403                                diagnostics: lsp::PublishDiagnosticsParams {
12404                                    uri,
12405                                    diagnostics,
12406                                    version,
12407                                },
12408                                result_id: result_id.map(SharedString::new),
12409                                disk_based_sources,
12410                                registration_id: new_registration_id,
12411                            });
12412                    }
12413                    acc
12414                },
12415            );
12416
12417        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12418            for (registration_id, diagnostic_updates) in diagnostic_updates {
12419                self.merge_lsp_diagnostics(
12420                    DiagnosticSourceKind::Pulled,
12421                    diagnostic_updates,
12422                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12423                        DiagnosticSourceKind::Pulled => {
12424                            old_diagnostic.registration_id != registration_id
12425                                || unchanged_buffers
12426                                    .get(&old_diagnostic.registration_id)
12427                                    .is_some_and(|unchanged_buffers| {
12428                                        unchanged_buffers.contains(&document_uri)
12429                                    })
12430                        }
12431                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12432                    },
12433                    cx,
12434                )
12435                .log_err();
12436            }
12437        }
12438    }
12439
12440    fn register_server_capabilities(
12441        &mut self,
12442        server_id: LanguageServerId,
12443        params: lsp::RegistrationParams,
12444        cx: &mut Context<Self>,
12445    ) -> anyhow::Result<()> {
12446        let server = self
12447            .language_server_for_id(server_id)
12448            .with_context(|| format!("no server {server_id} found"))?;
12449        for reg in params.registrations {
12450            match reg.method.as_str() {
12451                "workspace/didChangeWatchedFiles" => {
12452                    if let Some(options) = reg.register_options {
12453                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12454                            let caps = serde_json::from_value(options)?;
12455                            local_lsp_store
12456                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12457                            true
12458                        } else {
12459                            false
12460                        };
12461                        if notify {
12462                            notify_server_capabilities_updated(&server, cx);
12463                        }
12464                    }
12465                }
12466                "workspace/didChangeConfiguration" => {
12467                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12468                }
12469                "workspace/didChangeWorkspaceFolders" => {
12470                    // In this case register options is an empty object, we can ignore it
12471                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12472                        supported: Some(true),
12473                        change_notifications: Some(OneOf::Right(reg.id)),
12474                    };
12475                    server.update_capabilities(|capabilities| {
12476                        capabilities
12477                            .workspace
12478                            .get_or_insert_default()
12479                            .workspace_folders = Some(caps);
12480                    });
12481                    notify_server_capabilities_updated(&server, cx);
12482                }
12483                "workspace/symbol" => {
12484                    let options = parse_register_capabilities(reg)?;
12485                    server.update_capabilities(|capabilities| {
12486                        capabilities.workspace_symbol_provider = Some(options);
12487                    });
12488                    notify_server_capabilities_updated(&server, cx);
12489                }
12490                "workspace/fileOperations" => {
12491                    if let Some(options) = reg.register_options {
12492                        let caps = serde_json::from_value(options)?;
12493                        server.update_capabilities(|capabilities| {
12494                            capabilities
12495                                .workspace
12496                                .get_or_insert_default()
12497                                .file_operations = Some(caps);
12498                        });
12499                        notify_server_capabilities_updated(&server, cx);
12500                    }
12501                }
12502                "workspace/executeCommand" => {
12503                    if let Some(options) = reg.register_options {
12504                        let options = serde_json::from_value(options)?;
12505                        server.update_capabilities(|capabilities| {
12506                            capabilities.execute_command_provider = Some(options);
12507                        });
12508                        notify_server_capabilities_updated(&server, cx);
12509                    }
12510                }
12511                "textDocument/rangeFormatting" => {
12512                    let options = parse_register_capabilities(reg)?;
12513                    server.update_capabilities(|capabilities| {
12514                        capabilities.document_range_formatting_provider = Some(options);
12515                    });
12516                    notify_server_capabilities_updated(&server, cx);
12517                }
12518                "textDocument/onTypeFormatting" => {
12519                    if let Some(options) = reg
12520                        .register_options
12521                        .map(serde_json::from_value)
12522                        .transpose()?
12523                    {
12524                        server.update_capabilities(|capabilities| {
12525                            capabilities.document_on_type_formatting_provider = Some(options);
12526                        });
12527                        notify_server_capabilities_updated(&server, cx);
12528                    }
12529                }
12530                "textDocument/formatting" => {
12531                    let options = parse_register_capabilities(reg)?;
12532                    server.update_capabilities(|capabilities| {
12533                        capabilities.document_formatting_provider = Some(options);
12534                    });
12535                    notify_server_capabilities_updated(&server, cx);
12536                }
12537                "textDocument/rename" => {
12538                    let options = parse_register_capabilities(reg)?;
12539                    server.update_capabilities(|capabilities| {
12540                        capabilities.rename_provider = Some(options);
12541                    });
12542                    notify_server_capabilities_updated(&server, cx);
12543                }
12544                "textDocument/inlayHint" => {
12545                    let options = parse_register_capabilities(reg)?;
12546                    server.update_capabilities(|capabilities| {
12547                        capabilities.inlay_hint_provider = Some(options);
12548                    });
12549                    notify_server_capabilities_updated(&server, cx);
12550                }
12551                "textDocument/documentSymbol" => {
12552                    let options = parse_register_capabilities(reg)?;
12553                    server.update_capabilities(|capabilities| {
12554                        capabilities.document_symbol_provider = Some(options);
12555                    });
12556                    notify_server_capabilities_updated(&server, cx);
12557                }
12558                "textDocument/codeAction" => {
12559                    let options = parse_register_capabilities(reg)?;
12560                    let provider = match options {
12561                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12562                        OneOf::Right(caps) => caps,
12563                    };
12564                    server.update_capabilities(|capabilities| {
12565                        capabilities.code_action_provider = Some(provider);
12566                    });
12567                    notify_server_capabilities_updated(&server, cx);
12568                }
12569                "textDocument/definition" => {
12570                    let options = parse_register_capabilities(reg)?;
12571                    server.update_capabilities(|capabilities| {
12572                        capabilities.definition_provider = Some(options);
12573                    });
12574                    notify_server_capabilities_updated(&server, cx);
12575                }
12576                "textDocument/completion" => {
12577                    if let Some(caps) = reg
12578                        .register_options
12579                        .map(serde_json::from_value::<CompletionOptions>)
12580                        .transpose()?
12581                    {
12582                        server.update_capabilities(|capabilities| {
12583                            capabilities.completion_provider = Some(caps.clone());
12584                        });
12585
12586                        if let Some(local) = self.as_local() {
12587                            let mut buffers_with_language_server = Vec::new();
12588                            for handle in self.buffer_store.read(cx).buffers() {
12589                                let buffer_id = handle.read(cx).remote_id();
12590                                if local
12591                                    .buffers_opened_in_servers
12592                                    .get(&buffer_id)
12593                                    .filter(|s| s.contains(&server_id))
12594                                    .is_some()
12595                                {
12596                                    buffers_with_language_server.push(handle);
12597                                }
12598                            }
12599                            let triggers = caps
12600                                .trigger_characters
12601                                .unwrap_or_default()
12602                                .into_iter()
12603                                .collect::<BTreeSet<_>>();
12604                            for handle in buffers_with_language_server {
12605                                let triggers = triggers.clone();
12606                                let _ = handle.update(cx, move |buffer, cx| {
12607                                    buffer.set_completion_triggers(server_id, triggers, cx);
12608                                });
12609                            }
12610                        }
12611                        notify_server_capabilities_updated(&server, cx);
12612                    }
12613                }
12614                "textDocument/hover" => {
12615                    let options = parse_register_capabilities(reg)?;
12616                    let provider = match options {
12617                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12618                        OneOf::Right(caps) => caps,
12619                    };
12620                    server.update_capabilities(|capabilities| {
12621                        capabilities.hover_provider = Some(provider);
12622                    });
12623                    notify_server_capabilities_updated(&server, cx);
12624                }
12625                "textDocument/signatureHelp" => {
12626                    if let Some(caps) = reg
12627                        .register_options
12628                        .map(serde_json::from_value)
12629                        .transpose()?
12630                    {
12631                        server.update_capabilities(|capabilities| {
12632                            capabilities.signature_help_provider = Some(caps);
12633                        });
12634                        notify_server_capabilities_updated(&server, cx);
12635                    }
12636                }
12637                "textDocument/didChange" => {
12638                    if let Some(sync_kind) = reg
12639                        .register_options
12640                        .and_then(|opts| opts.get("syncKind").cloned())
12641                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12642                        .transpose()?
12643                    {
12644                        server.update_capabilities(|capabilities| {
12645                            let mut sync_options =
12646                                Self::take_text_document_sync_options(capabilities);
12647                            sync_options.change = Some(sync_kind);
12648                            capabilities.text_document_sync =
12649                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12650                        });
12651                        notify_server_capabilities_updated(&server, cx);
12652                    }
12653                }
12654                "textDocument/didSave" => {
12655                    if let Some(include_text) = reg
12656                        .register_options
12657                        .map(|opts| {
12658                            let transpose = opts
12659                                .get("includeText")
12660                                .cloned()
12661                                .map(serde_json::from_value::<Option<bool>>)
12662                                .transpose();
12663                            match transpose {
12664                                Ok(value) => Ok(value.flatten()),
12665                                Err(e) => Err(e),
12666                            }
12667                        })
12668                        .transpose()?
12669                    {
12670                        server.update_capabilities(|capabilities| {
12671                            let mut sync_options =
12672                                Self::take_text_document_sync_options(capabilities);
12673                            sync_options.save =
12674                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12675                                    include_text,
12676                                }));
12677                            capabilities.text_document_sync =
12678                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12679                        });
12680                        notify_server_capabilities_updated(&server, cx);
12681                    }
12682                }
12683                "textDocument/codeLens" => {
12684                    if let Some(caps) = reg
12685                        .register_options
12686                        .map(serde_json::from_value)
12687                        .transpose()?
12688                    {
12689                        server.update_capabilities(|capabilities| {
12690                            capabilities.code_lens_provider = Some(caps);
12691                        });
12692                        notify_server_capabilities_updated(&server, cx);
12693                    }
12694                }
12695                "textDocument/diagnostic" => {
12696                    if let Some(caps) = reg
12697                        .register_options
12698                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12699                        .transpose()?
12700                    {
12701                        let local = self
12702                            .as_local_mut()
12703                            .context("Expected LSP Store to be local")?;
12704                        let state = local
12705                            .language_servers
12706                            .get_mut(&server_id)
12707                            .context("Could not obtain Language Servers state")?;
12708                        local
12709                            .language_server_dynamic_registrations
12710                            .entry(server_id)
12711                            .or_default()
12712                            .diagnostics
12713                            .insert(Some(reg.id.clone()), caps.clone());
12714
12715                        let supports_workspace_diagnostics =
12716                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12717                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12718                                    diagnostic_options.workspace_diagnostics
12719                                }
12720                                DiagnosticServerCapabilities::RegistrationOptions(
12721                                    diagnostic_registration_options,
12722                                ) => {
12723                                    diagnostic_registration_options
12724                                        .diagnostic_options
12725                                        .workspace_diagnostics
12726                                }
12727                            };
12728
12729                        if supports_workspace_diagnostics(&caps) {
12730                            if let LanguageServerState::Running {
12731                                workspace_diagnostics_refresh_tasks,
12732                                ..
12733                            } = state
12734                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12735                                    Some(reg.id.clone()),
12736                                    caps.clone(),
12737                                    server.clone(),
12738                                    cx,
12739                                )
12740                            {
12741                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12742                            }
12743                        }
12744
12745                        server.update_capabilities(|capabilities| {
12746                            capabilities.diagnostic_provider = Some(caps);
12747                        });
12748
12749                        notify_server_capabilities_updated(&server, cx);
12750
12751                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12752                    }
12753                }
12754                "textDocument/documentColor" => {
12755                    let options = parse_register_capabilities(reg)?;
12756                    let provider = match options {
12757                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12758                        OneOf::Right(caps) => caps,
12759                    };
12760                    server.update_capabilities(|capabilities| {
12761                        capabilities.color_provider = Some(provider);
12762                    });
12763                    notify_server_capabilities_updated(&server, cx);
12764                }
12765                "textDocument/foldingRange" => {
12766                    let options = parse_register_capabilities(reg)?;
12767                    let provider = match options {
12768                        OneOf::Left(value) => lsp::FoldingRangeProviderCapability::Simple(value),
12769                        OneOf::Right(caps) => caps,
12770                    };
12771                    server.update_capabilities(|capabilities| {
12772                        capabilities.folding_range_provider = Some(provider);
12773                    });
12774                    notify_server_capabilities_updated(&server, cx);
12775                }
12776                _ => log::warn!("unhandled capability registration: {reg:?}"),
12777            }
12778        }
12779
12780        Ok(())
12781    }
12782
12783    fn unregister_server_capabilities(
12784        &mut self,
12785        server_id: LanguageServerId,
12786        params: lsp::UnregistrationParams,
12787        cx: &mut Context<Self>,
12788    ) -> anyhow::Result<()> {
12789        let server = self
12790            .language_server_for_id(server_id)
12791            .with_context(|| format!("no server {server_id} found"))?;
12792        for unreg in params.unregisterations.iter() {
12793            match unreg.method.as_str() {
12794                "workspace/didChangeWatchedFiles" => {
12795                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12796                        local_lsp_store
12797                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12798                        true
12799                    } else {
12800                        false
12801                    };
12802                    if notify {
12803                        notify_server_capabilities_updated(&server, cx);
12804                    }
12805                }
12806                "workspace/didChangeConfiguration" => {
12807                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12808                }
12809                "workspace/didChangeWorkspaceFolders" => {
12810                    server.update_capabilities(|capabilities| {
12811                        capabilities
12812                            .workspace
12813                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12814                                workspace_folders: None,
12815                                file_operations: None,
12816                            })
12817                            .workspace_folders = None;
12818                    });
12819                    notify_server_capabilities_updated(&server, cx);
12820                }
12821                "workspace/symbol" => {
12822                    server.update_capabilities(|capabilities| {
12823                        capabilities.workspace_symbol_provider = None
12824                    });
12825                    notify_server_capabilities_updated(&server, cx);
12826                }
12827                "workspace/fileOperations" => {
12828                    server.update_capabilities(|capabilities| {
12829                        capabilities
12830                            .workspace
12831                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12832                                workspace_folders: None,
12833                                file_operations: None,
12834                            })
12835                            .file_operations = None;
12836                    });
12837                    notify_server_capabilities_updated(&server, cx);
12838                }
12839                "workspace/executeCommand" => {
12840                    server.update_capabilities(|capabilities| {
12841                        capabilities.execute_command_provider = None;
12842                    });
12843                    notify_server_capabilities_updated(&server, cx);
12844                }
12845                "textDocument/rangeFormatting" => {
12846                    server.update_capabilities(|capabilities| {
12847                        capabilities.document_range_formatting_provider = None
12848                    });
12849                    notify_server_capabilities_updated(&server, cx);
12850                }
12851                "textDocument/onTypeFormatting" => {
12852                    server.update_capabilities(|capabilities| {
12853                        capabilities.document_on_type_formatting_provider = None;
12854                    });
12855                    notify_server_capabilities_updated(&server, cx);
12856                }
12857                "textDocument/formatting" => {
12858                    server.update_capabilities(|capabilities| {
12859                        capabilities.document_formatting_provider = None;
12860                    });
12861                    notify_server_capabilities_updated(&server, cx);
12862                }
12863                "textDocument/rename" => {
12864                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12865                    notify_server_capabilities_updated(&server, cx);
12866                }
12867                "textDocument/codeAction" => {
12868                    server.update_capabilities(|capabilities| {
12869                        capabilities.code_action_provider = None;
12870                    });
12871                    notify_server_capabilities_updated(&server, cx);
12872                }
12873                "textDocument/definition" => {
12874                    server.update_capabilities(|capabilities| {
12875                        capabilities.definition_provider = None;
12876                    });
12877                    notify_server_capabilities_updated(&server, cx);
12878                }
12879                "textDocument/completion" => {
12880                    server.update_capabilities(|capabilities| {
12881                        capabilities.completion_provider = None;
12882                    });
12883                    notify_server_capabilities_updated(&server, cx);
12884                }
12885                "textDocument/hover" => {
12886                    server.update_capabilities(|capabilities| {
12887                        capabilities.hover_provider = None;
12888                    });
12889                    notify_server_capabilities_updated(&server, cx);
12890                }
12891                "textDocument/signatureHelp" => {
12892                    server.update_capabilities(|capabilities| {
12893                        capabilities.signature_help_provider = None;
12894                    });
12895                    notify_server_capabilities_updated(&server, cx);
12896                }
12897                "textDocument/didChange" => {
12898                    server.update_capabilities(|capabilities| {
12899                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12900                        sync_options.change = None;
12901                        capabilities.text_document_sync =
12902                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12903                    });
12904                    notify_server_capabilities_updated(&server, cx);
12905                }
12906                "textDocument/didSave" => {
12907                    server.update_capabilities(|capabilities| {
12908                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12909                        sync_options.save = None;
12910                        capabilities.text_document_sync =
12911                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12912                    });
12913                    notify_server_capabilities_updated(&server, cx);
12914                }
12915                "textDocument/codeLens" => {
12916                    server.update_capabilities(|capabilities| {
12917                        capabilities.code_lens_provider = None;
12918                    });
12919                    notify_server_capabilities_updated(&server, cx);
12920                }
12921                "textDocument/diagnostic" => {
12922                    let local = self
12923                        .as_local_mut()
12924                        .context("Expected LSP Store to be local")?;
12925
12926                    let state = local
12927                        .language_servers
12928                        .get_mut(&server_id)
12929                        .context("Could not obtain Language Servers state")?;
12930                    let registrations = local
12931                        .language_server_dynamic_registrations
12932                        .get_mut(&server_id)
12933                        .with_context(|| {
12934                            format!("Expected dynamic registration to exist for server {server_id}")
12935                        })?;
12936                    registrations.diagnostics
12937                        .remove(&Some(unreg.id.clone()))
12938                        .with_context(|| format!(
12939                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12940                            unreg.id)
12941                        )?;
12942                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12943
12944                    if let LanguageServerState::Running {
12945                        workspace_diagnostics_refresh_tasks,
12946                        ..
12947                    } = state
12948                    {
12949                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12950                    }
12951
12952                    self.clear_unregistered_diagnostics(
12953                        server_id,
12954                        SharedString::from(unreg.id.clone()),
12955                        cx,
12956                    )?;
12957
12958                    if removed_last_diagnostic_provider {
12959                        server.update_capabilities(|capabilities| {
12960                            debug_assert!(capabilities.diagnostic_provider.is_some());
12961                            capabilities.diagnostic_provider = None;
12962                        });
12963                    }
12964
12965                    notify_server_capabilities_updated(&server, cx);
12966                }
12967                "textDocument/documentColor" => {
12968                    server.update_capabilities(|capabilities| {
12969                        capabilities.color_provider = None;
12970                    });
12971                    notify_server_capabilities_updated(&server, cx);
12972                }
12973                "textDocument/foldingRange" => {
12974                    server.update_capabilities(|capabilities| {
12975                        capabilities.folding_range_provider = None;
12976                    });
12977                    notify_server_capabilities_updated(&server, cx);
12978                }
12979                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12980            }
12981        }
12982
12983        Ok(())
12984    }
12985
12986    fn clear_unregistered_diagnostics(
12987        &mut self,
12988        server_id: LanguageServerId,
12989        cleared_registration_id: SharedString,
12990        cx: &mut Context<Self>,
12991    ) -> anyhow::Result<()> {
12992        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12993
12994        self.buffer_store.update(cx, |buffer_store, cx| {
12995            for buffer_handle in buffer_store.buffers() {
12996                let buffer = buffer_handle.read(cx);
12997                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12998                let Some(abs_path) = abs_path else {
12999                    continue;
13000                };
13001                affected_abs_paths.insert(abs_path);
13002            }
13003        });
13004
13005        let local = self.as_local().context("Expected LSP Store to be local")?;
13006        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
13007            let Some(worktree) = self
13008                .worktree_store
13009                .read(cx)
13010                .worktree_for_id(*worktree_id, cx)
13011            else {
13012                continue;
13013            };
13014
13015            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
13016                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
13017                    let has_matching_registration =
13018                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
13019                            entry.diagnostic.registration_id.as_ref()
13020                                == Some(&cleared_registration_id)
13021                        });
13022                    if has_matching_registration {
13023                        let abs_path = worktree.read(cx).absolutize(rel_path);
13024                        affected_abs_paths.insert(abs_path);
13025                    }
13026                }
13027            }
13028        }
13029
13030        if affected_abs_paths.is_empty() {
13031            return Ok(());
13032        }
13033
13034        // Send a fake diagnostic update which clears the state for the registration ID
13035        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
13036            affected_abs_paths
13037                .into_iter()
13038                .map(|abs_path| DocumentDiagnosticsUpdate {
13039                    diagnostics: DocumentDiagnostics {
13040                        diagnostics: Vec::new(),
13041                        document_abs_path: abs_path,
13042                        version: None,
13043                    },
13044                    result_id: None,
13045                    registration_id: Some(cleared_registration_id.clone()),
13046                    server_id,
13047                    disk_based_sources: Cow::Borrowed(&[]),
13048                })
13049                .collect();
13050
13051        let merge_registration_id = cleared_registration_id.clone();
13052        self.merge_diagnostic_entries(
13053            clears,
13054            move |_, diagnostic, _| {
13055                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
13056                    diagnostic.registration_id != Some(merge_registration_id.clone())
13057                } else {
13058                    true
13059                }
13060            },
13061            cx,
13062        )?;
13063
13064        Ok(())
13065    }
13066
13067    async fn deduplicate_range_based_lsp_requests<T>(
13068        lsp_store: &Entity<Self>,
13069        server_id: Option<LanguageServerId>,
13070        lsp_request_id: LspRequestId,
13071        proto_request: &T::ProtoRequest,
13072        range: Range<Anchor>,
13073        cx: &mut AsyncApp,
13074    ) -> Result<()>
13075    where
13076        T: LspCommand,
13077        T::ProtoRequest: proto::LspRequestMessage,
13078    {
13079        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13080        let version = deserialize_version(proto_request.buffer_version());
13081        let buffer = lsp_store.update(cx, |this, cx| {
13082            this.buffer_store.read(cx).get_existing(buffer_id)
13083        })?;
13084        buffer
13085            .update(cx, |buffer, _| buffer.wait_for_version(version))
13086            .await?;
13087        lsp_store.update(cx, |lsp_store, cx| {
13088            let buffer_snapshot = buffer.read(cx).snapshot();
13089            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13090            let chunks_queried_for = lsp_data
13091                .inlay_hints
13092                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
13093                .collect::<Vec<_>>();
13094            match chunks_queried_for.as_slice() {
13095                &[chunk] => {
13096                    let key = LspKey {
13097                        request_type: TypeId::of::<T>(),
13098                        server_queried: server_id,
13099                    };
13100                    let previous_request = lsp_data
13101                        .chunk_lsp_requests
13102                        .entry(key)
13103                        .or_default()
13104                        .insert(chunk, lsp_request_id);
13105                    if let Some((previous_request, running_requests)) =
13106                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13107                    {
13108                        running_requests.remove(&previous_request);
13109                    }
13110                }
13111                _ambiguous_chunks => {
13112                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13113                    // there, a buffer version-based check will be performed and outdated requests discarded.
13114                }
13115            }
13116            anyhow::Ok(())
13117        })?;
13118
13119        Ok(())
13120    }
13121
13122    async fn query_lsp_locally<T>(
13123        lsp_store: Entity<Self>,
13124        for_server_id: Option<LanguageServerId>,
13125        sender_id: proto::PeerId,
13126        lsp_request_id: LspRequestId,
13127        proto_request: T::ProtoRequest,
13128        position: Option<Anchor>,
13129        cx: &mut AsyncApp,
13130    ) -> Result<()>
13131    where
13132        T: LspCommand + Clone,
13133        T::ProtoRequest: proto::LspRequestMessage,
13134        <T::ProtoRequest as proto::RequestMessage>::Response:
13135            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13136    {
13137        let (buffer_version, buffer) =
13138            Self::wait_for_buffer_version::<T>(&lsp_store, &proto_request, cx).await?;
13139        let request =
13140            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13141        let key = LspKey {
13142            request_type: TypeId::of::<T>(),
13143            server_queried: for_server_id,
13144        };
13145        lsp_store.update(cx, |lsp_store, cx| {
13146            let request_task = match for_server_id {
13147                Some(server_id) => {
13148                    let server_task = lsp_store.request_lsp(
13149                        buffer.clone(),
13150                        LanguageServerToQuery::Other(server_id),
13151                        request.clone(),
13152                        cx,
13153                    );
13154                    cx.background_spawn(async move {
13155                        let mut responses = Vec::new();
13156                        match server_task.await {
13157                            Ok(response) => responses.push((server_id, response)),
13158                            // rust-analyzer likes to error with this when its still loading up
13159                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13160                            Err(e) => log::error!(
13161                                "Error handling response for request {request:?}: {e:#}"
13162                            ),
13163                        }
13164                        responses
13165                    })
13166                }
13167                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13168            };
13169            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13170            if T::ProtoRequest::stop_previous_requests() {
13171                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13172                    lsp_requests.clear();
13173                }
13174            }
13175            lsp_data.lsp_requests.entry(key).or_default().insert(
13176                lsp_request_id,
13177                cx.spawn(async move |lsp_store, cx| {
13178                    let response = request_task.await;
13179                    lsp_store
13180                        .update(cx, |lsp_store, cx| {
13181                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13182                            {
13183                                let response = response
13184                                    .into_iter()
13185                                    .map(|(server_id, response)| {
13186                                        (
13187                                            server_id.to_proto(),
13188                                            T::response_to_proto(
13189                                                response,
13190                                                lsp_store,
13191                                                sender_id,
13192                                                &buffer_version,
13193                                                cx,
13194                                            )
13195                                            .into(),
13196                                        )
13197                                    })
13198                                    .collect::<HashMap<_, _>>();
13199                                match client.send_lsp_response::<T::ProtoRequest>(
13200                                    project_id,
13201                                    lsp_request_id,
13202                                    response,
13203                                ) {
13204                                    Ok(()) => {}
13205                                    Err(e) => {
13206                                        log::error!("Failed to send LSP response: {e:#}",)
13207                                    }
13208                                }
13209                            }
13210                        })
13211                        .ok();
13212                }),
13213            );
13214        });
13215        Ok(())
13216    }
13217
13218    async fn wait_for_buffer_version<T>(
13219        lsp_store: &Entity<Self>,
13220        proto_request: &T::ProtoRequest,
13221        cx: &mut AsyncApp,
13222    ) -> Result<(Global, Entity<Buffer>)>
13223    where
13224        T: LspCommand,
13225        T::ProtoRequest: proto::LspRequestMessage,
13226    {
13227        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13228        let version = deserialize_version(proto_request.buffer_version());
13229        let buffer = lsp_store.update(cx, |this, cx| {
13230            this.buffer_store.read(cx).get_existing(buffer_id)
13231        })?;
13232        buffer
13233            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13234            .await?;
13235        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13236        Ok((buffer_version, buffer))
13237    }
13238
13239    fn take_text_document_sync_options(
13240        capabilities: &mut lsp::ServerCapabilities,
13241    ) -> lsp::TextDocumentSyncOptions {
13242        match capabilities.text_document_sync.take() {
13243            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13244            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13245                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13246                sync_options.change = Some(sync_kind);
13247                sync_options
13248            }
13249            None => lsp::TextDocumentSyncOptions::default(),
13250        }
13251    }
13252
13253    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13254        self.downstream_client.clone()
13255    }
13256
13257    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13258        self.worktree_store.clone()
13259    }
13260
13261    /// Gets what's stored in the LSP data for the given buffer.
13262    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13263        self.lsp_data.get_mut(&buffer_id)
13264    }
13265
13266    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13267    /// new [`BufferLspData`] will be created to replace the previous state.
13268    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13269        let (buffer_id, buffer_version) =
13270            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13271        let lsp_data = self
13272            .lsp_data
13273            .entry(buffer_id)
13274            .or_insert_with(|| BufferLspData::new(buffer, cx));
13275        if buffer_version.changed_since(&lsp_data.buffer_version) {
13276            // To send delta requests for semantic tokens, the previous tokens
13277            // need to be kept between buffer changes.
13278            let semantic_tokens = lsp_data.semantic_tokens.take();
13279            *lsp_data = BufferLspData::new(buffer, cx);
13280            lsp_data.semantic_tokens = semantic_tokens;
13281        }
13282        lsp_data
13283    }
13284}
13285
13286// Registration with registerOptions as null, should fallback to true.
13287// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13288fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13289    reg: lsp::Registration,
13290) -> Result<OneOf<bool, T>> {
13291    Ok(match reg.register_options {
13292        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13293        None => OneOf::Left(true),
13294    })
13295}
13296
13297fn subscribe_to_binary_statuses(
13298    languages: &Arc<LanguageRegistry>,
13299    cx: &mut Context<'_, LspStore>,
13300) -> Task<()> {
13301    let mut server_statuses = languages.language_server_binary_statuses();
13302    cx.spawn(async move |lsp_store, cx| {
13303        while let Some((server_name, binary_status)) = server_statuses.next().await {
13304            if lsp_store
13305                .update(cx, |_, cx| {
13306                    let mut message = None;
13307                    let binary_status = match binary_status {
13308                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13309                        BinaryStatus::CheckingForUpdate => {
13310                            proto::ServerBinaryStatus::CheckingForUpdate
13311                        }
13312                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13313                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13314                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13315                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13316                        BinaryStatus::Failed { error } => {
13317                            message = Some(error);
13318                            proto::ServerBinaryStatus::Failed
13319                        }
13320                    };
13321                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13322                        // Binary updates are about the binary that might not have any language server id at that point.
13323                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13324                        language_server_id: LanguageServerId(0),
13325                        name: Some(server_name),
13326                        message: proto::update_language_server::Variant::StatusUpdate(
13327                            proto::StatusUpdate {
13328                                message,
13329                                status: Some(proto::status_update::Status::Binary(
13330                                    binary_status as i32,
13331                                )),
13332                            },
13333                        ),
13334                    });
13335                })
13336                .is_err()
13337            {
13338                break;
13339            }
13340        }
13341    })
13342}
13343
13344fn lsp_workspace_diagnostics_refresh(
13345    registration_id: Option<String>,
13346    options: DiagnosticServerCapabilities,
13347    server: Arc<LanguageServer>,
13348    cx: &mut Context<'_, LspStore>,
13349) -> Option<WorkspaceRefreshTask> {
13350    let identifier = workspace_diagnostic_identifier(&options)?;
13351    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13352
13353    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13354    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13355    refresh_tx.try_send(()).ok();
13356
13357    let request_timeout = ProjectSettings::get_global(cx)
13358        .global_lsp_settings
13359        .get_request_timeout();
13360
13361    // 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.
13362    // This allows users to increase the duration if need be
13363    let timeout = if request_timeout != Duration::ZERO {
13364        request_timeout.max(DEFAULT_LSP_REQUEST_TIMEOUT)
13365    } else {
13366        request_timeout
13367    };
13368
13369    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13370        let mut attempts = 0;
13371        let max_attempts = 50;
13372        let mut requests = 0;
13373
13374        loop {
13375            let Some(()) = refresh_rx.recv().await else {
13376                return;
13377            };
13378
13379            'request: loop {
13380                requests += 1;
13381                if attempts > max_attempts {
13382                    log::error!(
13383                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13384                    );
13385                    return;
13386                }
13387                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13388                cx.background_executor()
13389                    .timer(Duration::from_millis(backoff_millis))
13390                    .await;
13391                attempts += 1;
13392
13393                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13394                    lsp_store
13395                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13396                        .into_iter()
13397                        .filter_map(|(abs_path, result_id)| {
13398                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13399                            Some(lsp::PreviousResultId {
13400                                uri,
13401                                value: result_id.to_string(),
13402                            })
13403                        })
13404                        .collect()
13405                }) else {
13406                    return;
13407                };
13408
13409                let token = if let Some(registration_id) = &registration_id {
13410                    format!(
13411                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13412                        server.server_id(),
13413                    )
13414                } else {
13415                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13416                };
13417
13418                progress_rx.try_recv().ok();
13419                let timer = server.request_timer(timeout).fuse();
13420                let progress = pin!(progress_rx.recv().fuse());
13421                let response_result = server
13422                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13423                        lsp::WorkspaceDiagnosticParams {
13424                            previous_result_ids,
13425                            identifier: identifier.clone(),
13426                            work_done_progress_params: Default::default(),
13427                            partial_result_params: lsp::PartialResultParams {
13428                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13429                            },
13430                        },
13431                        select(timer, progress).then(|either| match either {
13432                            Either::Left((message, ..)) => ready(message).left_future(),
13433                            Either::Right(..) => pending::<String>().right_future(),
13434                        }),
13435                    )
13436                    .await;
13437
13438                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13439                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13440                match response_result {
13441                    ConnectionResult::Timeout => {
13442                        log::error!("Timeout during workspace diagnostics pull");
13443                        continue 'request;
13444                    }
13445                    ConnectionResult::ConnectionReset => {
13446                        log::error!("Server closed a workspace diagnostics pull request");
13447                        continue 'request;
13448                    }
13449                    ConnectionResult::Result(Err(e)) => {
13450                        log::error!("Error during workspace diagnostics pull: {e:#}");
13451                        break 'request;
13452                    }
13453                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13454                        attempts = 0;
13455                        if lsp_store
13456                            .update(cx, |lsp_store, cx| {
13457                                lsp_store.apply_workspace_diagnostic_report(
13458                                    server.server_id(),
13459                                    pulled_diagnostics,
13460                                    registration_id_shared.clone(),
13461                                    cx,
13462                                )
13463                            })
13464                            .is_err()
13465                        {
13466                            return;
13467                        }
13468                        break 'request;
13469                    }
13470                }
13471            }
13472        }
13473    });
13474
13475    Some(WorkspaceRefreshTask {
13476        refresh_tx,
13477        progress_tx,
13478        task: workspace_query_language_server,
13479    })
13480}
13481
13482fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<SharedString> {
13483    match &options {
13484        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => diagnostic_options
13485            .identifier
13486            .as_deref()
13487            .map(SharedString::new),
13488        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13489            let diagnostic_options = &registration_options.diagnostic_options;
13490            diagnostic_options
13491                .identifier
13492                .as_deref()
13493                .map(SharedString::new)
13494        }
13495    }
13496}
13497
13498fn workspace_diagnostic_identifier(
13499    options: &DiagnosticServerCapabilities,
13500) -> Option<Option<String>> {
13501    match &options {
13502        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13503            if !diagnostic_options.workspace_diagnostics {
13504                return None;
13505            }
13506            Some(diagnostic_options.identifier.clone())
13507        }
13508        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13509            let diagnostic_options = &registration_options.diagnostic_options;
13510            if !diagnostic_options.workspace_diagnostics {
13511                return None;
13512            }
13513            Some(diagnostic_options.identifier.clone())
13514        }
13515    }
13516}
13517
13518fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13519    let CompletionSource::BufferWord {
13520        word_range,
13521        resolved,
13522    } = &mut completion.source
13523    else {
13524        return;
13525    };
13526    if *resolved {
13527        return;
13528    }
13529
13530    if completion.new_text
13531        != snapshot
13532            .text_for_range(word_range.clone())
13533            .collect::<String>()
13534    {
13535        return;
13536    }
13537
13538    let mut offset = 0;
13539    for chunk in snapshot.chunks(
13540        word_range.clone(),
13541        LanguageAwareStyling {
13542            tree_sitter: true,
13543            diagnostics: true,
13544        },
13545    ) {
13546        let end_offset = offset + chunk.text.len();
13547        if let Some(highlight_id) = chunk.syntax_highlight_id {
13548            completion
13549                .label
13550                .runs
13551                .push((offset..end_offset, highlight_id));
13552        }
13553        offset = end_offset;
13554    }
13555    *resolved = true;
13556}
13557
13558impl EventEmitter<LspStoreEvent> for LspStore {}
13559
13560fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13561    hover
13562        .contents
13563        .retain(|hover_block| !hover_block.text.trim().is_empty());
13564    if hover.contents.is_empty() {
13565        None
13566    } else {
13567        Some(hover)
13568    }
13569}
13570
13571async fn populate_labels_for_completions(
13572    new_completions: Vec<CoreCompletion>,
13573    language: Option<Arc<Language>>,
13574    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13575) -> Vec<Completion> {
13576    let lsp_completions = new_completions
13577        .iter()
13578        .filter_map(|new_completion| {
13579            new_completion
13580                .source
13581                .lsp_completion(true)
13582                .map(|lsp_completion| lsp_completion.into_owned())
13583        })
13584        .collect::<Vec<_>>();
13585
13586    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13587        lsp_adapter
13588            .labels_for_completions(&lsp_completions, language)
13589            .await
13590            .log_err()
13591            .unwrap_or_default()
13592    } else {
13593        Vec::new()
13594    }
13595    .into_iter()
13596    .fuse();
13597
13598    let mut completions = Vec::new();
13599    for completion in new_completions {
13600        match completion.source.lsp_completion(true) {
13601            Some(lsp_completion) => {
13602                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13603
13604                let mut label = labels.next().flatten().unwrap_or_else(|| {
13605                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13606                });
13607                ensure_uniform_list_compatible_label(&mut label);
13608                completions.push(Completion {
13609                    label,
13610                    documentation,
13611                    replace_range: completion.replace_range,
13612                    new_text: completion.new_text,
13613                    insert_text_mode: lsp_completion.insert_text_mode,
13614                    source: completion.source,
13615                    icon_path: None,
13616                    confirm: None,
13617                    match_start: None,
13618                    snippet_deduplication_key: None,
13619                });
13620            }
13621            None => {
13622                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13623                ensure_uniform_list_compatible_label(&mut label);
13624                completions.push(Completion {
13625                    label,
13626                    documentation: None,
13627                    replace_range: completion.replace_range,
13628                    new_text: completion.new_text,
13629                    source: completion.source,
13630                    insert_text_mode: None,
13631                    icon_path: None,
13632                    confirm: None,
13633                    match_start: None,
13634                    snippet_deduplication_key: None,
13635                });
13636            }
13637        }
13638    }
13639    completions
13640}
13641
13642#[derive(Debug)]
13643pub enum LanguageServerToQuery {
13644    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13645    FirstCapable,
13646    /// Query a specific language server.
13647    Other(LanguageServerId),
13648}
13649
13650#[derive(Default)]
13651struct RenamePathsWatchedForServer {
13652    did_rename: Vec<RenameActionPredicate>,
13653    will_rename: Vec<RenameActionPredicate>,
13654}
13655
13656impl RenamePathsWatchedForServer {
13657    fn with_did_rename_patterns(
13658        mut self,
13659        did_rename: Option<&FileOperationRegistrationOptions>,
13660    ) -> Self {
13661        if let Some(did_rename) = did_rename {
13662            self.did_rename = did_rename
13663                .filters
13664                .iter()
13665                .filter_map(|filter| filter.try_into().log_err())
13666                .collect();
13667        }
13668        self
13669    }
13670    fn with_will_rename_patterns(
13671        mut self,
13672        will_rename: Option<&FileOperationRegistrationOptions>,
13673    ) -> Self {
13674        if let Some(will_rename) = will_rename {
13675            self.will_rename = will_rename
13676                .filters
13677                .iter()
13678                .filter_map(|filter| filter.try_into().log_err())
13679                .collect();
13680        }
13681        self
13682    }
13683
13684    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13685        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13686    }
13687    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13688        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13689    }
13690}
13691
13692impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13693    type Error = globset::Error;
13694    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13695        Ok(Self {
13696            kind: ops.pattern.matches.clone(),
13697            glob: GlobBuilder::new(&ops.pattern.glob)
13698                .case_insensitive(
13699                    ops.pattern
13700                        .options
13701                        .as_ref()
13702                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13703                )
13704                .build()?
13705                .compile_matcher(),
13706        })
13707    }
13708}
13709struct RenameActionPredicate {
13710    glob: GlobMatcher,
13711    kind: Option<FileOperationPatternKind>,
13712}
13713
13714impl RenameActionPredicate {
13715    // Returns true if language server should be notified
13716    fn eval(&self, path: &str, is_dir: bool) -> bool {
13717        self.kind.as_ref().is_none_or(|kind| {
13718            let expected_kind = if is_dir {
13719                FileOperationPatternKind::Folder
13720            } else {
13721                FileOperationPatternKind::File
13722            };
13723            kind == &expected_kind
13724        }) && self.glob.is_match(path)
13725    }
13726}
13727
13728#[derive(Default)]
13729struct LanguageServerWatchedPaths {
13730    worktree_paths: HashMap<WorktreeId, GlobSet>,
13731    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13732}
13733
13734#[derive(Default)]
13735struct LanguageServerWatchedPathsBuilder {
13736    worktree_paths: HashMap<WorktreeId, GlobSet>,
13737    abs_paths: HashMap<Arc<Path>, GlobSet>,
13738}
13739
13740impl LanguageServerWatchedPathsBuilder {
13741    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13742        self.worktree_paths.insert(worktree_id, glob_set);
13743    }
13744    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13745        self.abs_paths.insert(path, glob_set);
13746    }
13747    fn build(
13748        self,
13749        fs: Arc<dyn Fs>,
13750        language_server_id: LanguageServerId,
13751        cx: &mut Context<LspStore>,
13752    ) -> LanguageServerWatchedPaths {
13753        let lsp_store = cx.weak_entity();
13754
13755        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13756        let abs_paths = self
13757            .abs_paths
13758            .into_iter()
13759            .map(|(abs_path, globset)| {
13760                let task = cx.spawn({
13761                    let abs_path = abs_path.clone();
13762                    let fs = fs.clone();
13763
13764                    let lsp_store = lsp_store.clone();
13765                    async move |_, cx| {
13766                        maybe!(async move {
13767                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13768                            while let Some(update) = push_updates.0.next().await {
13769                                let action = lsp_store
13770                                    .update(cx, |this, _| {
13771                                        let Some(local) = this.as_local() else {
13772                                            return ControlFlow::Break(());
13773                                        };
13774                                        let Some(watcher) = local
13775                                            .language_server_watched_paths
13776                                            .get(&language_server_id)
13777                                        else {
13778                                            return ControlFlow::Break(());
13779                                        };
13780                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13781                                            "Watched abs path is not registered with a watcher",
13782                                        );
13783                                        let matching_entries = update
13784                                            .into_iter()
13785                                            .filter(|event| globs.is_match(&event.path))
13786                                            .collect::<Vec<_>>();
13787                                        this.lsp_notify_abs_paths_changed(
13788                                            language_server_id,
13789                                            matching_entries,
13790                                        );
13791                                        ControlFlow::Continue(())
13792                                    })
13793                                    .ok()?;
13794
13795                                if action.is_break() {
13796                                    break;
13797                                }
13798                            }
13799                            Some(())
13800                        })
13801                        .await;
13802                    }
13803                });
13804                (abs_path, (globset, task))
13805            })
13806            .collect();
13807        LanguageServerWatchedPaths {
13808            worktree_paths: self.worktree_paths,
13809            abs_paths,
13810        }
13811    }
13812}
13813
13814struct LspBufferSnapshot {
13815    version: i32,
13816    snapshot: TextBufferSnapshot,
13817}
13818
13819/// A prompt requested by LSP server.
13820#[derive(Clone, Debug)]
13821pub struct LanguageServerPromptRequest {
13822    pub id: usize,
13823    pub level: PromptLevel,
13824    pub message: String,
13825    pub actions: Vec<MessageActionItem>,
13826    pub lsp_name: String,
13827    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13828}
13829
13830impl LanguageServerPromptRequest {
13831    pub fn new(
13832        level: PromptLevel,
13833        message: String,
13834        actions: Vec<MessageActionItem>,
13835        lsp_name: String,
13836        response_channel: smol::channel::Sender<MessageActionItem>,
13837    ) -> Self {
13838        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13839        LanguageServerPromptRequest {
13840            id,
13841            level,
13842            message,
13843            actions,
13844            lsp_name,
13845            response_channel,
13846        }
13847    }
13848    pub async fn respond(self, index: usize) -> Option<()> {
13849        if let Some(response) = self.actions.into_iter().nth(index) {
13850            self.response_channel.send(response).await.ok()
13851        } else {
13852            None
13853        }
13854    }
13855
13856    #[cfg(any(test, feature = "test-support"))]
13857    pub fn test(
13858        level: PromptLevel,
13859        message: String,
13860        actions: Vec<MessageActionItem>,
13861        lsp_name: String,
13862    ) -> Self {
13863        let (tx, _rx) = smol::channel::unbounded();
13864        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13865    }
13866}
13867impl PartialEq for LanguageServerPromptRequest {
13868    fn eq(&self, other: &Self) -> bool {
13869        self.message == other.message && self.actions == other.actions
13870    }
13871}
13872
13873#[derive(Clone, Debug, PartialEq)]
13874pub enum LanguageServerLogType {
13875    Log(MessageType),
13876    Trace { verbose_info: Option<String> },
13877    Rpc { received: bool },
13878}
13879
13880impl LanguageServerLogType {
13881    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13882        match self {
13883            Self::Log(log_type) => {
13884                use proto::log_message::LogLevel;
13885                let level = match *log_type {
13886                    MessageType::ERROR => LogLevel::Error,
13887                    MessageType::WARNING => LogLevel::Warning,
13888                    MessageType::INFO => LogLevel::Info,
13889                    MessageType::LOG => LogLevel::Log,
13890                    other => {
13891                        log::warn!("Unknown lsp log message type: {other:?}");
13892                        LogLevel::Log
13893                    }
13894                };
13895                proto::language_server_log::LogType::Log(proto::LogMessage {
13896                    level: level as i32,
13897                })
13898            }
13899            Self::Trace { verbose_info } => {
13900                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13901                    verbose_info: verbose_info.to_owned(),
13902                })
13903            }
13904            Self::Rpc { received } => {
13905                let kind = if *received {
13906                    proto::rpc_message::Kind::Received
13907                } else {
13908                    proto::rpc_message::Kind::Sent
13909                };
13910                let kind = kind as i32;
13911                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13912            }
13913        }
13914    }
13915
13916    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13917        use proto::log_message::LogLevel;
13918        use proto::rpc_message;
13919        match log_type {
13920            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13921                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13922                    LogLevel::Error => MessageType::ERROR,
13923                    LogLevel::Warning => MessageType::WARNING,
13924                    LogLevel::Info => MessageType::INFO,
13925                    LogLevel::Log => MessageType::LOG,
13926                },
13927            ),
13928            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13929                verbose_info: trace_message.verbose_info,
13930            },
13931            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13932                received: match rpc_message::Kind::from_i32(message.kind)
13933                    .unwrap_or(rpc_message::Kind::Received)
13934                {
13935                    rpc_message::Kind::Received => true,
13936                    rpc_message::Kind::Sent => false,
13937                },
13938            },
13939        }
13940    }
13941}
13942
13943pub struct WorkspaceRefreshTask {
13944    refresh_tx: mpsc::Sender<()>,
13945    progress_tx: mpsc::Sender<()>,
13946    #[allow(dead_code)]
13947    task: Task<()>,
13948}
13949
13950pub enum LanguageServerState {
13951    Starting {
13952        startup: Task<Option<Arc<LanguageServer>>>,
13953        /// List of language servers that will be added to the workspace once it's initialization completes.
13954        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13955    },
13956
13957    Running {
13958        adapter: Arc<CachedLspAdapter>,
13959        server: Arc<LanguageServer>,
13960        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13961        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13962    },
13963}
13964
13965impl LanguageServerState {
13966    fn add_workspace_folder(&self, uri: Uri) {
13967        match self {
13968            LanguageServerState::Starting {
13969                pending_workspace_folders,
13970                ..
13971            } => {
13972                pending_workspace_folders.lock().insert(uri);
13973            }
13974            LanguageServerState::Running { server, .. } => {
13975                server.add_workspace_folder(uri);
13976            }
13977        }
13978    }
13979    fn _remove_workspace_folder(&self, uri: Uri) {
13980        match self {
13981            LanguageServerState::Starting {
13982                pending_workspace_folders,
13983                ..
13984            } => {
13985                pending_workspace_folders.lock().remove(&uri);
13986            }
13987            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13988        }
13989    }
13990}
13991
13992impl std::fmt::Debug for LanguageServerState {
13993    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13994        match self {
13995            LanguageServerState::Starting { .. } => {
13996                f.debug_struct("LanguageServerState::Starting").finish()
13997            }
13998            LanguageServerState::Running { .. } => {
13999                f.debug_struct("LanguageServerState::Running").finish()
14000            }
14001        }
14002    }
14003}
14004
14005#[derive(Clone, Debug, Serialize)]
14006pub struct LanguageServerProgress {
14007    pub is_disk_based_diagnostics_progress: bool,
14008    pub is_cancellable: bool,
14009    pub title: Option<String>,
14010    pub message: Option<String>,
14011    pub percentage: Option<usize>,
14012    #[serde(skip_serializing)]
14013    pub last_update_at: Instant,
14014}
14015
14016#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
14017pub struct DiagnosticSummary {
14018    pub error_count: usize,
14019    pub warning_count: usize,
14020}
14021
14022impl DiagnosticSummary {
14023    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
14024        let mut this = Self {
14025            error_count: 0,
14026            warning_count: 0,
14027        };
14028
14029        for entry in diagnostics {
14030            if entry.diagnostic.is_primary {
14031                match entry.diagnostic.severity {
14032                    DiagnosticSeverity::ERROR => this.error_count += 1,
14033                    DiagnosticSeverity::WARNING => this.warning_count += 1,
14034                    _ => {}
14035                }
14036            }
14037        }
14038
14039        this
14040    }
14041
14042    pub fn is_empty(&self) -> bool {
14043        self.error_count == 0 && self.warning_count == 0
14044    }
14045
14046    pub fn to_proto(
14047        self,
14048        language_server_id: LanguageServerId,
14049        path: &RelPath,
14050    ) -> proto::DiagnosticSummary {
14051        proto::DiagnosticSummary {
14052            path: path.to_proto(),
14053            language_server_id: language_server_id.0 as u64,
14054            error_count: self.error_count as u32,
14055            warning_count: self.warning_count as u32,
14056        }
14057    }
14058}
14059
14060#[derive(Clone, Debug)]
14061pub enum CompletionDocumentation {
14062    /// There is no documentation for this completion.
14063    Undocumented,
14064    /// A single line of documentation.
14065    SingleLine(SharedString),
14066    /// Multiple lines of plain text documentation.
14067    MultiLinePlainText(SharedString),
14068    /// Markdown documentation.
14069    MultiLineMarkdown(SharedString),
14070    /// Both single line and multiple lines of plain text documentation.
14071    SingleLineAndMultiLinePlainText {
14072        single_line: SharedString,
14073        plain_text: Option<SharedString>,
14074    },
14075}
14076
14077impl CompletionDocumentation {
14078    #[cfg(any(test, feature = "test-support"))]
14079    pub fn text(&self) -> SharedString {
14080        match self {
14081            CompletionDocumentation::Undocumented => "".into(),
14082            CompletionDocumentation::SingleLine(s) => s.clone(),
14083            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
14084            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
14085            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
14086                single_line.clone()
14087            }
14088        }
14089    }
14090}
14091
14092impl From<lsp::Documentation> for CompletionDocumentation {
14093    fn from(docs: lsp::Documentation) -> Self {
14094        match docs {
14095            lsp::Documentation::String(text) => {
14096                if text.lines().count() <= 1 {
14097                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
14098                } else {
14099                    CompletionDocumentation::MultiLinePlainText(text.into())
14100                }
14101            }
14102
14103            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
14104                lsp::MarkupKind::PlainText => {
14105                    if value.lines().count() <= 1 {
14106                        CompletionDocumentation::SingleLine(value.into())
14107                    } else {
14108                        CompletionDocumentation::MultiLinePlainText(value.into())
14109                    }
14110                }
14111
14112                lsp::MarkupKind::Markdown => {
14113                    CompletionDocumentation::MultiLineMarkdown(value.into())
14114                }
14115            },
14116        }
14117    }
14118}
14119
14120pub enum ResolvedHint {
14121    Resolved(InlayHint),
14122    Resolving(Shared<Task<()>>),
14123}
14124
14125pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
14126    glob.components()
14127        .take_while(|component| match component {
14128            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
14129            _ => true,
14130        })
14131        .collect()
14132}
14133
14134pub struct SshLspAdapter {
14135    name: LanguageServerName,
14136    binary: LanguageServerBinary,
14137    initialization_options: Option<String>,
14138    code_action_kinds: Option<Vec<CodeActionKind>>,
14139}
14140
14141impl SshLspAdapter {
14142    pub fn new(
14143        name: LanguageServerName,
14144        binary: LanguageServerBinary,
14145        initialization_options: Option<String>,
14146        code_action_kinds: Option<String>,
14147    ) -> Self {
14148        Self {
14149            name,
14150            binary,
14151            initialization_options,
14152            code_action_kinds: code_action_kinds
14153                .as_ref()
14154                .and_then(|c| serde_json::from_str(c).ok()),
14155        }
14156    }
14157}
14158
14159impl LspInstaller for SshLspAdapter {
14160    type BinaryVersion = ();
14161    async fn check_if_user_installed(
14162        &self,
14163        _: &dyn LspAdapterDelegate,
14164        _: Option<Toolchain>,
14165        _: &AsyncApp,
14166    ) -> Option<LanguageServerBinary> {
14167        Some(self.binary.clone())
14168    }
14169
14170    async fn cached_server_binary(
14171        &self,
14172        _: PathBuf,
14173        _: &dyn LspAdapterDelegate,
14174    ) -> Option<LanguageServerBinary> {
14175        None
14176    }
14177
14178    async fn fetch_latest_server_version(
14179        &self,
14180        _: &dyn LspAdapterDelegate,
14181        _: bool,
14182        _: &mut AsyncApp,
14183    ) -> Result<()> {
14184        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14185    }
14186
14187    async fn fetch_server_binary(
14188        &self,
14189        _: (),
14190        _: PathBuf,
14191        _: &dyn LspAdapterDelegate,
14192    ) -> Result<LanguageServerBinary> {
14193        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14194    }
14195}
14196
14197#[async_trait(?Send)]
14198impl LspAdapter for SshLspAdapter {
14199    fn name(&self) -> LanguageServerName {
14200        self.name.clone()
14201    }
14202
14203    async fn initialization_options(
14204        self: Arc<Self>,
14205        _: &Arc<dyn LspAdapterDelegate>,
14206        _: &mut AsyncApp,
14207    ) -> Result<Option<serde_json::Value>> {
14208        let Some(options) = &self.initialization_options else {
14209            return Ok(None);
14210        };
14211        let result = serde_json::from_str(options)?;
14212        Ok(result)
14213    }
14214
14215    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14216        self.code_action_kinds.clone()
14217    }
14218}
14219
14220pub fn language_server_settings<'a>(
14221    delegate: &'a dyn LspAdapterDelegate,
14222    language: &LanguageServerName,
14223    cx: &'a App,
14224) -> Option<&'a LspSettings> {
14225    language_server_settings_for(
14226        SettingsLocation {
14227            worktree_id: delegate.worktree_id(),
14228            path: RelPath::empty(),
14229        },
14230        language,
14231        cx,
14232    )
14233}
14234
14235pub fn language_server_settings_for<'a>(
14236    location: SettingsLocation<'a>,
14237    language: &LanguageServerName,
14238    cx: &'a App,
14239) -> Option<&'a LspSettings> {
14240    ProjectSettings::get(Some(location), cx).lsp.get(language)
14241}
14242
14243pub struct LocalLspAdapterDelegate {
14244    lsp_store: WeakEntity<LspStore>,
14245    worktree: worktree::Snapshot,
14246    fs: Arc<dyn Fs>,
14247    http_client: Arc<dyn HttpClient>,
14248    language_registry: Arc<LanguageRegistry>,
14249    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14250}
14251
14252impl LocalLspAdapterDelegate {
14253    pub fn new(
14254        language_registry: Arc<LanguageRegistry>,
14255        environment: &Entity<ProjectEnvironment>,
14256        lsp_store: WeakEntity<LspStore>,
14257        worktree: &Entity<Worktree>,
14258        http_client: Arc<dyn HttpClient>,
14259        fs: Arc<dyn Fs>,
14260        cx: &mut App,
14261    ) -> Arc<Self> {
14262        let load_shell_env_task =
14263            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14264
14265        Arc::new(Self {
14266            lsp_store,
14267            worktree: worktree.read(cx).snapshot(),
14268            fs,
14269            http_client,
14270            language_registry,
14271            load_shell_env_task,
14272        })
14273    }
14274
14275    pub fn from_local_lsp(
14276        local: &LocalLspStore,
14277        worktree: &Entity<Worktree>,
14278        cx: &mut App,
14279    ) -> Arc<Self> {
14280        Self::new(
14281            local.languages.clone(),
14282            &local.environment,
14283            local.weak.clone(),
14284            worktree,
14285            local.http_client.clone(),
14286            local.fs.clone(),
14287            cx,
14288        )
14289    }
14290}
14291
14292#[async_trait]
14293impl LspAdapterDelegate for LocalLspAdapterDelegate {
14294    fn show_notification(&self, message: &str, cx: &mut App) {
14295        self.lsp_store
14296            .update(cx, |_, cx| {
14297                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14298            })
14299            .ok();
14300    }
14301
14302    fn http_client(&self) -> Arc<dyn HttpClient> {
14303        self.http_client.clone()
14304    }
14305
14306    fn worktree_id(&self) -> WorktreeId {
14307        self.worktree.id()
14308    }
14309
14310    fn worktree_root_path(&self) -> &Path {
14311        self.worktree.abs_path().as_ref()
14312    }
14313
14314    fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
14315        self.worktree.resolve_relative_path(path)
14316    }
14317
14318    async fn shell_env(&self) -> HashMap<String, String> {
14319        let task = self.load_shell_env_task.clone();
14320        task.await.unwrap_or_default()
14321    }
14322
14323    async fn npm_package_installed_version(
14324        &self,
14325        package_name: &str,
14326    ) -> Result<Option<(PathBuf, Version)>> {
14327        let local_package_directory = self.worktree_root_path();
14328        let node_modules_directory = local_package_directory.join("node_modules");
14329
14330        if let Some(version) =
14331            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14332        {
14333            return Ok(Some((node_modules_directory, version)));
14334        }
14335        let Some(npm) = self.which("npm".as_ref()).await else {
14336            log::warn!(
14337                "Failed to find npm executable for {:?}",
14338                local_package_directory
14339            );
14340            return Ok(None);
14341        };
14342
14343        let env = self.shell_env().await;
14344        let output = util::command::new_command(&npm)
14345            .args(["root", "-g"])
14346            .envs(env)
14347            .current_dir(local_package_directory)
14348            .output()
14349            .await?;
14350        let global_node_modules =
14351            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14352
14353        if let Some(version) =
14354            read_package_installed_version(global_node_modules.clone(), package_name).await?
14355        {
14356            return Ok(Some((global_node_modules, version)));
14357        }
14358        return Ok(None);
14359    }
14360
14361    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14362        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14363        if self.fs.is_file(&worktree_abs_path).await {
14364            worktree_abs_path.pop();
14365        }
14366
14367        let env = self.shell_env().await;
14368
14369        let shell_path = env.get("PATH").cloned();
14370
14371        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14372    }
14373
14374    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14375        let mut working_dir = self.worktree_root_path().to_path_buf();
14376        if self.fs.is_file(&working_dir).await {
14377            working_dir.pop();
14378        }
14379        let output = util::command::new_command(&command.path)
14380            .args(command.arguments)
14381            .envs(command.env.clone().unwrap_or_default())
14382            .current_dir(working_dir)
14383            .output()
14384            .await?;
14385
14386        anyhow::ensure!(
14387            output.status.success(),
14388            "{}, stdout: {:?}, stderr: {:?}",
14389            output.status,
14390            String::from_utf8_lossy(&output.stdout),
14391            String::from_utf8_lossy(&output.stderr)
14392        );
14393        Ok(())
14394    }
14395
14396    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14397        self.language_registry
14398            .update_lsp_binary_status(server_name, status);
14399    }
14400
14401    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14402        self.language_registry
14403            .all_lsp_adapters()
14404            .into_iter()
14405            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14406            .collect()
14407    }
14408
14409    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14410        let dir = self.language_registry.language_server_download_dir(name)?;
14411
14412        if !dir.exists() {
14413            smol::fs::create_dir_all(&dir)
14414                .await
14415                .context("failed to create container directory")
14416                .log_err()?;
14417        }
14418
14419        Some(dir)
14420    }
14421
14422    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14423        let entry = self
14424            .worktree
14425            .entry_for_path(path)
14426            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14427        let abs_path = self.worktree.absolutize(&entry.path);
14428        self.fs.load(&abs_path).await
14429    }
14430}
14431
14432async fn populate_labels_for_symbols(
14433    symbols: Vec<CoreSymbol>,
14434    language_registry: &Arc<LanguageRegistry>,
14435    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14436    output: &mut Vec<Symbol>,
14437) {
14438    #[allow(clippy::mutable_key_type)]
14439    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14440
14441    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14442    for symbol in symbols {
14443        let Some(file_name) = symbol.path.file_name() else {
14444            continue;
14445        };
14446        let language = language_registry
14447            .load_language_for_file_path(Path::new(file_name))
14448            .await
14449            .ok()
14450            .or_else(|| {
14451                unknown_paths.insert(file_name.into());
14452                None
14453            });
14454        symbols_by_language
14455            .entry(language)
14456            .or_default()
14457            .push(symbol);
14458    }
14459
14460    for unknown_path in unknown_paths {
14461        log::info!("no language found for symbol in file {unknown_path:?}");
14462    }
14463
14464    let mut label_params = Vec::new();
14465    for (language, mut symbols) in symbols_by_language {
14466        label_params.clear();
14467        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14468            name: mem::take(&mut symbol.name),
14469            kind: symbol.kind,
14470            container_name: symbol.container_name.take(),
14471        }));
14472
14473        let mut labels = Vec::new();
14474        if let Some(language) = language {
14475            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14476                language_registry
14477                    .lsp_adapters(&language.name())
14478                    .first()
14479                    .cloned()
14480            });
14481            if let Some(lsp_adapter) = lsp_adapter {
14482                labels = lsp_adapter
14483                    .labels_for_symbols(&label_params, &language)
14484                    .await
14485                    .log_err()
14486                    .unwrap_or_default();
14487            }
14488        }
14489
14490        for (
14491            (
14492                symbol,
14493                language::Symbol {
14494                    name,
14495                    container_name,
14496                    ..
14497                },
14498            ),
14499            label,
14500        ) in symbols
14501            .into_iter()
14502            .zip(label_params.drain(..))
14503            .zip(labels.into_iter().chain(iter::repeat(None)))
14504        {
14505            output.push(Symbol {
14506                language_server_name: symbol.language_server_name,
14507                source_worktree_id: symbol.source_worktree_id,
14508                source_language_server_id: symbol.source_language_server_id,
14509                path: symbol.path,
14510                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14511                name,
14512                kind: symbol.kind,
14513                range: symbol.range,
14514                container_name,
14515            });
14516        }
14517    }
14518}
14519
14520pub(crate) fn collapse_newlines(text: &str, separator: &str) -> String {
14521    text.lines()
14522        .map(|line| line.trim())
14523        .filter(|line| !line.is_empty())
14524        .join(separator)
14525}
14526
14527fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14528    match server.capabilities().text_document_sync.as_ref()? {
14529        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14530            // Server wants didSave but didn't specify includeText.
14531            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14532            // Server doesn't want didSave at all.
14533            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14534            // Server provided SaveOptions.
14535            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14536                Some(save_options.include_text.unwrap_or(false))
14537            }
14538        },
14539        // We do not have any save info. Kind affects didChange only.
14540        lsp::TextDocumentSyncCapability::Kind(_) => None,
14541    }
14542}
14543
14544/// Completion items are displayed in a `UniformList`.
14545/// Usually, those items are single-line strings, but in LSP responses,
14546/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14547/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14548/// 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,
14549/// breaking the completions menu presentation.
14550///
14551/// 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.
14552pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14553    let mut new_text = String::with_capacity(label.text.len());
14554    let mut offset_map = vec![0; label.text.len() + 1];
14555    let mut last_char_was_space = false;
14556    let mut new_idx = 0;
14557    let chars = label.text.char_indices().fuse();
14558    let mut newlines_removed = false;
14559
14560    for (idx, c) in chars {
14561        offset_map[idx] = new_idx;
14562
14563        match c {
14564            '\n' if last_char_was_space => {
14565                newlines_removed = true;
14566            }
14567            '\t' | ' ' if last_char_was_space => {}
14568            '\n' if !last_char_was_space => {
14569                new_text.push(' ');
14570                new_idx += 1;
14571                last_char_was_space = true;
14572                newlines_removed = true;
14573            }
14574            ' ' | '\t' => {
14575                new_text.push(' ');
14576                new_idx += 1;
14577                last_char_was_space = true;
14578            }
14579            _ => {
14580                new_text.push(c);
14581                new_idx += c.len_utf8();
14582                last_char_was_space = false;
14583            }
14584        }
14585    }
14586    offset_map[label.text.len()] = new_idx;
14587
14588    // Only modify the label if newlines were removed.
14589    if !newlines_removed {
14590        return;
14591    }
14592
14593    let last_index = new_idx;
14594    let mut run_ranges_errors = Vec::new();
14595    label.runs.retain_mut(|(range, _)| {
14596        match offset_map.get(range.start) {
14597            Some(&start) => range.start = start,
14598            None => {
14599                run_ranges_errors.push(range.clone());
14600                return false;
14601            }
14602        }
14603
14604        match offset_map.get(range.end) {
14605            Some(&end) => range.end = end,
14606            None => {
14607                run_ranges_errors.push(range.clone());
14608                range.end = last_index;
14609            }
14610        }
14611        true
14612    });
14613    if !run_ranges_errors.is_empty() {
14614        log::error!(
14615            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14616            label.text
14617        );
14618    }
14619
14620    let mut wrong_filter_range = None;
14621    if label.filter_range == (0..label.text.len()) {
14622        label.filter_range = 0..new_text.len();
14623    } else {
14624        let mut original_filter_range = Some(label.filter_range.clone());
14625        match offset_map.get(label.filter_range.start) {
14626            Some(&start) => label.filter_range.start = start,
14627            None => {
14628                wrong_filter_range = original_filter_range.take();
14629                label.filter_range.start = last_index;
14630            }
14631        }
14632
14633        match offset_map.get(label.filter_range.end) {
14634            Some(&end) => label.filter_range.end = end,
14635            None => {
14636                wrong_filter_range = original_filter_range.take();
14637                label.filter_range.end = last_index;
14638            }
14639        }
14640    }
14641    if let Some(wrong_filter_range) = wrong_filter_range {
14642        log::error!(
14643            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14644            label.text
14645        );
14646    }
14647
14648    label.text = new_text;
14649}
14650
14651/// Apply edits to the buffer that will become part of the formatting transaction.
14652/// Fails if the buffer has been edited since the start of that transaction.
14653fn extend_formatting_transaction(
14654    buffer: &FormattableBuffer,
14655    formatting_transaction_id: text::TransactionId,
14656    cx: &mut AsyncApp,
14657    operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
14658) -> anyhow::Result<()> {
14659    buffer.handle.update(cx, |buffer, cx| {
14660        let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
14661        if last_transaction_id != Some(formatting_transaction_id) {
14662            anyhow::bail!("Buffer edited while formatting. Aborting")
14663        }
14664        buffer.start_transaction();
14665        operation(buffer, cx);
14666        if let Some(transaction_id) = buffer.end_transaction(cx) {
14667            buffer.merge_transactions(transaction_id, formatting_transaction_id);
14668        }
14669        Ok(())
14670    })
14671}