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, LanguageName, LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate,
   76    LspInstaller, ManifestDelegate, ManifestName, ModelineSettings, OffsetUtf16, Patch, PointUtf16,
   77    TextBufferSnapshot, ToOffset, ToOffsetUtf16, ToPointUtf16, Toolchain, Transaction, Unclipped,
   78    language_settings::{
   79        AllLanguageSettings, FormatOnSave, Formatter, LanguageSettings, all_language_settings,
   80    },
   81    modeline, point_to_lsp,
   82    proto::{
   83        deserialize_anchor, deserialize_anchor_range, deserialize_version, serialize_anchor,
   84        serialize_anchor_range, serialize_version,
   85    },
   86    range_from_lsp, range_to_lsp,
   87    row_chunk::RowChunk,
   88};
   89use lsp::{
   90    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   91    DEFAULT_LSP_REQUEST_TIMEOUT, DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   92    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   93    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LanguageServer,
   94    LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId, LanguageServerName,
   95    LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType, OneOf,
   96    RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles,
   97    WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   98};
   99use node_runtime::read_package_installed_version;
  100use parking_lot::Mutex;
  101use postage::{mpsc, sink::Sink, stream::Stream, watch};
  102use rand::prelude::*;
  103use rpc::{
  104    AnyProtoClient, ErrorCode, ErrorExt as _,
  105    proto::{LspRequestId, LspRequestMessage as _},
  106};
  107use semver::Version;
  108use serde::Serialize;
  109use serde_json::Value;
  110use settings::{Settings, SettingsLocation, SettingsStore};
  111use sha2::{Digest, Sha256};
  112use snippet::Snippet;
  113use std::{
  114    any::TypeId,
  115    borrow::Cow,
  116    cell::RefCell,
  117    cmp::{Ordering, Reverse},
  118    collections::{VecDeque, hash_map},
  119    convert::TryInto,
  120    ffi::OsStr,
  121    future::ready,
  122    iter, mem,
  123    ops::{ControlFlow, Range},
  124    path::{self, Path, PathBuf},
  125    pin::pin,
  126    rc::Rc,
  127    sync::{
  128        Arc,
  129        atomic::{self, AtomicUsize},
  130    },
  131    time::{Duration, Instant},
  132    vec,
  133};
  134use sum_tree::Dimensions;
  135use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  136
  137use util::{
  138    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  139    paths::{PathStyle, SanitizedPath, UrlExt},
  140    post_inc,
  141    redact::redact_command,
  142    rel_path::RelPath,
  143};
  144
  145pub use document_colors::DocumentColors;
  146pub use folding_ranges::LspFoldingRange;
  147pub use fs::*;
  148pub use language::Location;
  149pub use lsp_store::inlay_hints::{CacheInlayHints, InvalidationStrategy};
  150#[cfg(any(test, feature = "test-support"))]
  151pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  152#[cfg(any(test, feature = "test-support"))]
  153pub use prettier::RANGE_FORMAT_SUFFIX as TEST_PRETTIER_RANGE_FORMAT_SUFFIX;
  154pub use semantic_tokens::{
  155    BufferSemanticToken, BufferSemanticTokens, RefreshForServer, SemanticTokenStylizer, TokenType,
  156};
  157
  158pub use worktree::{
  159    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  160    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  161};
  162
  163const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  164pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  165const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  166const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  167static NEXT_PROMPT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
  168
  169#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  170pub enum ProgressToken {
  171    Number(i32),
  172    String(SharedString),
  173}
  174
  175impl std::fmt::Display for ProgressToken {
  176    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  177        match self {
  178            Self::Number(number) => write!(f, "{number}"),
  179            Self::String(string) => write!(f, "{string}"),
  180        }
  181    }
  182}
  183
  184impl ProgressToken {
  185    fn from_lsp(value: lsp::NumberOrString) -> Self {
  186        match value {
  187            lsp::NumberOrString::Number(number) => Self::Number(number),
  188            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  189        }
  190    }
  191
  192    fn to_lsp(&self) -> lsp::NumberOrString {
  193        match self {
  194            Self::Number(number) => lsp::NumberOrString::Number(*number),
  195            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  196        }
  197    }
  198
  199    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  200        Some(match value.value? {
  201            proto::progress_token::Value::Number(number) => Self::Number(number),
  202            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  203        })
  204    }
  205
  206    fn to_proto(&self) -> proto::ProgressToken {
  207        proto::ProgressToken {
  208            value: Some(match self {
  209                Self::Number(number) => proto::progress_token::Value::Number(*number),
  210                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  211            }),
  212        }
  213    }
  214}
  215
  216#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  217pub enum FormatTrigger {
  218    Save,
  219    Manual,
  220}
  221
  222pub enum LspFormatTarget {
  223    Buffers,
  224    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  225}
  226
  227#[derive(Debug, Clone, PartialEq, Eq, Hash)]
  228pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  229
  230struct OpenLspBuffer(Entity<Buffer>);
  231
  232impl FormatTrigger {
  233    fn from_proto(value: i32) -> FormatTrigger {
  234        match value {
  235            0 => FormatTrigger::Save,
  236            1 => FormatTrigger::Manual,
  237            _ => FormatTrigger::Save,
  238        }
  239    }
  240}
  241
  242#[derive(Clone)]
  243struct UnifiedLanguageServer {
  244    id: LanguageServerId,
  245    project_roots: HashSet<Arc<RelPath>>,
  246}
  247
  248/// Settings that affect language server identity.
  249///
  250/// Dynamic settings (`LspSettings::settings`) are excluded because they can be
  251/// updated via `workspace/didChangeConfiguration` without restarting the server.
  252#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  253struct LanguageServerSeedSettings {
  254    binary: Option<BinarySettings>,
  255    initialization_options: Option<serde_json::Value>,
  256}
  257
  258#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  259struct LanguageServerSeed {
  260    worktree_id: WorktreeId,
  261    name: LanguageServerName,
  262    toolchain: Option<Toolchain>,
  263    settings: LanguageServerSeedSettings,
  264}
  265
  266#[derive(Debug)]
  267pub struct DocumentDiagnosticsUpdate<'a, D> {
  268    pub diagnostics: D,
  269    pub result_id: Option<SharedString>,
  270    pub registration_id: Option<SharedString>,
  271    pub server_id: LanguageServerId,
  272    pub disk_based_sources: Cow<'a, [String]>,
  273}
  274
  275pub struct DocumentDiagnostics {
  276    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  277    document_abs_path: PathBuf,
  278    version: Option<i32>,
  279}
  280
  281#[derive(Default, Debug)]
  282struct DynamicRegistrations {
  283    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  284    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  285}
  286
  287pub struct LocalLspStore {
  288    weak: WeakEntity<LspStore>,
  289    pub worktree_store: Entity<WorktreeStore>,
  290    toolchain_store: Entity<LocalToolchainStore>,
  291    http_client: Arc<dyn HttpClient>,
  292    environment: Entity<ProjectEnvironment>,
  293    fs: Arc<dyn Fs>,
  294    languages: Arc<LanguageRegistry>,
  295    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  296    yarn: Entity<YarnPathStore>,
  297    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  298    buffers_being_formatted: HashSet<BufferId>,
  299    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  300    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  301    watched_manifest_filenames: HashSet<ManifestName>,
  302    language_server_paths_watched_for_rename:
  303        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  304    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  305    supplementary_language_servers:
  306        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  307    prettier_store: Entity<PrettierStore>,
  308    next_diagnostic_group_id: usize,
  309    diagnostics: HashMap<
  310        WorktreeId,
  311        HashMap<
  312            Arc<RelPath>,
  313            Vec<(
  314                LanguageServerId,
  315                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  316            )>,
  317        >,
  318    >,
  319    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  320    _subscription: gpui::Subscription,
  321    lsp_tree: LanguageServerTree,
  322    registered_buffers: HashMap<BufferId, usize>,
  323    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  324    buffer_pull_diagnostics_result_ids: HashMap<
  325        LanguageServerId,
  326        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  327    >,
  328    workspace_pull_diagnostics_result_ids: HashMap<
  329        LanguageServerId,
  330        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  331    >,
  332    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  333
  334    buffers_to_refresh_hash_set: HashSet<BufferId>,
  335    buffers_to_refresh_queue: VecDeque<BufferId>,
  336    _background_diagnostics_worker: Shared<Task<()>>,
  337}
  338
  339impl LocalLspStore {
  340    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  341    pub fn running_language_server_for_id(
  342        &self,
  343        id: LanguageServerId,
  344    ) -> Option<&Arc<LanguageServer>> {
  345        let language_server_state = self.language_servers.get(&id)?;
  346
  347        match language_server_state {
  348            LanguageServerState::Running { server, .. } => Some(server),
  349            LanguageServerState::Starting { .. } => None,
  350        }
  351    }
  352
  353    fn get_or_insert_language_server(
  354        &mut self,
  355        worktree_handle: &Entity<Worktree>,
  356        delegate: Arc<LocalLspAdapterDelegate>,
  357        disposition: &Arc<LaunchDisposition>,
  358        language_name: &LanguageName,
  359        cx: &mut App,
  360    ) -> LanguageServerId {
  361        let key = LanguageServerSeed {
  362            worktree_id: worktree_handle.read(cx).id(),
  363            name: disposition.server_name.clone(),
  364            settings: LanguageServerSeedSettings {
  365                binary: disposition.settings.binary.clone(),
  366                initialization_options: disposition.settings.initialization_options.clone(),
  367            },
  368            toolchain: disposition.toolchain.clone(),
  369        };
  370        if let Some(state) = self.language_server_ids.get_mut(&key) {
  371            state.project_roots.insert(disposition.path.path.clone());
  372            state.id
  373        } else {
  374            let adapter = self
  375                .languages
  376                .lsp_adapters(language_name)
  377                .into_iter()
  378                .find(|adapter| adapter.name() == disposition.server_name)
  379                .expect("To find LSP adapter");
  380            let new_language_server_id = self.start_language_server(
  381                worktree_handle,
  382                delegate,
  383                adapter,
  384                disposition.settings.clone(),
  385                key.clone(),
  386                language_name.clone(),
  387                cx,
  388            );
  389            if let Some(state) = self.language_server_ids.get_mut(&key) {
  390                state.project_roots.insert(disposition.path.path.clone());
  391            } else {
  392                debug_assert!(
  393                    false,
  394                    "Expected `start_language_server` to ensure that `key` exists in a map"
  395                );
  396            }
  397            new_language_server_id
  398        }
  399    }
  400
  401    fn start_language_server(
  402        &mut self,
  403        worktree_handle: &Entity<Worktree>,
  404        delegate: Arc<LocalLspAdapterDelegate>,
  405        adapter: Arc<CachedLspAdapter>,
  406        settings: Arc<LspSettings>,
  407        key: LanguageServerSeed,
  408        language_name: LanguageName,
  409        cx: &mut App,
  410    ) -> LanguageServerId {
  411        let worktree = worktree_handle.read(cx);
  412
  413        let worktree_id = worktree.id();
  414        let worktree_abs_path = worktree.abs_path();
  415        let toolchain = key.toolchain.clone();
  416        let override_options = settings.initialization_options.clone();
  417
  418        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  419
  420        let server_id = self.languages.next_language_server_id();
  421        log::trace!(
  422            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  423            adapter.name.0
  424        );
  425
  426        let wait_until_worktree_trust =
  427            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  428                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  429                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  430                });
  431                if can_trust {
  432                    self.restricted_worktrees_tasks.remove(&worktree_id);
  433                    None
  434                } else {
  435                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  436                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  437                        hash_map::Entry::Vacant(v) => {
  438                            let (mut tx, rx) = watch::channel::<bool>();
  439                            let lsp_store = self.weak.clone();
  440                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  441                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  442                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  443                                        tx.blocking_send(true).ok();
  444                                        lsp_store
  445                                            .update(cx, |lsp_store, _| {
  446                                                if let Some(local_lsp_store) =
  447                                                    lsp_store.as_local_mut()
  448                                                {
  449                                                    local_lsp_store
  450                                                        .restricted_worktrees_tasks
  451                                                        .remove(&worktree_id);
  452                                                }
  453                                            })
  454                                            .ok();
  455                                    }
  456                                }
  457                            });
  458                            v.insert((subscription, rx.clone()));
  459                            Some(rx)
  460                        }
  461                    }
  462                }
  463            });
  464        let update_binary_status = wait_until_worktree_trust.is_none();
  465
  466        let binary = self.get_language_server_binary(
  467            worktree_abs_path.clone(),
  468            adapter.clone(),
  469            settings,
  470            toolchain.clone(),
  471            delegate.clone(),
  472            true,
  473            wait_until_worktree_trust,
  474            cx,
  475        );
  476        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  477
  478        let pending_server = cx.spawn({
  479            let adapter = adapter.clone();
  480            let server_name = adapter.name.clone();
  481            let stderr_capture = stderr_capture.clone();
  482            #[cfg(any(test, feature = "test-support"))]
  483            let lsp_store = self.weak.clone();
  484            let pending_workspace_folders = pending_workspace_folders.clone();
  485            async move |cx| {
  486                let binary = binary.await?;
  487                #[cfg(any(test, feature = "test-support"))]
  488                if let Some(server) = lsp_store
  489                    .update(&mut cx.clone(), |this, cx| {
  490                        this.languages.create_fake_language_server(
  491                            server_id,
  492                            &server_name,
  493                            binary.clone(),
  494                            &mut cx.to_async(),
  495                        )
  496                    })
  497                    .ok()
  498                    .flatten()
  499                {
  500                    return Ok(server);
  501                }
  502
  503                let code_action_kinds = adapter.code_action_kinds();
  504                lsp::LanguageServer::new(
  505                    stderr_capture,
  506                    server_id,
  507                    server_name,
  508                    binary,
  509                    &worktree_abs_path,
  510                    code_action_kinds,
  511                    Some(pending_workspace_folders),
  512                    cx,
  513                )
  514            }
  515        });
  516
  517        let startup = {
  518            let server_name = adapter.name.0.clone();
  519            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  520            let key = key.clone();
  521            let adapter = adapter.clone();
  522            let lsp_store = self.weak.clone();
  523            let pending_workspace_folders = pending_workspace_folders.clone();
  524            let pull_diagnostics = ProjectSettings::get_global(cx)
  525                .diagnostics
  526                .lsp_pull_diagnostics
  527                .enabled;
  528            let settings_location = SettingsLocation {
  529                worktree_id,
  530                path: RelPath::empty(),
  531            };
  532            let augments_syntax_tokens = AllLanguageSettings::get(Some(settings_location), cx)
  533                .language(Some(settings_location), Some(&language_name), cx)
  534                .semantic_tokens
  535                .use_tree_sitter();
  536            cx.spawn(async move |cx| {
  537                let result = async {
  538                    let language_server = pending_server.await?;
  539
  540                    let workspace_config = Self::workspace_configuration_for_adapter(
  541                        adapter.adapter.clone(),
  542                        &delegate,
  543                        toolchain,
  544                        None,
  545                        cx,
  546                    )
  547                    .await?;
  548
  549                    let mut initialization_options = Self::initialization_options_for_adapter(
  550                        adapter.adapter.clone(),
  551                        &delegate,
  552                        cx,
  553                    )
  554                    .await?;
  555
  556                    match (&mut initialization_options, override_options) {
  557                        (Some(initialization_options), Some(override_options)) => {
  558                            merge_json_value_into(override_options, initialization_options);
  559                        }
  560                        (None, override_options) => initialization_options = override_options,
  561                        _ => {}
  562                    }
  563
  564                    let initialization_params = cx.update(|cx| {
  565                        let mut params = language_server.default_initialize_params(
  566                            pull_diagnostics,
  567                            augments_syntax_tokens,
  568                            cx,
  569                        );
  570                        params.initialization_options = initialization_options;
  571                        adapter.adapter.prepare_initialize_params(params, cx)
  572                    })?;
  573
  574                    Self::setup_lsp_messages(
  575                        lsp_store.clone(),
  576                        &language_server,
  577                        delegate.clone(),
  578                        adapter.clone(),
  579                    );
  580
  581                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  582                        settings: workspace_config,
  583                    };
  584                    let language_server = cx
  585                        .update(|cx| {
  586                            let request_timeout = ProjectSettings::get_global(cx)
  587                                .global_lsp_settings
  588                                .get_request_timeout();
  589
  590                            language_server.initialize(
  591                                initialization_params,
  592                                Arc::new(did_change_configuration_params.clone()),
  593                                request_timeout,
  594                                cx,
  595                            )
  596                        })
  597                        .await
  598                        .inspect_err(|_| {
  599                            if let Some(lsp_store) = lsp_store.upgrade() {
  600                                lsp_store.update(cx, |lsp_store, cx| {
  601                                    lsp_store.cleanup_lsp_data(server_id);
  602                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  603                                });
  604                            }
  605                        })?;
  606
  607                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  608                        did_change_configuration_params,
  609                    )?;
  610
  611                    anyhow::Ok(language_server)
  612                }
  613                .await;
  614
  615                match result {
  616                    Ok(server) => {
  617                        lsp_store
  618                            .update(cx, |lsp_store, cx| {
  619                                lsp_store.insert_newly_running_language_server(
  620                                    adapter,
  621                                    server.clone(),
  622                                    server_id,
  623                                    key,
  624                                    pending_workspace_folders,
  625                                    cx,
  626                                );
  627                            })
  628                            .ok();
  629                        stderr_capture.lock().take();
  630                        Some(server)
  631                    }
  632
  633                    Err(err) => {
  634                        let log = stderr_capture.lock().take().unwrap_or_default();
  635                        delegate.update_status(
  636                            adapter.name(),
  637                            BinaryStatus::Failed {
  638                                error: if log.is_empty() {
  639                                    format!("{err:#}")
  640                                } else {
  641                                    format!("{err:#}\n-- stderr --\n{log}")
  642                                },
  643                            },
  644                        );
  645                        log::error!(
  646                            "Failed to start language server {server_name:?}: {}",
  647                            redact_command(&format!("{err:?}"))
  648                        );
  649                        if !log.is_empty() {
  650                            log::error!("server stderr: {}", redact_command(&log));
  651                        }
  652                        None
  653                    }
  654                }
  655            })
  656        };
  657        let state = LanguageServerState::Starting {
  658            startup,
  659            pending_workspace_folders,
  660        };
  661
  662        if update_binary_status {
  663            self.languages
  664                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  665        }
  666
  667        self.language_servers.insert(server_id, state);
  668        self.language_server_ids
  669            .entry(key)
  670            .or_insert(UnifiedLanguageServer {
  671                id: server_id,
  672                project_roots: Default::default(),
  673            });
  674        server_id
  675    }
  676
  677    fn get_language_server_binary(
  678        &self,
  679        worktree_abs_path: Arc<Path>,
  680        adapter: Arc<CachedLspAdapter>,
  681        settings: Arc<LspSettings>,
  682        toolchain: Option<Toolchain>,
  683        delegate: Arc<dyn LspAdapterDelegate>,
  684        allow_binary_download: bool,
  685        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  686        cx: &mut App,
  687    ) -> Task<Result<LanguageServerBinary>> {
  688        if let Some(settings) = &settings.binary
  689            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  690        {
  691            let settings = settings.clone();
  692            let languages = self.languages.clone();
  693            return cx.background_spawn(async move {
  694                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  695                    let already_trusted =  *wait_until_worktree_trust.borrow();
  696                    if !already_trusted {
  697                        log::info!(
  698                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  699                            adapter.name(),
  700                        );
  701                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  702                            if worktree_trusted {
  703                                break;
  704                            }
  705                        }
  706                        log::info!(
  707                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  708                            adapter.name(),
  709                        );
  710                    }
  711                    languages
  712                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  713                }
  714                let mut env = delegate.shell_env().await;
  715                env.extend(settings.env.unwrap_or_default());
  716
  717                Ok(LanguageServerBinary {
  718                    path: delegate.resolve_relative_path(path),
  719                    env: Some(env),
  720                    arguments: settings
  721                        .arguments
  722                        .unwrap_or_default()
  723                        .iter()
  724                        .map(Into::into)
  725                        .collect(),
  726                })
  727            });
  728        }
  729        let lsp_binary_options = LanguageServerBinaryOptions {
  730            allow_path_lookup: !settings
  731                .binary
  732                .as_ref()
  733                .and_then(|b| b.ignore_system_version)
  734                .unwrap_or_default(),
  735            allow_binary_download,
  736            pre_release: settings
  737                .fetch
  738                .as_ref()
  739                .and_then(|f| f.pre_release)
  740                .unwrap_or(false),
  741        };
  742
  743        cx.spawn(async move |cx| {
  744            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  745                let already_trusted =  *wait_until_worktree_trust.borrow();
  746                if !already_trusted {
  747                    log::info!(
  748                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  749                        adapter.name(),
  750                    );
  751                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  752                        if worktree_trusted {
  753                            break;
  754                        }
  755                    }
  756                    log::info!(
  757                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  758                            adapter.name(),
  759                    );
  760                }
  761            }
  762
  763            let (existing_binary, maybe_download_binary) = adapter
  764                .clone()
  765                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  766                .await
  767                .await;
  768
  769            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  770
  771            let mut binary = match (existing_binary, maybe_download_binary) {
  772                (binary, None) => binary?,
  773                (Err(_), Some(downloader)) => downloader.await?,
  774                (Ok(existing_binary), Some(downloader)) => {
  775                    let mut download_timeout = cx
  776                        .background_executor()
  777                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  778                        .fuse();
  779                    let mut downloader = downloader.fuse();
  780                    futures::select! {
  781                        _ = download_timeout => {
  782                            // Return existing binary and kick the existing work to the background.
  783                            cx.spawn(async move |_| downloader.await).detach();
  784                            Ok(existing_binary)
  785                        },
  786                        downloaded_or_existing_binary = downloader => {
  787                            // If download fails, this results in the existing binary.
  788                            downloaded_or_existing_binary
  789                        }
  790                    }?
  791                }
  792            };
  793            let mut shell_env = delegate.shell_env().await;
  794
  795            shell_env.extend(binary.env.unwrap_or_default());
  796
  797            if let Some(settings) = settings.binary.as_ref() {
  798                if let Some(arguments) = &settings.arguments {
  799                    binary.arguments = arguments.iter().map(Into::into).collect();
  800                }
  801                if let Some(env) = &settings.env {
  802                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  803                }
  804            }
  805
  806            binary.env = Some(shell_env);
  807            Ok(binary)
  808        })
  809    }
  810
  811    fn setup_lsp_messages(
  812        lsp_store: WeakEntity<LspStore>,
  813        language_server: &LanguageServer,
  814        delegate: Arc<dyn LspAdapterDelegate>,
  815        adapter: Arc<CachedLspAdapter>,
  816    ) {
  817        let name = language_server.name();
  818        let server_id = language_server.server_id();
  819        language_server
  820            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  821                let adapter = adapter.clone();
  822                let this = lsp_store.clone();
  823                move |mut params, cx| {
  824                    let adapter = adapter.clone();
  825                    if let Some(this) = this.upgrade() {
  826                        this.update(cx, |this, cx| {
  827                            adapter.process_diagnostics(&mut params, server_id);
  828
  829                            this.merge_lsp_diagnostics(
  830                                DiagnosticSourceKind::Pushed,
  831                                vec![DocumentDiagnosticsUpdate {
  832                                    server_id,
  833                                    diagnostics: params,
  834                                    result_id: None,
  835                                    disk_based_sources: Cow::Borrowed(
  836                                        &adapter.disk_based_diagnostic_sources,
  837                                    ),
  838                                    registration_id: None,
  839                                }],
  840                                |_, diagnostic, _cx| match diagnostic.source_kind {
  841                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  842                                        adapter.retain_old_diagnostic(diagnostic)
  843                                    }
  844                                    DiagnosticSourceKind::Pulled => true,
  845                                },
  846                                cx,
  847                            )
  848                            .log_err();
  849                        });
  850                    }
  851                }
  852            })
  853            .detach();
  854        language_server
  855            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  856                let adapter = adapter.adapter.clone();
  857                let delegate = delegate.clone();
  858                let this = lsp_store.clone();
  859                move |params, cx| {
  860                    let adapter = adapter.clone();
  861                    let delegate = delegate.clone();
  862                    let this = this.clone();
  863                    let mut cx = cx.clone();
  864                    async move {
  865                        let toolchain_for_id = this
  866                            .update(&mut cx, |this, _| {
  867                                this.as_local()?.language_server_ids.iter().find_map(
  868                                    |(seed, value)| {
  869                                        (value.id == server_id).then(|| seed.toolchain.clone())
  870                                    },
  871                                )
  872                            })?
  873                            .context("Expected the LSP store to be in a local mode")?;
  874
  875                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  876                        for item in &params.items {
  877                            let scope_uri = item.scope_uri.clone();
  878                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  879                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  880                            else {
  881                                // We've already queried workspace configuration of this URI.
  882                                continue;
  883                            };
  884                            let workspace_config = Self::workspace_configuration_for_adapter(
  885                                adapter.clone(),
  886                                &delegate,
  887                                toolchain_for_id.clone(),
  888                                scope_uri,
  889                                &mut cx,
  890                            )
  891                            .await?;
  892                            new_scope_uri.insert(workspace_config);
  893                        }
  894
  895                        Ok(params
  896                            .items
  897                            .into_iter()
  898                            .filter_map(|item| {
  899                                let workspace_config =
  900                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  901                                if let Some(section) = &item.section {
  902                                    Some(
  903                                        workspace_config
  904                                            .get(section)
  905                                            .cloned()
  906                                            .unwrap_or(serde_json::Value::Null),
  907                                    )
  908                                } else {
  909                                    Some(workspace_config.clone())
  910                                }
  911                            })
  912                            .collect())
  913                    }
  914                }
  915            })
  916            .detach();
  917
  918        language_server
  919            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  920                let this = lsp_store.clone();
  921                move |_, cx| {
  922                    let this = this.clone();
  923                    let cx = cx.clone();
  924                    async move {
  925                        let Some(server) =
  926                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  927                        else {
  928                            return Ok(None);
  929                        };
  930                        let root = server.workspace_folders();
  931                        Ok(Some(
  932                            root.into_iter()
  933                                .map(|uri| WorkspaceFolder {
  934                                    uri,
  935                                    name: Default::default(),
  936                                })
  937                                .collect(),
  938                        ))
  939                    }
  940                }
  941            })
  942            .detach();
  943        // Even though we don't have handling for these requests, respond to them to
  944        // avoid stalling any language server like `gopls` which waits for a response
  945        // to these requests when initializing.
  946        language_server
  947            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  948                let this = lsp_store.clone();
  949                move |params, cx| {
  950                    let this = this.clone();
  951                    let mut cx = cx.clone();
  952                    async move {
  953                        this.update(&mut cx, |this, _| {
  954                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  955                            {
  956                                status
  957                                    .progress_tokens
  958                                    .insert(ProgressToken::from_lsp(params.token));
  959                            }
  960                        })?;
  961
  962                        Ok(())
  963                    }
  964                }
  965            })
  966            .detach();
  967
  968        language_server
  969            .on_request::<lsp::request::RegisterCapability, _, _>({
  970                let lsp_store = lsp_store.clone();
  971                move |params, cx| {
  972                    let lsp_store = lsp_store.clone();
  973                    let mut cx = cx.clone();
  974                    async move {
  975                        lsp_store
  976                            .update(&mut cx, |lsp_store, cx| {
  977                                if lsp_store.as_local().is_some() {
  978                                    match lsp_store
  979                                        .register_server_capabilities(server_id, params, cx)
  980                                    {
  981                                        Ok(()) => {}
  982                                        Err(e) => {
  983                                            log::error!(
  984                                                "Failed to register server capabilities: {e:#}"
  985                                            );
  986                                        }
  987                                    };
  988                                }
  989                            })
  990                            .ok();
  991                        Ok(())
  992                    }
  993                }
  994            })
  995            .detach();
  996
  997        language_server
  998            .on_request::<lsp::request::UnregisterCapability, _, _>({
  999                let lsp_store = lsp_store.clone();
 1000                move |params, cx| {
 1001                    let lsp_store = lsp_store.clone();
 1002                    let mut cx = cx.clone();
 1003                    async move {
 1004                        lsp_store
 1005                            .update(&mut cx, |lsp_store, cx| {
 1006                                if lsp_store.as_local().is_some() {
 1007                                    match lsp_store
 1008                                        .unregister_server_capabilities(server_id, params, cx)
 1009                                    {
 1010                                        Ok(()) => {}
 1011                                        Err(e) => {
 1012                                            log::error!(
 1013                                                "Failed to unregister server capabilities: {e:#}"
 1014                                            );
 1015                                        }
 1016                                    }
 1017                                }
 1018                            })
 1019                            .ok();
 1020                        Ok(())
 1021                    }
 1022                }
 1023            })
 1024            .detach();
 1025
 1026        language_server
 1027            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
 1028                let this = lsp_store.clone();
 1029                move |params, cx| {
 1030                    let mut cx = cx.clone();
 1031                    let this = this.clone();
 1032                    async move {
 1033                        LocalLspStore::on_lsp_workspace_edit(
 1034                            this.clone(),
 1035                            params,
 1036                            server_id,
 1037                            &mut cx,
 1038                        )
 1039                        .await
 1040                    }
 1041                }
 1042            })
 1043            .detach();
 1044
 1045        language_server
 1046            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1047                let lsp_store = lsp_store.clone();
 1048                let request_id = Arc::new(AtomicUsize::new(0));
 1049                move |(), cx| {
 1050                    let lsp_store = lsp_store.clone();
 1051                    let request_id = request_id.clone();
 1052                    let mut cx = cx.clone();
 1053                    async move {
 1054                        lsp_store
 1055                            .update(&mut cx, |lsp_store, cx| {
 1056                                let request_id =
 1057                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1058                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1059                                    server_id,
 1060                                    request_id,
 1061                                });
 1062                                lsp_store
 1063                                    .downstream_client
 1064                                    .as_ref()
 1065                                    .map(|(client, project_id)| {
 1066                                        client.send(proto::RefreshInlayHints {
 1067                                            project_id: *project_id,
 1068                                            server_id: server_id.to_proto(),
 1069                                            request_id: request_id.map(|id| id as u64),
 1070                                        })
 1071                                    })
 1072                            })?
 1073                            .transpose()?;
 1074                        Ok(())
 1075                    }
 1076                }
 1077            })
 1078            .detach();
 1079
 1080        language_server
 1081            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1082                let this = lsp_store.clone();
 1083                move |(), cx| {
 1084                    let this = this.clone();
 1085                    let mut cx = cx.clone();
 1086                    async move {
 1087                        this.update(&mut cx, |this, cx| {
 1088                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1089                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1090                                client.send(proto::RefreshCodeLens {
 1091                                    project_id: *project_id,
 1092                                })
 1093                            })
 1094                        })?
 1095                        .transpose()?;
 1096                        Ok(())
 1097                    }
 1098                }
 1099            })
 1100            .detach();
 1101
 1102        language_server
 1103            .on_request::<lsp::request::SemanticTokensRefresh, _, _>({
 1104                let lsp_store = lsp_store.clone();
 1105                let request_id = Arc::new(AtomicUsize::new(0));
 1106                move |(), cx| {
 1107                    let lsp_store = lsp_store.clone();
 1108                    let request_id = request_id.clone();
 1109                    let mut cx = cx.clone();
 1110                    async move {
 1111                        lsp_store
 1112                            .update(&mut cx, |lsp_store, cx| {
 1113                                let request_id =
 1114                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1115                                cx.emit(LspStoreEvent::RefreshSemanticTokens {
 1116                                    server_id,
 1117                                    request_id,
 1118                                });
 1119                                lsp_store
 1120                                    .downstream_client
 1121                                    .as_ref()
 1122                                    .map(|(client, project_id)| {
 1123                                        client.send(proto::RefreshSemanticTokens {
 1124                                            project_id: *project_id,
 1125                                            server_id: server_id.to_proto(),
 1126                                            request_id: request_id.map(|id| id as u64),
 1127                                        })
 1128                                    })
 1129                            })?
 1130                            .transpose()?;
 1131                        Ok(())
 1132                    }
 1133                }
 1134            })
 1135            .detach();
 1136
 1137        language_server
 1138            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1139                let this = lsp_store.clone();
 1140                move |(), cx| {
 1141                    let this = this.clone();
 1142                    let mut cx = cx.clone();
 1143                    async move {
 1144                        this.update(&mut cx, |lsp_store, cx| {
 1145                            lsp_store.pull_workspace_diagnostics(server_id);
 1146                            lsp_store
 1147                                .downstream_client
 1148                                .as_ref()
 1149                                .map(|(client, project_id)| {
 1150                                    client.send(proto::PullWorkspaceDiagnostics {
 1151                                        project_id: *project_id,
 1152                                        server_id: server_id.to_proto(),
 1153                                    })
 1154                                })
 1155                                .transpose()?;
 1156                            anyhow::Ok(
 1157                                lsp_store.pull_document_diagnostics_for_server(server_id, None, cx),
 1158                            )
 1159                        })??
 1160                        .await;
 1161                        Ok(())
 1162                    }
 1163                }
 1164            })
 1165            .detach();
 1166
 1167        language_server
 1168            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1169                let this = lsp_store.clone();
 1170                let name = name.to_string();
 1171                let adapter = adapter.clone();
 1172                move |params, cx| {
 1173                    let this = this.clone();
 1174                    let name = name.to_string();
 1175                    let adapter = adapter.clone();
 1176                    let mut cx = cx.clone();
 1177                    async move {
 1178                        let actions = params.actions.unwrap_or_default();
 1179                        let message = params.message.clone();
 1180                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1181                        let level = match params.typ {
 1182                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1183                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1184                            _ => PromptLevel::Info,
 1185                        };
 1186                        let request = LanguageServerPromptRequest::new(
 1187                            level,
 1188                            params.message,
 1189                            actions,
 1190                            name.clone(),
 1191                            tx,
 1192                        );
 1193
 1194                        let did_update = this
 1195                            .update(&mut cx, |_, cx| {
 1196                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1197                            })
 1198                            .is_ok();
 1199                        if did_update {
 1200                            let response = rx.recv().await.ok();
 1201                            if let Some(ref selected_action) = response {
 1202                                let context = language::PromptResponseContext {
 1203                                    message,
 1204                                    selected_action: selected_action.clone(),
 1205                                };
 1206                                adapter.process_prompt_response(&context, &mut cx)
 1207                            }
 1208
 1209                            Ok(response)
 1210                        } else {
 1211                            Ok(None)
 1212                        }
 1213                    }
 1214                }
 1215            })
 1216            .detach();
 1217        language_server
 1218            .on_notification::<lsp::notification::ShowMessage, _>({
 1219                let this = lsp_store.clone();
 1220                let name = name.to_string();
 1221                move |params, cx| {
 1222                    let this = this.clone();
 1223                    let name = name.to_string();
 1224                    let mut cx = cx.clone();
 1225
 1226                    let (tx, _) = smol::channel::bounded(1);
 1227                    let level = match params.typ {
 1228                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1229                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1230                        _ => PromptLevel::Info,
 1231                    };
 1232                    let request =
 1233                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1234
 1235                    let _ = this.update(&mut cx, |_, cx| {
 1236                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1237                    });
 1238                }
 1239            })
 1240            .detach();
 1241
 1242        let disk_based_diagnostics_progress_token =
 1243            adapter.disk_based_diagnostics_progress_token.clone();
 1244
 1245        language_server
 1246            .on_notification::<lsp::notification::Progress, _>({
 1247                let this = lsp_store.clone();
 1248                move |params, cx| {
 1249                    if let Some(this) = this.upgrade() {
 1250                        this.update(cx, |this, cx| {
 1251                            this.on_lsp_progress(
 1252                                params,
 1253                                server_id,
 1254                                disk_based_diagnostics_progress_token.clone(),
 1255                                cx,
 1256                            );
 1257                        });
 1258                    }
 1259                }
 1260            })
 1261            .detach();
 1262
 1263        language_server
 1264            .on_notification::<lsp::notification::LogMessage, _>({
 1265                let this = lsp_store.clone();
 1266                move |params, cx| {
 1267                    if let Some(this) = this.upgrade() {
 1268                        this.update(cx, |_, cx| {
 1269                            cx.emit(LspStoreEvent::LanguageServerLog(
 1270                                server_id,
 1271                                LanguageServerLogType::Log(params.typ),
 1272                                params.message,
 1273                            ));
 1274                        });
 1275                    }
 1276                }
 1277            })
 1278            .detach();
 1279
 1280        language_server
 1281            .on_notification::<lsp::notification::LogTrace, _>({
 1282                let this = lsp_store.clone();
 1283                move |params, cx| {
 1284                    let mut cx = cx.clone();
 1285                    if let Some(this) = this.upgrade() {
 1286                        this.update(&mut cx, |_, cx| {
 1287                            cx.emit(LspStoreEvent::LanguageServerLog(
 1288                                server_id,
 1289                                LanguageServerLogType::Trace {
 1290                                    verbose_info: params.verbose,
 1291                                },
 1292                                params.message,
 1293                            ));
 1294                        });
 1295                    }
 1296                }
 1297            })
 1298            .detach();
 1299
 1300        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1301        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1302        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1303        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1304    }
 1305
 1306    fn shutdown_language_servers_on_quit(&mut self) -> impl Future<Output = ()> + use<> {
 1307        let shutdown_futures = self
 1308            .language_servers
 1309            .drain()
 1310            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1311            .collect::<Vec<_>>();
 1312
 1313        async move {
 1314            join_all(shutdown_futures).await;
 1315        }
 1316    }
 1317
 1318    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1319        match server_state {
 1320            LanguageServerState::Running { server, .. } => {
 1321                if let Some(shutdown) = server.shutdown() {
 1322                    shutdown.await;
 1323                }
 1324            }
 1325            LanguageServerState::Starting { startup, .. } => {
 1326                if let Some(server) = startup.await
 1327                    && let Some(shutdown) = server.shutdown()
 1328                {
 1329                    shutdown.await;
 1330                }
 1331            }
 1332        }
 1333        Ok(())
 1334    }
 1335
 1336    fn language_servers_for_worktree(
 1337        &self,
 1338        worktree_id: WorktreeId,
 1339    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1340        self.language_server_ids
 1341            .iter()
 1342            .filter_map(move |(seed, state)| {
 1343                if seed.worktree_id != worktree_id {
 1344                    return None;
 1345                }
 1346
 1347                if let Some(LanguageServerState::Running { server, .. }) =
 1348                    self.language_servers.get(&state.id)
 1349                {
 1350                    Some(server)
 1351                } else {
 1352                    None
 1353                }
 1354            })
 1355    }
 1356
 1357    fn language_server_ids_for_project_path(
 1358        &self,
 1359        project_path: ProjectPath,
 1360        language: &Language,
 1361        cx: &mut App,
 1362    ) -> Vec<LanguageServerId> {
 1363        let Some(worktree) = self
 1364            .worktree_store
 1365            .read(cx)
 1366            .worktree_for_id(project_path.worktree_id, cx)
 1367        else {
 1368            return Vec::new();
 1369        };
 1370        let delegate: Arc<dyn ManifestDelegate> =
 1371            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1372
 1373        self.lsp_tree
 1374            .get(
 1375                project_path,
 1376                language.name(),
 1377                language.manifest(),
 1378                &delegate,
 1379                cx,
 1380            )
 1381            .collect::<Vec<_>>()
 1382    }
 1383
 1384    fn language_server_ids_for_buffer(
 1385        &self,
 1386        buffer: &Buffer,
 1387        cx: &mut App,
 1388    ) -> Vec<LanguageServerId> {
 1389        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1390            let worktree_id = file.worktree_id(cx);
 1391
 1392            let path: Arc<RelPath> = file
 1393                .path()
 1394                .parent()
 1395                .map(Arc::from)
 1396                .unwrap_or_else(|| file.path().clone());
 1397            let worktree_path = ProjectPath { worktree_id, path };
 1398            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1399        } else {
 1400            Vec::new()
 1401        }
 1402    }
 1403
 1404    fn language_servers_for_buffer<'a>(
 1405        &'a self,
 1406        buffer: &'a Buffer,
 1407        cx: &'a mut App,
 1408    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1409        self.language_server_ids_for_buffer(buffer, cx)
 1410            .into_iter()
 1411            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1412                LanguageServerState::Running {
 1413                    adapter, server, ..
 1414                } => Some((adapter, server)),
 1415                _ => None,
 1416            })
 1417    }
 1418
 1419    async fn execute_code_action_kind_locally(
 1420        lsp_store: WeakEntity<LspStore>,
 1421        mut buffers: Vec<Entity<Buffer>>,
 1422        kind: CodeActionKind,
 1423        push_to_history: bool,
 1424        cx: &mut AsyncApp,
 1425    ) -> anyhow::Result<ProjectTransaction> {
 1426        // Do not allow multiple concurrent code actions requests for the
 1427        // same buffer.
 1428        lsp_store.update(cx, |this, cx| {
 1429            let this = this.as_local_mut().unwrap();
 1430            buffers.retain(|buffer| {
 1431                this.buffers_being_formatted
 1432                    .insert(buffer.read(cx).remote_id())
 1433            });
 1434        })?;
 1435        let _cleanup = defer({
 1436            let this = lsp_store.clone();
 1437            let mut cx = cx.clone();
 1438            let buffers = &buffers;
 1439            move || {
 1440                this.update(&mut cx, |this, cx| {
 1441                    let this = this.as_local_mut().unwrap();
 1442                    for buffer in buffers {
 1443                        this.buffers_being_formatted
 1444                            .remove(&buffer.read(cx).remote_id());
 1445                    }
 1446                })
 1447                .ok();
 1448            }
 1449        });
 1450        let mut project_transaction = ProjectTransaction::default();
 1451
 1452        for buffer in &buffers {
 1453            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1454                buffer.update(cx, |buffer, cx| {
 1455                    lsp_store
 1456                        .as_local()
 1457                        .unwrap()
 1458                        .language_servers_for_buffer(buffer, cx)
 1459                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1460                        .collect::<Vec<_>>()
 1461                })
 1462            })?;
 1463            for (_, language_server) in adapters_and_servers.iter() {
 1464                let actions = Self::get_server_code_actions_from_action_kinds(
 1465                    &lsp_store,
 1466                    language_server.server_id(),
 1467                    vec![kind.clone()],
 1468                    buffer,
 1469                    cx,
 1470                )
 1471                .await?;
 1472                Self::execute_code_actions_on_server(
 1473                    &lsp_store,
 1474                    language_server,
 1475                    actions,
 1476                    push_to_history,
 1477                    &mut project_transaction,
 1478                    cx,
 1479                )
 1480                .await?;
 1481            }
 1482        }
 1483        Ok(project_transaction)
 1484    }
 1485
 1486    async fn format_locally(
 1487        lsp_store: WeakEntity<LspStore>,
 1488        mut buffers: Vec<FormattableBuffer>,
 1489        push_to_history: bool,
 1490        trigger: FormatTrigger,
 1491        logger: zlog::Logger,
 1492        cx: &mut AsyncApp,
 1493    ) -> anyhow::Result<ProjectTransaction> {
 1494        // Do not allow multiple concurrent formatting requests for the
 1495        // same buffer.
 1496        lsp_store.update(cx, |this, cx| {
 1497            let this = this.as_local_mut().unwrap();
 1498            buffers.retain(|buffer| {
 1499                this.buffers_being_formatted
 1500                    .insert(buffer.handle.read(cx).remote_id())
 1501            });
 1502        })?;
 1503
 1504        let _cleanup = defer({
 1505            let this = lsp_store.clone();
 1506            let mut cx = cx.clone();
 1507            let buffers = &buffers;
 1508            move || {
 1509                this.update(&mut cx, |this, cx| {
 1510                    let this = this.as_local_mut().unwrap();
 1511                    for buffer in buffers {
 1512                        this.buffers_being_formatted
 1513                            .remove(&buffer.handle.read(cx).remote_id());
 1514                    }
 1515                })
 1516                .ok();
 1517            }
 1518        });
 1519
 1520        let mut project_transaction = ProjectTransaction::default();
 1521
 1522        for buffer in &buffers {
 1523            zlog::debug!(
 1524                logger =>
 1525                "formatting buffer '{:?}'",
 1526                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1527            );
 1528            // Create an empty transaction to hold all of the formatting edits.
 1529            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1530                // ensure no transactions created while formatting are
 1531                // grouped with the previous transaction in the history
 1532                // based on the transaction group interval
 1533                buffer.finalize_last_transaction();
 1534                buffer
 1535                    .start_transaction()
 1536                    .context("transaction already open")?;
 1537                buffer.end_transaction(cx);
 1538                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1539                buffer.finalize_last_transaction();
 1540                anyhow::Ok(transaction_id)
 1541            })?;
 1542
 1543            let result = Self::format_buffer_locally(
 1544                lsp_store.clone(),
 1545                buffer,
 1546                formatting_transaction_id,
 1547                trigger,
 1548                logger,
 1549                cx,
 1550            )
 1551            .await;
 1552
 1553            buffer.handle.update(cx, |buffer, cx| {
 1554                let Some(formatting_transaction) =
 1555                    buffer.get_transaction(formatting_transaction_id).cloned()
 1556                else {
 1557                    zlog::warn!(logger => "no formatting transaction");
 1558                    return;
 1559                };
 1560                if formatting_transaction.edit_ids.is_empty() {
 1561                    zlog::debug!(logger => "no changes made while formatting");
 1562                    buffer.forget_transaction(formatting_transaction_id);
 1563                    return;
 1564                }
 1565                if !push_to_history {
 1566                    zlog::trace!(logger => "forgetting format transaction");
 1567                    buffer.forget_transaction(formatting_transaction.id);
 1568                }
 1569                project_transaction
 1570                    .0
 1571                    .insert(cx.entity(), formatting_transaction);
 1572            });
 1573
 1574            result?;
 1575        }
 1576
 1577        Ok(project_transaction)
 1578    }
 1579
 1580    async fn format_buffer_locally(
 1581        lsp_store: WeakEntity<LspStore>,
 1582        buffer: &FormattableBuffer,
 1583        formatting_transaction_id: clock::Lamport,
 1584        trigger: FormatTrigger,
 1585        logger: zlog::Logger,
 1586        cx: &mut AsyncApp,
 1587    ) -> Result<()> {
 1588        let (adapters_and_servers, settings, request_timeout) =
 1589            lsp_store.update(cx, |lsp_store, cx| {
 1590                buffer.handle.update(cx, |buffer, cx| {
 1591                    let adapters_and_servers = lsp_store
 1592                        .as_local()
 1593                        .unwrap()
 1594                        .language_servers_for_buffer(buffer, cx)
 1595                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1596                        .collect::<Vec<_>>();
 1597                    let settings = LanguageSettings::for_buffer(buffer, cx).into_owned();
 1598                    let request_timeout = ProjectSettings::get_global(cx)
 1599                        .global_lsp_settings
 1600                        .get_request_timeout();
 1601                    (adapters_and_servers, settings, request_timeout)
 1602                })
 1603            })?;
 1604
 1605        // handle whitespace formatting
 1606        if settings.remove_trailing_whitespace_on_save {
 1607            zlog::trace!(logger => "removing trailing whitespace");
 1608            let diff = buffer
 1609                .handle
 1610                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1611                .await;
 1612            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1613                buffer.apply_diff(diff, cx);
 1614            })?;
 1615        }
 1616
 1617        if settings.ensure_final_newline_on_save {
 1618            zlog::trace!(logger => "ensuring final newline");
 1619            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1620                buffer.ensure_final_newline(cx);
 1621            })?;
 1622        }
 1623
 1624        // Formatter for `code_actions_on_format` that runs before
 1625        // the rest of the formatters
 1626        let mut code_actions_on_format_formatters = None;
 1627        let should_run_code_actions_on_format = !matches!(
 1628            (trigger, &settings.format_on_save),
 1629            (FormatTrigger::Save, &FormatOnSave::Off)
 1630        );
 1631        if should_run_code_actions_on_format {
 1632            let have_code_actions_to_run_on_format = settings
 1633                .code_actions_on_format
 1634                .values()
 1635                .any(|enabled| *enabled);
 1636            if have_code_actions_to_run_on_format {
 1637                zlog::trace!(logger => "going to run code actions on format");
 1638                code_actions_on_format_formatters = Some(
 1639                    settings
 1640                        .code_actions_on_format
 1641                        .iter()
 1642                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1643                        .cloned()
 1644                        .map(Formatter::CodeAction)
 1645                        .collect::<Vec<_>>(),
 1646                );
 1647            }
 1648        }
 1649
 1650        let formatters = match (trigger, &settings.format_on_save) {
 1651            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1652            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1653                settings.formatter.as_ref()
 1654            }
 1655        };
 1656
 1657        let formatters = code_actions_on_format_formatters
 1658            .iter()
 1659            .flatten()
 1660            .chain(formatters);
 1661
 1662        for formatter in formatters {
 1663            let formatter = if formatter == &Formatter::Auto {
 1664                if settings.prettier.allowed {
 1665                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1666                    &Formatter::Prettier
 1667                } else {
 1668                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1669                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1670                }
 1671            } else {
 1672                formatter
 1673            };
 1674            if let Err(err) = Self::apply_formatter(
 1675                formatter,
 1676                &lsp_store,
 1677                buffer,
 1678                formatting_transaction_id,
 1679                &adapters_and_servers,
 1680                &settings,
 1681                request_timeout,
 1682                logger,
 1683                cx,
 1684            )
 1685            .await
 1686            {
 1687                zlog::error!(logger => "Formatter failed, skipping: {err:#}");
 1688            }
 1689        }
 1690
 1691        Ok(())
 1692    }
 1693
 1694    async fn apply_formatter(
 1695        formatter: &Formatter,
 1696        lsp_store: &WeakEntity<LspStore>,
 1697        buffer: &FormattableBuffer,
 1698        formatting_transaction_id: clock::Lamport,
 1699        adapters_and_servers: &[(Arc<CachedLspAdapter>, Arc<LanguageServer>)],
 1700        settings: &LanguageSettings,
 1701        request_timeout: Duration,
 1702        logger: zlog::Logger,
 1703        cx: &mut AsyncApp,
 1704    ) -> anyhow::Result<()> {
 1705        match formatter {
 1706            Formatter::None => {
 1707                zlog::trace!(logger => "skipping formatter 'none'");
 1708                return Ok(());
 1709            }
 1710            Formatter::Auto => {
 1711                debug_panic!("Auto resolved above");
 1712                return Ok(());
 1713            }
 1714            Formatter::Prettier => {
 1715                let logger = zlog::scoped!(logger => "prettier");
 1716                zlog::trace!(logger => "formatting");
 1717                let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1718
 1719                // When selection ranges are provided (via FormatSelections), we pass the
 1720                // encompassing UTF-16 range to Prettier so it can scope its formatting.
 1721                // After diffing, we filter the resulting edits to only keep those that
 1722                // overlap with the original byte-level selection ranges.
 1723                let (range_utf16, byte_ranges) = match buffer.ranges.as_ref() {
 1724                    Some(ranges) if !ranges.is_empty() => {
 1725                        let (utf16_range, byte_ranges) =
 1726                            buffer.handle.read_with(cx, |buffer, _cx| {
 1727                                let snapshot = buffer.snapshot();
 1728                                let mut min_start_utf16 = OffsetUtf16(usize::MAX);
 1729                                let mut max_end_utf16 = OffsetUtf16(0);
 1730                                let mut byte_ranges = Vec::with_capacity(ranges.len());
 1731                                for range in ranges {
 1732                                    let start_utf16 = range.start.to_offset_utf16(&snapshot);
 1733                                    let end_utf16 = range.end.to_offset_utf16(&snapshot);
 1734                                    min_start_utf16.0 = min_start_utf16.0.min(start_utf16.0);
 1735                                    max_end_utf16.0 = max_end_utf16.0.max(end_utf16.0);
 1736
 1737                                    let start_byte = range.start.to_offset(&snapshot);
 1738                                    let end_byte = range.end.to_offset(&snapshot);
 1739                                    byte_ranges.push(start_byte..end_byte);
 1740                                }
 1741                                (min_start_utf16..max_end_utf16, byte_ranges)
 1742                            });
 1743                        (Some(utf16_range), Some(byte_ranges))
 1744                    }
 1745                    _ => (None, None),
 1746                };
 1747
 1748                let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1749                    lsp_store.prettier_store().unwrap().downgrade()
 1750                })?;
 1751                let diff = prettier_store::format_with_prettier(
 1752                    &prettier,
 1753                    &buffer.handle,
 1754                    range_utf16,
 1755                    cx,
 1756                )
 1757                .await
 1758                .transpose()?;
 1759                let Some(mut diff) = diff else {
 1760                    zlog::trace!(logger => "No changes");
 1761                    return Ok(());
 1762                };
 1763
 1764                if let Some(byte_ranges) = byte_ranges {
 1765                    diff.edits.retain(|(edit_range, _)| {
 1766                        byte_ranges.iter().any(|selection_range| {
 1767                            edit_range.start < selection_range.end
 1768                                && edit_range.end > selection_range.start
 1769                        })
 1770                    });
 1771                    if diff.edits.is_empty() {
 1772                        zlog::trace!(logger => "No changes within selection");
 1773                        return Ok(());
 1774                    }
 1775                }
 1776
 1777                extend_formatting_transaction(
 1778                    buffer,
 1779                    formatting_transaction_id,
 1780                    cx,
 1781                    |buffer, cx| {
 1782                        buffer.apply_diff(diff, cx);
 1783                    },
 1784                )?;
 1785            }
 1786            Formatter::External { command, arguments } => {
 1787                let logger = zlog::scoped!(logger => "command");
 1788
 1789                if buffer.ranges.is_some() {
 1790                    zlog::debug!(logger => "External formatter does not support range formatting; skipping");
 1791                    return Ok(());
 1792                }
 1793
 1794                zlog::trace!(logger => "formatting");
 1795                let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1796
 1797                let diff =
 1798                    Self::format_via_external_command(buffer, &command, arguments.as_deref(), cx)
 1799                        .await
 1800                        .with_context(|| {
 1801                            format!("Failed to format buffer via external command: {}", command)
 1802                        })?;
 1803                let Some(diff) = diff else {
 1804                    zlog::trace!(logger => "No changes");
 1805                    return Ok(());
 1806                };
 1807
 1808                extend_formatting_transaction(
 1809                    buffer,
 1810                    formatting_transaction_id,
 1811                    cx,
 1812                    |buffer, cx| {
 1813                        buffer.apply_diff(diff, cx);
 1814                    },
 1815                )?;
 1816            }
 1817            Formatter::LanguageServer(specifier) => {
 1818                let logger = zlog::scoped!(logger => "language-server");
 1819                zlog::trace!(logger => "formatting");
 1820                let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1821
 1822                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1823                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1824                    return Ok(());
 1825                };
 1826
 1827                let language_server = match specifier {
 1828                    settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1829                        adapters_and_servers.iter().find_map(|(adapter, server)| {
 1830                            if adapter.name.0.as_ref() == name {
 1831                                Some(server.clone())
 1832                            } else {
 1833                                None
 1834                            }
 1835                        })
 1836                    }
 1837                    settings::LanguageServerFormatterSpecifier::Current => adapters_and_servers
 1838                        .iter()
 1839                        .find(|(_, server)| Self::server_supports_formatting(server))
 1840                        .map(|(_, server)| server.clone()),
 1841                };
 1842
 1843                let Some(language_server) = language_server else {
 1844                    log::debug!(
 1845                        "No language server found to format buffer '{:?}'. Skipping",
 1846                        buffer_path_abs.as_path().to_string_lossy()
 1847                    );
 1848                    return Ok(());
 1849                };
 1850
 1851                zlog::trace!(
 1852                    logger =>
 1853                    "Formatting buffer '{:?}' using language server '{:?}'",
 1854                    buffer_path_abs.as_path().to_string_lossy(),
 1855                    language_server.name()
 1856                );
 1857
 1858                let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1859                    zlog::trace!(logger => "formatting ranges");
 1860                    Self::format_ranges_via_lsp(
 1861                        &lsp_store,
 1862                        &buffer.handle,
 1863                        ranges,
 1864                        buffer_path_abs,
 1865                        &language_server,
 1866                        &settings,
 1867                        cx,
 1868                    )
 1869                    .await
 1870                    .context("Failed to format ranges via language server")?
 1871                } else {
 1872                    zlog::trace!(logger => "formatting full");
 1873                    Self::format_via_lsp(
 1874                        &lsp_store,
 1875                        &buffer.handle,
 1876                        buffer_path_abs,
 1877                        &language_server,
 1878                        &settings,
 1879                        cx,
 1880                    )
 1881                    .await
 1882                    .context("failed to format via language server")?
 1883                };
 1884
 1885                if edits.is_empty() {
 1886                    zlog::trace!(logger => "No changes");
 1887                    return Ok(());
 1888                }
 1889                extend_formatting_transaction(
 1890                    buffer,
 1891                    formatting_transaction_id,
 1892                    cx,
 1893                    |buffer, cx| {
 1894                        buffer.edit(edits, None, cx);
 1895                    },
 1896                )?;
 1897            }
 1898            Formatter::CodeAction(code_action_name) => {
 1899                let logger = zlog::scoped!(logger => "code-actions");
 1900                zlog::trace!(logger => "formatting");
 1901                let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1902
 1903                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1904                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1905                    return Ok(());
 1906                };
 1907
 1908                let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1909                zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1910
 1911                let mut actions_and_servers = Vec::new();
 1912
 1913                for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1914                    let actions_result = Self::get_server_code_actions_from_action_kinds(
 1915                        &lsp_store,
 1916                        language_server.server_id(),
 1917                        vec![code_action_kind.clone()],
 1918                        &buffer.handle,
 1919                        cx,
 1920                    )
 1921                    .await
 1922                    .with_context(|| {
 1923                        format!(
 1924                            "Failed to resolve code action {:?} with language server {}",
 1925                            code_action_kind,
 1926                            language_server.name()
 1927                        )
 1928                    });
 1929                    let Ok(actions) = actions_result else {
 1930                        // note: it may be better to set result to the error and break formatters here
 1931                        // but for now we try to execute the actions that we can resolve and skip the rest
 1932                        zlog::error!(
 1933                            logger =>
 1934                            "Failed to resolve code action {:?} with language server {}",
 1935                            code_action_kind,
 1936                            language_server.name()
 1937                        );
 1938                        continue;
 1939                    };
 1940                    for action in actions {
 1941                        actions_and_servers.push((action, index));
 1942                    }
 1943                }
 1944
 1945                if actions_and_servers.is_empty() {
 1946                    zlog::warn!(logger => "No code actions were resolved, continuing");
 1947                    return Ok(());
 1948                }
 1949
 1950                'actions: for (mut action, server_index) in actions_and_servers {
 1951                    let server = &adapters_and_servers[server_index].1;
 1952
 1953                    let describe_code_action = |action: &CodeAction| {
 1954                        format!(
 1955                            "code action '{}' with title \"{}\" on server {}",
 1956                            action
 1957                                .lsp_action
 1958                                .action_kind()
 1959                                .unwrap_or("unknown".into())
 1960                                .as_str(),
 1961                            action.lsp_action.title(),
 1962                            server.name(),
 1963                        )
 1964                    };
 1965
 1966                    zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1967
 1968                    if let Err(err) =
 1969                        Self::try_resolve_code_action(server, &mut action, request_timeout).await
 1970                    {
 1971                        zlog::error!(
 1972                            logger =>
 1973                            "Failed to resolve {}. Error: {}",
 1974                            describe_code_action(&action),
 1975                            err
 1976                        );
 1977                        continue;
 1978                    }
 1979
 1980                    if let Some(edit) = action.lsp_action.edit().cloned() {
 1981                        // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1982                        // but filters out and logs warnings for code actions that require unreasonably
 1983                        // difficult handling on our part, such as:
 1984                        // - applying edits that call commands
 1985                        //   which can result in arbitrary workspace edits being sent from the server that
 1986                        //   have no way of being tied back to the command that initiated them (i.e. we
 1987                        //   can't know which edits are part of the format request, or if the server is done sending
 1988                        //   actions in response to the command)
 1989                        // - actions that create/delete/modify/rename files other than the one we are formatting
 1990                        //   as we then would need to handle such changes correctly in the local history as well
 1991                        //   as the remote history through the ProjectTransaction
 1992                        // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1993                        // Supporting these actions is not impossible, but not supported as of yet.
 1994                        if edit.changes.is_none() && edit.document_changes.is_none() {
 1995                            zlog::trace!(
 1996                                logger =>
 1997                                "No changes for code action. Skipping {}",
 1998                                describe_code_action(&action),
 1999                            );
 2000                            continue;
 2001                        }
 2002
 2003                        let mut operations = Vec::new();
 2004                        if let Some(document_changes) = edit.document_changes {
 2005                            match document_changes {
 2006                                lsp::DocumentChanges::Edits(edits) => operations.extend(
 2007                                    edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 2008                                ),
 2009                                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2010                            }
 2011                        } else if let Some(changes) = edit.changes {
 2012                            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2013                                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2014                                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2015                                        uri,
 2016                                        version: None,
 2017                                    },
 2018                                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2019                                })
 2020                            }));
 2021                        }
 2022
 2023                        let mut edits = Vec::with_capacity(operations.len());
 2024
 2025                        if operations.is_empty() {
 2026                            zlog::trace!(
 2027                                logger =>
 2028                                "No changes for code action. Skipping {}",
 2029                                describe_code_action(&action),
 2030                            );
 2031                            continue;
 2032                        }
 2033                        for operation in operations {
 2034                            let op = match operation {
 2035                                lsp::DocumentChangeOperation::Edit(op) => op,
 2036                                lsp::DocumentChangeOperation::Op(_) => {
 2037                                    zlog::warn!(
 2038                                        logger =>
 2039                                        "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 2040                                        describe_code_action(&action),
 2041                                    );
 2042                                    continue 'actions;
 2043                                }
 2044                            };
 2045                            let Ok(file_path) = op.text_document.uri.to_file_path() else {
 2046                                zlog::warn!(
 2047                                    logger =>
 2048                                    "Failed to convert URI '{:?}' to file path. Skipping {}",
 2049                                    &op.text_document.uri,
 2050                                    describe_code_action(&action),
 2051                                );
 2052                                continue 'actions;
 2053                            };
 2054                            if &file_path != buffer_path_abs {
 2055                                zlog::warn!(
 2056                                    logger =>
 2057                                    "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 2058                                    file_path,
 2059                                    buffer_path_abs,
 2060                                    describe_code_action(&action),
 2061                                );
 2062                                continue 'actions;
 2063                            }
 2064
 2065                            let mut lsp_edits = Vec::new();
 2066                            for edit in op.edits {
 2067                                match edit {
 2068                                    Edit::Plain(edit) => {
 2069                                        if !lsp_edits.contains(&edit) {
 2070                                            lsp_edits.push(edit);
 2071                                        }
 2072                                    }
 2073                                    Edit::Annotated(edit) => {
 2074                                        if !lsp_edits.contains(&edit.text_edit) {
 2075                                            lsp_edits.push(edit.text_edit);
 2076                                        }
 2077                                    }
 2078                                    Edit::Snippet(_) => {
 2079                                        zlog::warn!(
 2080                                            logger =>
 2081                                            "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 2082                                            describe_code_action(&action),
 2083                                        );
 2084                                        continue 'actions;
 2085                                    }
 2086                                }
 2087                            }
 2088                            let edits_result = lsp_store
 2089                                .update(cx, |lsp_store, cx| {
 2090                                    lsp_store.as_local_mut().unwrap().edits_from_lsp(
 2091                                        &buffer.handle,
 2092                                        lsp_edits,
 2093                                        server.server_id(),
 2094                                        op.text_document.version,
 2095                                        cx,
 2096                                    )
 2097                                })?
 2098                                .await;
 2099                            let Ok(resolved_edits) = edits_result else {
 2100                                zlog::warn!(
 2101                                    logger =>
 2102                                    "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 2103                                    buffer_path_abs.as_path(),
 2104                                    describe_code_action(&action),
 2105                                );
 2106                                continue 'actions;
 2107                            };
 2108                            edits.extend(resolved_edits);
 2109                        }
 2110
 2111                        if edits.is_empty() {
 2112                            zlog::warn!(logger => "No edits resolved from LSP");
 2113                            continue;
 2114                        }
 2115
 2116                        extend_formatting_transaction(
 2117                            buffer,
 2118                            formatting_transaction_id,
 2119                            cx,
 2120                            |buffer, cx| {
 2121                                zlog::info!(
 2122                                    "Applying edits {edits:?}. Content: {:?}",
 2123                                    buffer.text()
 2124                                );
 2125                                buffer.edit(edits, None, cx);
 2126                                zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 2127                            },
 2128                        )?;
 2129                    }
 2130
 2131                    let Some(command) = action.lsp_action.command() else {
 2132                        continue;
 2133                    };
 2134
 2135                    zlog::warn!(
 2136                        logger =>
 2137                        "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 2138                        &command.command,
 2139                    );
 2140
 2141                    let server_capabilities = server.capabilities();
 2142                    let available_commands = server_capabilities
 2143                        .execute_command_provider
 2144                        .as_ref()
 2145                        .map(|options| options.commands.as_slice())
 2146                        .unwrap_or_default();
 2147                    if !available_commands.contains(&command.command) {
 2148                        zlog::warn!(
 2149                            logger =>
 2150                            "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2151                            command.command,
 2152                            server.name(),
 2153                        );
 2154                        continue;
 2155                    }
 2156
 2157                    extend_formatting_transaction(
 2158                        buffer,
 2159                        formatting_transaction_id,
 2160                        cx,
 2161                        |_, _| {},
 2162                    )?;
 2163                    zlog::info!(logger => "Executing command {}", &command.command);
 2164
 2165                    lsp_store.update(cx, |this, _| {
 2166                        this.as_local_mut()
 2167                            .unwrap()
 2168                            .last_workspace_edits_by_language_server
 2169                            .remove(&server.server_id());
 2170                    })?;
 2171
 2172                    let execute_command_result = server
 2173                        .request::<lsp::request::ExecuteCommand>(
 2174                            lsp::ExecuteCommandParams {
 2175                                command: command.command.clone(),
 2176                                arguments: command.arguments.clone().unwrap_or_default(),
 2177                                ..Default::default()
 2178                            },
 2179                            request_timeout,
 2180                        )
 2181                        .await
 2182                        .into_response();
 2183
 2184                    if execute_command_result.is_err() {
 2185                        zlog::error!(
 2186                            logger =>
 2187                            "Failed to execute command '{}' as part of {}",
 2188                            &command.command,
 2189                            describe_code_action(&action),
 2190                        );
 2191                        continue 'actions;
 2192                    }
 2193
 2194                    let mut project_transaction_command = lsp_store.update(cx, |this, _| {
 2195                        this.as_local_mut()
 2196                            .unwrap()
 2197                            .last_workspace_edits_by_language_server
 2198                            .remove(&server.server_id())
 2199                            .unwrap_or_default()
 2200                    })?;
 2201
 2202                    if let Some(transaction) = project_transaction_command.0.remove(&buffer.handle)
 2203                    {
 2204                        zlog::trace!(
 2205                            logger =>
 2206                            "Successfully captured {} edits that resulted from command {}",
 2207                            transaction.edit_ids.len(),
 2208                            &command.command,
 2209                        );
 2210                        let transaction_id_project_transaction = transaction.id;
 2211                        buffer.handle.update(cx, |buffer, _| {
 2212                            // it may have been removed from history if push_to_history was
 2213                            // false in deserialize_workspace_edit. If so push it so we
 2214                            // can merge it with the format transaction
 2215                            // and pop the combined transaction off the history stack
 2216                            // later if push_to_history is false
 2217                            if buffer.get_transaction(transaction.id).is_none() {
 2218                                buffer.push_transaction(transaction, Instant::now());
 2219                            }
 2220                            buffer.merge_transactions(
 2221                                transaction_id_project_transaction,
 2222                                formatting_transaction_id,
 2223                            );
 2224                        });
 2225                    }
 2226
 2227                    if project_transaction_command.0.is_empty() {
 2228                        continue;
 2229                    }
 2230
 2231                    let mut extra_buffers = String::new();
 2232                    for buffer in project_transaction_command.0.keys() {
 2233                        buffer.read_with(cx, |b, cx| {
 2234                            let Some(path) = b.project_path(cx) else {
 2235                                return;
 2236                            };
 2237
 2238                            if !extra_buffers.is_empty() {
 2239                                extra_buffers.push_str(", ");
 2240                            }
 2241                            extra_buffers.push_str(path.path.as_unix_str());
 2242                        });
 2243                    }
 2244                    zlog::warn!(
 2245                        logger =>
 2246                        "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2247                        &command.command,
 2248                        extra_buffers,
 2249                    );
 2250                    // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2251                    // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2252                    // add it so it's included, and merge it into the format transaction when its created later
 2253                }
 2254            }
 2255        }
 2256
 2257        Ok(())
 2258    }
 2259
 2260    pub async fn format_ranges_via_lsp(
 2261        this: &WeakEntity<LspStore>,
 2262        buffer_handle: &Entity<Buffer>,
 2263        ranges: &[Range<Anchor>],
 2264        abs_path: &Path,
 2265        language_server: &Arc<LanguageServer>,
 2266        settings: &LanguageSettings,
 2267        cx: &mut AsyncApp,
 2268    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2269        let capabilities = &language_server.capabilities();
 2270        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2271        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2272            anyhow::bail!(
 2273                "{} language server does not support range formatting",
 2274                language_server.name()
 2275            );
 2276        }
 2277
 2278        let uri = file_path_to_lsp_url(abs_path)?;
 2279        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2280
 2281        let request_timeout = cx.update(|app| {
 2282            ProjectSettings::get_global(app)
 2283                .global_lsp_settings
 2284                .get_request_timeout()
 2285        });
 2286        let lsp_edits = {
 2287            let mut lsp_ranges = Vec::new();
 2288            this.update(cx, |_this, cx| {
 2289                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2290                // not have been sent to the language server. This seems like a fairly systemic
 2291                // issue, though, the resolution probably is not specific to formatting.
 2292                //
 2293                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2294                // LSP.
 2295                let snapshot = buffer_handle.read(cx).snapshot();
 2296                for range in ranges {
 2297                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2298                }
 2299                anyhow::Ok(())
 2300            })??;
 2301
 2302            let mut edits = None;
 2303            for range in lsp_ranges {
 2304                if let Some(mut edit) = language_server
 2305                    .request::<lsp::request::RangeFormatting>(
 2306                        lsp::DocumentRangeFormattingParams {
 2307                            text_document: text_document.clone(),
 2308                            range,
 2309                            options: lsp_command::lsp_formatting_options(settings),
 2310                            work_done_progress_params: Default::default(),
 2311                        },
 2312                        request_timeout,
 2313                    )
 2314                    .await
 2315                    .into_response()?
 2316                {
 2317                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2318                }
 2319            }
 2320            edits
 2321        };
 2322
 2323        if let Some(lsp_edits) = lsp_edits {
 2324            this.update(cx, |this, cx| {
 2325                this.as_local_mut().unwrap().edits_from_lsp(
 2326                    buffer_handle,
 2327                    lsp_edits,
 2328                    language_server.server_id(),
 2329                    None,
 2330                    cx,
 2331                )
 2332            })?
 2333            .await
 2334        } else {
 2335            Ok(Vec::with_capacity(0))
 2336        }
 2337    }
 2338
 2339    fn server_supports_formatting(server: &Arc<LanguageServer>) -> bool {
 2340        let capabilities = server.capabilities();
 2341        let formatting = capabilities.document_formatting_provider.as_ref();
 2342        let range_formatting = capabilities.document_range_formatting_provider.as_ref();
 2343        matches!(formatting, Some(p) if *p != OneOf::Left(false))
 2344            || matches!(range_formatting, Some(p) if *p != OneOf::Left(false))
 2345    }
 2346
 2347    async fn format_via_lsp(
 2348        this: &WeakEntity<LspStore>,
 2349        buffer: &Entity<Buffer>,
 2350        abs_path: &Path,
 2351        language_server: &Arc<LanguageServer>,
 2352        settings: &LanguageSettings,
 2353        cx: &mut AsyncApp,
 2354    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2355        let logger = zlog::scoped!("lsp_format");
 2356        zlog::debug!(logger => "Formatting via LSP");
 2357
 2358        let uri = file_path_to_lsp_url(abs_path)?;
 2359        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2360        let capabilities = &language_server.capabilities();
 2361
 2362        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2363        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2364
 2365        let request_timeout = cx.update(|app| {
 2366            ProjectSettings::get_global(app)
 2367                .global_lsp_settings
 2368                .get_request_timeout()
 2369        });
 2370
 2371        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2372            let _timer = zlog::time!(logger => "format-full");
 2373            language_server
 2374                .request::<lsp::request::Formatting>(
 2375                    lsp::DocumentFormattingParams {
 2376                        text_document,
 2377                        options: lsp_command::lsp_formatting_options(settings),
 2378                        work_done_progress_params: Default::default(),
 2379                    },
 2380                    request_timeout,
 2381                )
 2382                .await
 2383                .into_response()?
 2384        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2385            let _timer = zlog::time!(logger => "format-range");
 2386            let buffer_start = lsp::Position::new(0, 0);
 2387            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2388            language_server
 2389                .request::<lsp::request::RangeFormatting>(
 2390                    lsp::DocumentRangeFormattingParams {
 2391                        text_document: text_document.clone(),
 2392                        range: lsp::Range::new(buffer_start, buffer_end),
 2393                        options: lsp_command::lsp_formatting_options(settings),
 2394                        work_done_progress_params: Default::default(),
 2395                    },
 2396                    request_timeout,
 2397                )
 2398                .await
 2399                .into_response()?
 2400        } else {
 2401            None
 2402        };
 2403
 2404        if let Some(lsp_edits) = lsp_edits {
 2405            this.update(cx, |this, cx| {
 2406                this.as_local_mut().unwrap().edits_from_lsp(
 2407                    buffer,
 2408                    lsp_edits,
 2409                    language_server.server_id(),
 2410                    None,
 2411                    cx,
 2412                )
 2413            })?
 2414            .await
 2415        } else {
 2416            Ok(Vec::with_capacity(0))
 2417        }
 2418    }
 2419
 2420    async fn format_via_external_command(
 2421        buffer: &FormattableBuffer,
 2422        command: &str,
 2423        arguments: Option<&[String]>,
 2424        cx: &mut AsyncApp,
 2425    ) -> Result<Option<Diff>> {
 2426        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2427            let file = File::from_dyn(buffer.file())?;
 2428            let worktree = file.worktree.read(cx);
 2429            let mut worktree_path = worktree.abs_path().to_path_buf();
 2430            if worktree.root_entry()?.is_file() {
 2431                worktree_path.pop();
 2432            }
 2433            Some(worktree_path)
 2434        });
 2435
 2436        use util::command::Stdio;
 2437        let mut child = util::command::new_command(command);
 2438
 2439        if let Some(buffer_env) = buffer.env.as_ref() {
 2440            child.envs(buffer_env);
 2441        }
 2442
 2443        if let Some(working_dir_path) = working_dir_path {
 2444            child.current_dir(working_dir_path);
 2445        }
 2446
 2447        if let Some(arguments) = arguments {
 2448            child.args(arguments.iter().map(|arg| {
 2449                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2450                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2451                } else {
 2452                    arg.replace("{buffer_path}", "Untitled")
 2453                }
 2454            }));
 2455        }
 2456
 2457        let mut child = child
 2458            .stdin(Stdio::piped())
 2459            .stdout(Stdio::piped())
 2460            .stderr(Stdio::piped())
 2461            .spawn()?;
 2462
 2463        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2464        let text = buffer
 2465            .handle
 2466            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2467        for chunk in text.chunks() {
 2468            stdin.write_all(chunk.as_bytes()).await?;
 2469        }
 2470        stdin.flush().await?;
 2471
 2472        let output = child.output().await?;
 2473        anyhow::ensure!(
 2474            output.status.success(),
 2475            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2476            output.status.code(),
 2477            String::from_utf8_lossy(&output.stdout),
 2478            String::from_utf8_lossy(&output.stderr),
 2479        );
 2480
 2481        let stdout = String::from_utf8(output.stdout)?;
 2482        Ok(Some(
 2483            buffer
 2484                .handle
 2485                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2486                .await,
 2487        ))
 2488    }
 2489
 2490    async fn try_resolve_code_action(
 2491        lang_server: &LanguageServer,
 2492        action: &mut CodeAction,
 2493        request_timeout: Duration,
 2494    ) -> anyhow::Result<()> {
 2495        match &mut action.lsp_action {
 2496            LspAction::Action(lsp_action) => {
 2497                if !action.resolved
 2498                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2499                    && lsp_action.data.is_some()
 2500                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2501                {
 2502                    **lsp_action = lang_server
 2503                        .request::<lsp::request::CodeActionResolveRequest>(
 2504                            *lsp_action.clone(),
 2505                            request_timeout,
 2506                        )
 2507                        .await
 2508                        .into_response()?;
 2509                }
 2510            }
 2511            LspAction::CodeLens(lens) => {
 2512                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2513                    *lens = lang_server
 2514                        .request::<lsp::request::CodeLensResolve>(lens.clone(), request_timeout)
 2515                        .await
 2516                        .into_response()?;
 2517                }
 2518            }
 2519            LspAction::Command(_) => {}
 2520        }
 2521
 2522        action.resolved = true;
 2523        anyhow::Ok(())
 2524    }
 2525
 2526    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2527        let buffer = buffer_handle.read(cx);
 2528
 2529        let file = buffer.file().cloned();
 2530
 2531        let Some(file) = File::from_dyn(file.as_ref()) else {
 2532            return;
 2533        };
 2534        if !file.is_local() {
 2535            return;
 2536        }
 2537        let path = ProjectPath::from_file(file, cx);
 2538        let worktree_id = file.worktree_id(cx);
 2539        let language = buffer.language().cloned();
 2540
 2541        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2542            for (server_id, diagnostics) in
 2543                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2544            {
 2545                self.update_buffer_diagnostics(
 2546                    buffer_handle,
 2547                    server_id,
 2548                    None,
 2549                    None,
 2550                    None,
 2551                    Vec::new(),
 2552                    diagnostics,
 2553                    cx,
 2554                )
 2555                .log_err();
 2556            }
 2557        }
 2558        let Some(language) = language else {
 2559            return;
 2560        };
 2561        let Some(snapshot) = self
 2562            .worktree_store
 2563            .read(cx)
 2564            .worktree_for_id(worktree_id, cx)
 2565            .map(|worktree| worktree.read(cx).snapshot())
 2566        else {
 2567            return;
 2568        };
 2569        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2570
 2571        for server_id in
 2572            self.lsp_tree
 2573                .get(path, language.name(), language.manifest(), &delegate, cx)
 2574        {
 2575            let server = self
 2576                .language_servers
 2577                .get(&server_id)
 2578                .and_then(|server_state| {
 2579                    if let LanguageServerState::Running { server, .. } = server_state {
 2580                        Some(server.clone())
 2581                    } else {
 2582                        None
 2583                    }
 2584                });
 2585            let server = match server {
 2586                Some(server) => server,
 2587                None => continue,
 2588            };
 2589
 2590            buffer_handle.update(cx, |buffer, cx| {
 2591                buffer.set_completion_triggers(
 2592                    server.server_id(),
 2593                    server
 2594                        .capabilities()
 2595                        .completion_provider
 2596                        .as_ref()
 2597                        .and_then(|provider| {
 2598                            provider
 2599                                .trigger_characters
 2600                                .as_ref()
 2601                                .map(|characters| characters.iter().cloned().collect())
 2602                        })
 2603                        .unwrap_or_default(),
 2604                    cx,
 2605                );
 2606            });
 2607        }
 2608    }
 2609
 2610    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2611        buffer.update(cx, |buffer, cx| {
 2612            let Some(language) = buffer.language() else {
 2613                return;
 2614            };
 2615            let path = ProjectPath {
 2616                worktree_id: old_file.worktree_id(cx),
 2617                path: old_file.path.clone(),
 2618            };
 2619            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2620                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2621                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2622            }
 2623        });
 2624    }
 2625
 2626    fn update_buffer_diagnostics(
 2627        &mut self,
 2628        buffer: &Entity<Buffer>,
 2629        server_id: LanguageServerId,
 2630        registration_id: Option<Option<SharedString>>,
 2631        result_id: Option<SharedString>,
 2632        version: Option<i32>,
 2633        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2634        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2635        cx: &mut Context<LspStore>,
 2636    ) -> Result<()> {
 2637        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2638            Ordering::Equal
 2639                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2640                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2641                .then_with(|| a.severity.cmp(&b.severity))
 2642                .then_with(|| a.message.cmp(&b.message))
 2643        }
 2644
 2645        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2646        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2647        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2648
 2649        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2650            Ordering::Equal
 2651                .then_with(|| a.range.start.cmp(&b.range.start))
 2652                .then_with(|| b.range.end.cmp(&a.range.end))
 2653                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2654        });
 2655
 2656        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2657
 2658        let edits_since_save = std::cell::LazyCell::new(|| {
 2659            let saved_version = buffer.read(cx).saved_version();
 2660            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2661        });
 2662
 2663        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2664
 2665        for (new_diagnostic, entry) in diagnostics {
 2666            let start;
 2667            let end;
 2668            if new_diagnostic && entry.diagnostic.is_disk_based {
 2669                // Some diagnostics are based on files on disk instead of buffers'
 2670                // current contents. Adjust these diagnostics' ranges to reflect
 2671                // any unsaved edits.
 2672                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2673                // and were properly adjusted on reuse.
 2674                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2675                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2676            } else {
 2677                start = entry.range.start;
 2678                end = entry.range.end;
 2679            }
 2680
 2681            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2682                ..snapshot.clip_point_utf16(end, Bias::Right);
 2683
 2684            // Expand empty ranges by one codepoint
 2685            if range.start == range.end {
 2686                // This will be go to the next boundary when being clipped
 2687                range.end.column += 1;
 2688                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2689                if range.start == range.end && range.end.column > 0 {
 2690                    range.start.column -= 1;
 2691                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2692                }
 2693            }
 2694
 2695            sanitized_diagnostics.push(DiagnosticEntry {
 2696                range,
 2697                diagnostic: entry.diagnostic,
 2698            });
 2699        }
 2700        drop(edits_since_save);
 2701
 2702        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2703        buffer.update(cx, |buffer, cx| {
 2704            if let Some(registration_id) = registration_id {
 2705                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2706                    self.buffer_pull_diagnostics_result_ids
 2707                        .entry(server_id)
 2708                        .or_default()
 2709                        .entry(registration_id)
 2710                        .or_default()
 2711                        .insert(abs_path, result_id);
 2712                }
 2713            }
 2714
 2715            buffer.update_diagnostics(server_id, set, cx)
 2716        });
 2717
 2718        Ok(())
 2719    }
 2720
 2721    fn register_language_server_for_invisible_worktree(
 2722        &mut self,
 2723        worktree: &Entity<Worktree>,
 2724        language_server_id: LanguageServerId,
 2725        cx: &mut App,
 2726    ) {
 2727        let worktree = worktree.read(cx);
 2728        let worktree_id = worktree.id();
 2729        debug_assert!(!worktree.is_visible());
 2730        let Some(mut origin_seed) = self
 2731            .language_server_ids
 2732            .iter()
 2733            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2734        else {
 2735            return;
 2736        };
 2737        origin_seed.worktree_id = worktree_id;
 2738        self.language_server_ids
 2739            .entry(origin_seed)
 2740            .or_insert_with(|| UnifiedLanguageServer {
 2741                id: language_server_id,
 2742                project_roots: Default::default(),
 2743            });
 2744    }
 2745
 2746    fn register_buffer_with_language_servers(
 2747        &mut self,
 2748        buffer_handle: &Entity<Buffer>,
 2749        only_register_servers: HashSet<LanguageServerSelector>,
 2750        cx: &mut Context<LspStore>,
 2751    ) {
 2752        let buffer = buffer_handle.read(cx);
 2753        let buffer_id = buffer.remote_id();
 2754
 2755        let Some(file) = File::from_dyn(buffer.file()) else {
 2756            return;
 2757        };
 2758        if !file.is_local() {
 2759            return;
 2760        }
 2761
 2762        let abs_path = file.abs_path(cx);
 2763        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2764            return;
 2765        };
 2766        let initial_snapshot = buffer.text_snapshot();
 2767        let worktree_id = file.worktree_id(cx);
 2768
 2769        let Some(language) = buffer.language().cloned() else {
 2770            return;
 2771        };
 2772        let path: Arc<RelPath> = file
 2773            .path()
 2774            .parent()
 2775            .map(Arc::from)
 2776            .unwrap_or_else(|| file.path().clone());
 2777        let Some(worktree) = self
 2778            .worktree_store
 2779            .read(cx)
 2780            .worktree_for_id(worktree_id, cx)
 2781        else {
 2782            return;
 2783        };
 2784        let language_name = language.name();
 2785        let (reused, delegate, servers) = self
 2786            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2787            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2788            .unwrap_or_else(|| {
 2789                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2790                let delegate: Arc<dyn ManifestDelegate> =
 2791                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2792
 2793                let servers = self
 2794                    .lsp_tree
 2795                    .walk(
 2796                        ProjectPath { worktree_id, path },
 2797                        language.name(),
 2798                        language.manifest(),
 2799                        &delegate,
 2800                        cx,
 2801                    )
 2802                    .collect::<Vec<_>>();
 2803                (false, lsp_delegate, servers)
 2804            });
 2805        let servers_and_adapters = servers
 2806            .into_iter()
 2807            .filter_map(|server_node| {
 2808                if reused && server_node.server_id().is_none() {
 2809                    return None;
 2810                }
 2811                if !only_register_servers.is_empty() {
 2812                    if let Some(server_id) = server_node.server_id()
 2813                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2814                    {
 2815                        return None;
 2816                    }
 2817                    if let Some(name) = server_node.name()
 2818                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2819                    {
 2820                        return None;
 2821                    }
 2822                }
 2823
 2824                let server_id = server_node.server_id_or_init(|disposition| {
 2825                    let path = &disposition.path;
 2826
 2827                    {
 2828                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2829
 2830                        let server_id = self.get_or_insert_language_server(
 2831                            &worktree,
 2832                            delegate.clone(),
 2833                            disposition,
 2834                            &language_name,
 2835                            cx,
 2836                        );
 2837
 2838                        if let Some(state) = self.language_servers.get(&server_id)
 2839                            && let Ok(uri) = uri
 2840                        {
 2841                            state.add_workspace_folder(uri);
 2842                        };
 2843                        server_id
 2844                    }
 2845                })?;
 2846                let server_state = self.language_servers.get(&server_id)?;
 2847                if let LanguageServerState::Running {
 2848                    server, adapter, ..
 2849                } = server_state
 2850                {
 2851                    Some((server.clone(), adapter.clone()))
 2852                } else {
 2853                    None
 2854                }
 2855            })
 2856            .collect::<Vec<_>>();
 2857        for (server, adapter) in servers_and_adapters {
 2858            buffer_handle.update(cx, |buffer, cx| {
 2859                buffer.set_completion_triggers(
 2860                    server.server_id(),
 2861                    server
 2862                        .capabilities()
 2863                        .completion_provider
 2864                        .as_ref()
 2865                        .and_then(|provider| {
 2866                            provider
 2867                                .trigger_characters
 2868                                .as_ref()
 2869                                .map(|characters| characters.iter().cloned().collect())
 2870                        })
 2871                        .unwrap_or_default(),
 2872                    cx,
 2873                );
 2874            });
 2875
 2876            let snapshot = LspBufferSnapshot {
 2877                version: 0,
 2878                snapshot: initial_snapshot.clone(),
 2879            };
 2880
 2881            let mut registered = false;
 2882            self.buffer_snapshots
 2883                .entry(buffer_id)
 2884                .or_default()
 2885                .entry(server.server_id())
 2886                .or_insert_with(|| {
 2887                    registered = true;
 2888                    server.register_buffer(
 2889                        uri.clone(),
 2890                        adapter.language_id(&language.name()),
 2891                        0,
 2892                        initial_snapshot.text(),
 2893                    );
 2894
 2895                    vec![snapshot]
 2896                });
 2897
 2898            self.buffers_opened_in_servers
 2899                .entry(buffer_id)
 2900                .or_default()
 2901                .insert(server.server_id());
 2902            if registered {
 2903                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2904                    language_server_id: server.server_id(),
 2905                    name: None,
 2906                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2907                        proto::RegisteredForBuffer {
 2908                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2909                            buffer_id: buffer_id.to_proto(),
 2910                        },
 2911                    ),
 2912                });
 2913            }
 2914        }
 2915    }
 2916
 2917    fn reuse_existing_language_server<'lang_name>(
 2918        &self,
 2919        server_tree: &LanguageServerTree,
 2920        worktree: &Entity<Worktree>,
 2921        language_name: &'lang_name LanguageName,
 2922        cx: &mut App,
 2923    ) -> Option<(
 2924        Arc<LocalLspAdapterDelegate>,
 2925        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2926    )> {
 2927        if worktree.read(cx).is_visible() {
 2928            return None;
 2929        }
 2930
 2931        let worktree_store = self.worktree_store.read(cx);
 2932        let servers = server_tree
 2933            .instances
 2934            .iter()
 2935            .filter(|(worktree_id, _)| {
 2936                worktree_store
 2937                    .worktree_for_id(**worktree_id, cx)
 2938                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2939            })
 2940            .flat_map(|(worktree_id, servers)| {
 2941                servers
 2942                    .roots
 2943                    .iter()
 2944                    .flat_map(|(_, language_servers)| language_servers)
 2945                    .map(move |(_, (server_node, server_languages))| {
 2946                        (worktree_id, server_node, server_languages)
 2947                    })
 2948                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2949                    .map(|(worktree_id, server_node, _)| {
 2950                        (
 2951                            *worktree_id,
 2952                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2953                        )
 2954                    })
 2955            })
 2956            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2957                acc.entry(worktree_id)
 2958                    .or_insert_with(Vec::new)
 2959                    .push(server_node);
 2960                acc
 2961            })
 2962            .into_values()
 2963            .max_by_key(|servers| servers.len())?;
 2964
 2965        let worktree_id = worktree.read(cx).id();
 2966        let apply = move |tree: &mut LanguageServerTree| {
 2967            for server_node in &servers {
 2968                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2969            }
 2970            servers
 2971        };
 2972
 2973        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2974        Some((delegate, apply))
 2975    }
 2976
 2977    pub(crate) fn unregister_old_buffer_from_language_servers(
 2978        &mut self,
 2979        buffer: &Entity<Buffer>,
 2980        old_file: &File,
 2981        cx: &mut App,
 2982    ) {
 2983        let old_path = match old_file.as_local() {
 2984            Some(local) => local.abs_path(cx),
 2985            None => return,
 2986        };
 2987
 2988        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2989            debug_panic!("{old_path:?} is not parseable as an URI");
 2990            return;
 2991        };
 2992        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2993    }
 2994
 2995    pub(crate) fn unregister_buffer_from_language_servers(
 2996        &mut self,
 2997        buffer: &Entity<Buffer>,
 2998        file_url: &lsp::Uri,
 2999        cx: &mut App,
 3000    ) {
 3001        buffer.update(cx, |buffer, cx| {
 3002            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 3003
 3004            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 3005                if snapshots
 3006                    .as_mut()
 3007                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 3008                {
 3009                    language_server.unregister_buffer(file_url.clone());
 3010                }
 3011            }
 3012        });
 3013    }
 3014
 3015    fn buffer_snapshot_for_lsp_version(
 3016        &mut self,
 3017        buffer: &Entity<Buffer>,
 3018        server_id: LanguageServerId,
 3019        version: Option<i32>,
 3020        cx: &App,
 3021    ) -> Result<TextBufferSnapshot> {
 3022        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 3023
 3024        if let Some(version) = version {
 3025            let buffer_id = buffer.read(cx).remote_id();
 3026            let snapshots = if let Some(snapshots) = self
 3027                .buffer_snapshots
 3028                .get_mut(&buffer_id)
 3029                .and_then(|m| m.get_mut(&server_id))
 3030            {
 3031                snapshots
 3032            } else if version == 0 {
 3033                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 3034                // We detect this case and treat it as if the version was `None`.
 3035                return Ok(buffer.read(cx).text_snapshot());
 3036            } else {
 3037                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 3038            };
 3039
 3040            let found_snapshot = snapshots
 3041                    .binary_search_by_key(&version, |e| e.version)
 3042                    .map(|ix| snapshots[ix].snapshot.clone())
 3043                    .map_err(|_| {
 3044                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 3045                    })?;
 3046
 3047            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 3048            Ok(found_snapshot)
 3049        } else {
 3050            Ok((buffer.read(cx)).text_snapshot())
 3051        }
 3052    }
 3053
 3054    async fn get_server_code_actions_from_action_kinds(
 3055        lsp_store: &WeakEntity<LspStore>,
 3056        language_server_id: LanguageServerId,
 3057        code_action_kinds: Vec<lsp::CodeActionKind>,
 3058        buffer: &Entity<Buffer>,
 3059        cx: &mut AsyncApp,
 3060    ) -> Result<Vec<CodeAction>> {
 3061        let actions = lsp_store
 3062            .update(cx, move |this, cx| {
 3063                let request = GetCodeActions {
 3064                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 3065                    kinds: Some(code_action_kinds),
 3066                };
 3067                let server = LanguageServerToQuery::Other(language_server_id);
 3068                this.request_lsp(buffer.clone(), server, request, cx)
 3069            })?
 3070            .await?;
 3071        Ok(actions)
 3072    }
 3073
 3074    pub async fn execute_code_actions_on_server(
 3075        lsp_store: &WeakEntity<LspStore>,
 3076        language_server: &Arc<LanguageServer>,
 3077        actions: Vec<CodeAction>,
 3078        push_to_history: bool,
 3079        project_transaction: &mut ProjectTransaction,
 3080        cx: &mut AsyncApp,
 3081    ) -> anyhow::Result<()> {
 3082        let request_timeout = cx.update(|app| {
 3083            ProjectSettings::get_global(app)
 3084                .global_lsp_settings
 3085                .get_request_timeout()
 3086        });
 3087
 3088        for mut action in actions {
 3089            Self::try_resolve_code_action(language_server, &mut action, request_timeout)
 3090                .await
 3091                .context("resolving a formatting code action")?;
 3092
 3093            if let Some(edit) = action.lsp_action.edit() {
 3094                if edit.changes.is_none() && edit.document_changes.is_none() {
 3095                    continue;
 3096                }
 3097
 3098                let new = Self::deserialize_workspace_edit(
 3099                    lsp_store.upgrade().context("project dropped")?,
 3100                    edit.clone(),
 3101                    push_to_history,
 3102                    language_server.clone(),
 3103                    cx,
 3104                )
 3105                .await?;
 3106                project_transaction.0.extend(new.0);
 3107            }
 3108
 3109            let Some(command) = action.lsp_action.command() else {
 3110                continue;
 3111            };
 3112
 3113            let server_capabilities = language_server.capabilities();
 3114            let available_commands = server_capabilities
 3115                .execute_command_provider
 3116                .as_ref()
 3117                .map(|options| options.commands.as_slice())
 3118                .unwrap_or_default();
 3119            if !available_commands.contains(&command.command) {
 3120                log::warn!(
 3121                    "Cannot execute a command {} not listed in the language server capabilities",
 3122                    command.command
 3123                );
 3124                continue;
 3125            }
 3126
 3127            lsp_store.update(cx, |lsp_store, _| {
 3128                if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 3129                    mode.last_workspace_edits_by_language_server
 3130                        .remove(&language_server.server_id());
 3131                }
 3132            })?;
 3133
 3134            language_server
 3135                .request::<lsp::request::ExecuteCommand>(
 3136                    lsp::ExecuteCommandParams {
 3137                        command: command.command.clone(),
 3138                        arguments: command.arguments.clone().unwrap_or_default(),
 3139                        ..Default::default()
 3140                    },
 3141                    request_timeout,
 3142                )
 3143                .await
 3144                .into_response()
 3145                .context("execute command")?;
 3146
 3147            lsp_store.update(cx, |this, _| {
 3148                if let LspStoreMode::Local(mode) = &mut this.mode {
 3149                    project_transaction.0.extend(
 3150                        mode.last_workspace_edits_by_language_server
 3151                            .remove(&language_server.server_id())
 3152                            .unwrap_or_default()
 3153                            .0,
 3154                    )
 3155                }
 3156            })?;
 3157        }
 3158        Ok(())
 3159    }
 3160
 3161    pub async fn deserialize_text_edits(
 3162        this: Entity<LspStore>,
 3163        buffer_to_edit: Entity<Buffer>,
 3164        edits: Vec<lsp::TextEdit>,
 3165        push_to_history: bool,
 3166        _: Arc<CachedLspAdapter>,
 3167        language_server: Arc<LanguageServer>,
 3168        cx: &mut AsyncApp,
 3169    ) -> Result<Option<Transaction>> {
 3170        let edits = this
 3171            .update(cx, |this, cx| {
 3172                this.as_local_mut().unwrap().edits_from_lsp(
 3173                    &buffer_to_edit,
 3174                    edits,
 3175                    language_server.server_id(),
 3176                    None,
 3177                    cx,
 3178                )
 3179            })
 3180            .await?;
 3181
 3182        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3183            buffer.finalize_last_transaction();
 3184            buffer.start_transaction();
 3185            for (range, text) in edits {
 3186                buffer.edit([(range, text)], None, cx);
 3187            }
 3188
 3189            if buffer.end_transaction(cx).is_some() {
 3190                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3191                if !push_to_history {
 3192                    buffer.forget_transaction(transaction.id);
 3193                }
 3194                Some(transaction)
 3195            } else {
 3196                None
 3197            }
 3198        });
 3199
 3200        Ok(transaction)
 3201    }
 3202
 3203    #[allow(clippy::type_complexity)]
 3204    pub fn edits_from_lsp(
 3205        &mut self,
 3206        buffer: &Entity<Buffer>,
 3207        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3208        server_id: LanguageServerId,
 3209        version: Option<i32>,
 3210        cx: &mut Context<LspStore>,
 3211    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3212        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3213        cx.background_spawn(async move {
 3214            let snapshot = snapshot?;
 3215            let mut lsp_edits = lsp_edits
 3216                .into_iter()
 3217                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3218                .collect::<Vec<_>>();
 3219
 3220            lsp_edits.sort_unstable_by_key(|(range, _)| (range.start, range.end));
 3221
 3222            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3223            let mut edits = Vec::new();
 3224            while let Some((range, mut new_text)) = lsp_edits.next() {
 3225                // Clip invalid ranges provided by the language server.
 3226                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3227                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3228
 3229                // Combine any LSP edits that are adjacent.
 3230                //
 3231                // Also, combine LSP edits that are separated from each other by only
 3232                // a newline. This is important because for some code actions,
 3233                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3234                // are separated by unchanged newline characters.
 3235                //
 3236                // In order for the diffing logic below to work properly, any edits that
 3237                // cancel each other out must be combined into one.
 3238                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3239                    if next_range.start.0 > range.end {
 3240                        if next_range.start.0.row > range.end.row + 1
 3241                            || next_range.start.0.column > 0
 3242                            || snapshot.clip_point_utf16(
 3243                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3244                                Bias::Left,
 3245                            ) > range.end
 3246                        {
 3247                            break;
 3248                        }
 3249                        new_text.push('\n');
 3250                    }
 3251                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3252                    new_text.push_str(next_text);
 3253                    lsp_edits.next();
 3254                }
 3255
 3256                // For multiline edits, perform a diff of the old and new text so that
 3257                // we can identify the changes more precisely, preserving the locations
 3258                // of any anchors positioned in the unchanged regions.
 3259                if range.end.row > range.start.row {
 3260                    let offset = range.start.to_offset(&snapshot);
 3261                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3262                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3263                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3264                        (
 3265                            snapshot.anchor_after(offset + range.start)
 3266                                ..snapshot.anchor_before(offset + range.end),
 3267                            replacement,
 3268                        )
 3269                    }));
 3270                } else if range.end == range.start {
 3271                    let anchor = snapshot.anchor_after(range.start);
 3272                    edits.push((anchor..anchor, new_text.into()));
 3273                } else {
 3274                    let edit_start = snapshot.anchor_after(range.start);
 3275                    let edit_end = snapshot.anchor_before(range.end);
 3276                    edits.push((edit_start..edit_end, new_text.into()));
 3277                }
 3278            }
 3279
 3280            Ok(edits)
 3281        })
 3282    }
 3283
 3284    pub(crate) async fn deserialize_workspace_edit(
 3285        this: Entity<LspStore>,
 3286        edit: lsp::WorkspaceEdit,
 3287        push_to_history: bool,
 3288        language_server: Arc<LanguageServer>,
 3289        cx: &mut AsyncApp,
 3290    ) -> Result<ProjectTransaction> {
 3291        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3292
 3293        let mut operations = Vec::new();
 3294        if let Some(document_changes) = edit.document_changes {
 3295            match document_changes {
 3296                lsp::DocumentChanges::Edits(edits) => {
 3297                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3298                }
 3299                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3300            }
 3301        } else if let Some(changes) = edit.changes {
 3302            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3303                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3304                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3305                        uri,
 3306                        version: None,
 3307                    },
 3308                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3309                })
 3310            }));
 3311        }
 3312
 3313        let mut project_transaction = ProjectTransaction::default();
 3314        for operation in operations {
 3315            match operation {
 3316                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3317                    let abs_path = op
 3318                        .uri
 3319                        .to_file_path()
 3320                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3321
 3322                    if let Some(parent_path) = abs_path.parent() {
 3323                        fs.create_dir(parent_path).await?;
 3324                    }
 3325                    if abs_path.ends_with("/") {
 3326                        fs.create_dir(&abs_path).await?;
 3327                    } else {
 3328                        fs.create_file(
 3329                            &abs_path,
 3330                            op.options
 3331                                .map(|options| fs::CreateOptions {
 3332                                    overwrite: options.overwrite.unwrap_or(false),
 3333                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3334                                })
 3335                                .unwrap_or_default(),
 3336                        )
 3337                        .await?;
 3338                    }
 3339                }
 3340
 3341                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3342                    let source_abs_path = op
 3343                        .old_uri
 3344                        .to_file_path()
 3345                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3346                    let target_abs_path = op
 3347                        .new_uri
 3348                        .to_file_path()
 3349                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3350
 3351                    let options = fs::RenameOptions {
 3352                        overwrite: op
 3353                            .options
 3354                            .as_ref()
 3355                            .and_then(|options| options.overwrite)
 3356                            .unwrap_or(false),
 3357                        ignore_if_exists: op
 3358                            .options
 3359                            .as_ref()
 3360                            .and_then(|options| options.ignore_if_exists)
 3361                            .unwrap_or(false),
 3362                        create_parents: true,
 3363                    };
 3364
 3365                    fs.rename(&source_abs_path, &target_abs_path, options)
 3366                        .await?;
 3367                }
 3368
 3369                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3370                    let abs_path = op
 3371                        .uri
 3372                        .to_file_path()
 3373                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3374                    let options = op
 3375                        .options
 3376                        .map(|options| fs::RemoveOptions {
 3377                            recursive: options.recursive.unwrap_or(false),
 3378                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3379                        })
 3380                        .unwrap_or_default();
 3381                    if abs_path.ends_with("/") {
 3382                        fs.remove_dir(&abs_path, options).await?;
 3383                    } else {
 3384                        fs.remove_file(&abs_path, options).await?;
 3385                    }
 3386                }
 3387
 3388                lsp::DocumentChangeOperation::Edit(op) => {
 3389                    let buffer_to_edit = this
 3390                        .update(cx, |this, cx| {
 3391                            this.open_local_buffer_via_lsp(
 3392                                op.text_document.uri.clone(),
 3393                                language_server.server_id(),
 3394                                cx,
 3395                            )
 3396                        })
 3397                        .await?;
 3398
 3399                    let edits = this
 3400                        .update(cx, |this, cx| {
 3401                            let path = buffer_to_edit.read(cx).project_path(cx);
 3402                            let active_entry = this.active_entry;
 3403                            let is_active_entry = path.is_some_and(|project_path| {
 3404                                this.worktree_store
 3405                                    .read(cx)
 3406                                    .entry_for_path(&project_path, cx)
 3407                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3408                            });
 3409                            let local = this.as_local_mut().unwrap();
 3410
 3411                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3412                            for edit in op.edits {
 3413                                match edit {
 3414                                    Edit::Plain(edit) => {
 3415                                        if !edits.contains(&edit) {
 3416                                            edits.push(edit)
 3417                                        }
 3418                                    }
 3419                                    Edit::Annotated(edit) => {
 3420                                        if !edits.contains(&edit.text_edit) {
 3421                                            edits.push(edit.text_edit)
 3422                                        }
 3423                                    }
 3424                                    Edit::Snippet(edit) => {
 3425                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3426                                        else {
 3427                                            continue;
 3428                                        };
 3429
 3430                                        if is_active_entry {
 3431                                            snippet_edits.push((edit.range, snippet));
 3432                                        } else {
 3433                                            // Since this buffer is not focused, apply a normal edit.
 3434                                            let new_edit = TextEdit {
 3435                                                range: edit.range,
 3436                                                new_text: snippet.text,
 3437                                            };
 3438                                            if !edits.contains(&new_edit) {
 3439                                                edits.push(new_edit);
 3440                                            }
 3441                                        }
 3442                                    }
 3443                                }
 3444                            }
 3445                            if !snippet_edits.is_empty() {
 3446                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3447                                let version = if let Some(buffer_version) = op.text_document.version
 3448                                {
 3449                                    local
 3450                                        .buffer_snapshot_for_lsp_version(
 3451                                            &buffer_to_edit,
 3452                                            language_server.server_id(),
 3453                                            Some(buffer_version),
 3454                                            cx,
 3455                                        )
 3456                                        .ok()
 3457                                        .map(|snapshot| snapshot.version)
 3458                                } else {
 3459                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3460                                };
 3461
 3462                                let most_recent_edit =
 3463                                    version.and_then(|version| version.most_recent());
 3464                                // Check if the edit that triggered that edit has been made by this participant.
 3465
 3466                                if let Some(most_recent_edit) = most_recent_edit {
 3467                                    cx.emit(LspStoreEvent::SnippetEdit {
 3468                                        buffer_id,
 3469                                        edits: snippet_edits,
 3470                                        most_recent_edit,
 3471                                    });
 3472                                }
 3473                            }
 3474
 3475                            local.edits_from_lsp(
 3476                                &buffer_to_edit,
 3477                                edits,
 3478                                language_server.server_id(),
 3479                                op.text_document.version,
 3480                                cx,
 3481                            )
 3482                        })
 3483                        .await?;
 3484
 3485                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3486                        buffer.finalize_last_transaction();
 3487                        buffer.start_transaction();
 3488                        for (range, text) in edits {
 3489                            buffer.edit([(range, text)], None, cx);
 3490                        }
 3491
 3492                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3493                            if push_to_history {
 3494                                buffer.finalize_last_transaction();
 3495                                buffer.get_transaction(transaction_id).cloned()
 3496                            } else {
 3497                                buffer.forget_transaction(transaction_id)
 3498                            }
 3499                        })
 3500                    });
 3501                    if let Some(transaction) = transaction {
 3502                        project_transaction.0.insert(buffer_to_edit, transaction);
 3503                    }
 3504                }
 3505            }
 3506        }
 3507
 3508        Ok(project_transaction)
 3509    }
 3510
 3511    async fn on_lsp_workspace_edit(
 3512        this: WeakEntity<LspStore>,
 3513        params: lsp::ApplyWorkspaceEditParams,
 3514        server_id: LanguageServerId,
 3515        cx: &mut AsyncApp,
 3516    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3517        let this = this.upgrade().context("project project closed")?;
 3518        let language_server = this
 3519            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3520            .context("language server not found")?;
 3521        let transaction = Self::deserialize_workspace_edit(
 3522            this.clone(),
 3523            params.edit,
 3524            true,
 3525            language_server.clone(),
 3526            cx,
 3527        )
 3528        .await
 3529        .log_err();
 3530        this.update(cx, |this, cx| {
 3531            if let Some(transaction) = transaction {
 3532                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3533
 3534                this.as_local_mut()
 3535                    .unwrap()
 3536                    .last_workspace_edits_by_language_server
 3537                    .insert(server_id, transaction);
 3538            }
 3539        });
 3540        Ok(lsp::ApplyWorkspaceEditResponse {
 3541            applied: true,
 3542            failed_change: None,
 3543            failure_reason: None,
 3544        })
 3545    }
 3546
 3547    fn remove_worktree(
 3548        &mut self,
 3549        id_to_remove: WorktreeId,
 3550        cx: &mut Context<LspStore>,
 3551    ) -> Vec<LanguageServerId> {
 3552        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3553        self.diagnostics.remove(&id_to_remove);
 3554        self.prettier_store.update(cx, |prettier_store, cx| {
 3555            prettier_store.remove_worktree(id_to_remove, cx);
 3556        });
 3557
 3558        let mut servers_to_remove = BTreeSet::default();
 3559        let mut servers_to_preserve = HashSet::default();
 3560        for (seed, state) in &self.language_server_ids {
 3561            if seed.worktree_id == id_to_remove {
 3562                servers_to_remove.insert(state.id);
 3563            } else {
 3564                servers_to_preserve.insert(state.id);
 3565            }
 3566        }
 3567        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3568        self.language_server_ids
 3569            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3570        for server_id_to_remove in &servers_to_remove {
 3571            self.language_server_watched_paths
 3572                .remove(server_id_to_remove);
 3573            self.language_server_paths_watched_for_rename
 3574                .remove(server_id_to_remove);
 3575            self.last_workspace_edits_by_language_server
 3576                .remove(server_id_to_remove);
 3577            self.language_servers.remove(server_id_to_remove);
 3578            self.buffer_pull_diagnostics_result_ids
 3579                .remove(server_id_to_remove);
 3580            self.workspace_pull_diagnostics_result_ids
 3581                .remove(server_id_to_remove);
 3582            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3583                buffer_servers.remove(server_id_to_remove);
 3584            }
 3585            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3586        }
 3587        servers_to_remove.into_iter().collect()
 3588    }
 3589
 3590    fn rebuild_watched_paths_inner<'a>(
 3591        &'a self,
 3592        language_server_id: LanguageServerId,
 3593        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3594        cx: &mut Context<LspStore>,
 3595    ) -> LanguageServerWatchedPathsBuilder {
 3596        let worktrees = self
 3597            .worktree_store
 3598            .read(cx)
 3599            .worktrees()
 3600            .filter_map(|worktree| {
 3601                self.language_servers_for_worktree(worktree.read(cx).id())
 3602                    .find(|server| server.server_id() == language_server_id)
 3603                    .map(|_| worktree)
 3604            })
 3605            .collect::<Vec<_>>();
 3606
 3607        let mut worktree_globs = HashMap::default();
 3608        let mut abs_globs = HashMap::default();
 3609        log::trace!(
 3610            "Processing new watcher paths for language server with id {}",
 3611            language_server_id
 3612        );
 3613
 3614        for watcher in watchers {
 3615            if let Some((worktree, literal_prefix, pattern)) =
 3616                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3617            {
 3618                worktree.update(cx, |worktree, _| {
 3619                    if let Some((tree, glob)) =
 3620                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3621                    {
 3622                        tree.add_path_prefix_to_scan(literal_prefix);
 3623                        worktree_globs
 3624                            .entry(tree.id())
 3625                            .or_insert_with(GlobSetBuilder::new)
 3626                            .add(glob);
 3627                    }
 3628                });
 3629            } else {
 3630                let (path, pattern) = match &watcher.glob_pattern {
 3631                    lsp::GlobPattern::String(s) => {
 3632                        let watcher_path = SanitizedPath::new(s);
 3633                        let path = glob_literal_prefix(watcher_path.as_path());
 3634                        let pattern = watcher_path
 3635                            .as_path()
 3636                            .strip_prefix(&path)
 3637                            .map(|p| p.to_string_lossy().into_owned())
 3638                            .unwrap_or_else(|e| {
 3639                                debug_panic!(
 3640                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3641                                    s,
 3642                                    path.display(),
 3643                                    e
 3644                                );
 3645                                watcher_path.as_path().to_string_lossy().into_owned()
 3646                            });
 3647                        (path, pattern)
 3648                    }
 3649                    lsp::GlobPattern::Relative(rp) => {
 3650                        let Ok(mut base_uri) = match &rp.base_uri {
 3651                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3652                            lsp::OneOf::Right(base_uri) => base_uri,
 3653                        }
 3654                        .to_file_path() else {
 3655                            continue;
 3656                        };
 3657
 3658                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3659                        let pattern = Path::new(&rp.pattern)
 3660                            .strip_prefix(&path)
 3661                            .map(|p| p.to_string_lossy().into_owned())
 3662                            .unwrap_or_else(|e| {
 3663                                debug_panic!(
 3664                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3665                                    rp.pattern,
 3666                                    path.display(),
 3667                                    e
 3668                                );
 3669                                rp.pattern.clone()
 3670                            });
 3671                        base_uri.push(path);
 3672                        (base_uri, pattern)
 3673                    }
 3674                };
 3675
 3676                if let Some(glob) = Glob::new(&pattern).log_err() {
 3677                    if !path
 3678                        .components()
 3679                        .any(|c| matches!(c, path::Component::Normal(_)))
 3680                    {
 3681                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3682                        // rather than adding a new watcher for `/`.
 3683                        for worktree in &worktrees {
 3684                            worktree_globs
 3685                                .entry(worktree.read(cx).id())
 3686                                .or_insert_with(GlobSetBuilder::new)
 3687                                .add(glob.clone());
 3688                        }
 3689                    } else {
 3690                        abs_globs
 3691                            .entry(path.into())
 3692                            .or_insert_with(GlobSetBuilder::new)
 3693                            .add(glob);
 3694                    }
 3695                }
 3696            }
 3697        }
 3698
 3699        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3700        for (worktree_id, builder) in worktree_globs {
 3701            if let Ok(globset) = builder.build() {
 3702                watch_builder.watch_worktree(worktree_id, globset);
 3703            }
 3704        }
 3705        for (abs_path, builder) in abs_globs {
 3706            if let Ok(globset) = builder.build() {
 3707                watch_builder.watch_abs_path(abs_path, globset);
 3708            }
 3709        }
 3710        watch_builder
 3711    }
 3712
 3713    fn worktree_and_path_for_file_watcher(
 3714        worktrees: &[Entity<Worktree>],
 3715        watcher: &FileSystemWatcher,
 3716        cx: &App,
 3717    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3718        worktrees.iter().find_map(|worktree| {
 3719            let tree = worktree.read(cx);
 3720            let worktree_root_path = tree.abs_path();
 3721            let path_style = tree.path_style();
 3722            match &watcher.glob_pattern {
 3723                lsp::GlobPattern::String(s) => {
 3724                    let watcher_path = SanitizedPath::new(s);
 3725                    let relative = watcher_path
 3726                        .as_path()
 3727                        .strip_prefix(&worktree_root_path)
 3728                        .ok()?;
 3729                    let literal_prefix = glob_literal_prefix(relative);
 3730                    Some((
 3731                        worktree.clone(),
 3732                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3733                        relative.to_string_lossy().into_owned(),
 3734                    ))
 3735                }
 3736                lsp::GlobPattern::Relative(rp) => {
 3737                    let base_uri = match &rp.base_uri {
 3738                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3739                        lsp::OneOf::Right(base_uri) => base_uri,
 3740                    }
 3741                    .to_file_path()
 3742                    .ok()?;
 3743                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3744                    let mut literal_prefix = relative.to_owned();
 3745                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3746                    Some((
 3747                        worktree.clone(),
 3748                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3749                        rp.pattern.clone(),
 3750                    ))
 3751                }
 3752            }
 3753        })
 3754    }
 3755
 3756    fn rebuild_watched_paths(
 3757        &mut self,
 3758        language_server_id: LanguageServerId,
 3759        cx: &mut Context<LspStore>,
 3760    ) {
 3761        let Some(registrations) = self
 3762            .language_server_dynamic_registrations
 3763            .get(&language_server_id)
 3764        else {
 3765            return;
 3766        };
 3767
 3768        let watch_builder = self.rebuild_watched_paths_inner(
 3769            language_server_id,
 3770            registrations.did_change_watched_files.values().flatten(),
 3771            cx,
 3772        );
 3773        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3774        self.language_server_watched_paths
 3775            .insert(language_server_id, watcher);
 3776
 3777        cx.notify();
 3778    }
 3779
 3780    fn on_lsp_did_change_watched_files(
 3781        &mut self,
 3782        language_server_id: LanguageServerId,
 3783        registration_id: &str,
 3784        params: DidChangeWatchedFilesRegistrationOptions,
 3785        cx: &mut Context<LspStore>,
 3786    ) {
 3787        let registrations = self
 3788            .language_server_dynamic_registrations
 3789            .entry(language_server_id)
 3790            .or_default();
 3791
 3792        registrations
 3793            .did_change_watched_files
 3794            .insert(registration_id.to_string(), params.watchers);
 3795
 3796        self.rebuild_watched_paths(language_server_id, cx);
 3797    }
 3798
 3799    fn on_lsp_unregister_did_change_watched_files(
 3800        &mut self,
 3801        language_server_id: LanguageServerId,
 3802        registration_id: &str,
 3803        cx: &mut Context<LspStore>,
 3804    ) {
 3805        let registrations = self
 3806            .language_server_dynamic_registrations
 3807            .entry(language_server_id)
 3808            .or_default();
 3809
 3810        if registrations
 3811            .did_change_watched_files
 3812            .remove(registration_id)
 3813            .is_some()
 3814        {
 3815            log::info!(
 3816                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3817                language_server_id,
 3818                registration_id
 3819            );
 3820        } else {
 3821            log::warn!(
 3822                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3823                language_server_id,
 3824                registration_id
 3825            );
 3826        }
 3827
 3828        self.rebuild_watched_paths(language_server_id, cx);
 3829    }
 3830
 3831    async fn initialization_options_for_adapter(
 3832        adapter: Arc<dyn LspAdapter>,
 3833        delegate: &Arc<dyn LspAdapterDelegate>,
 3834        cx: &mut AsyncApp,
 3835    ) -> Result<Option<serde_json::Value>> {
 3836        let Some(mut initialization_config) =
 3837            adapter.clone().initialization_options(delegate, cx).await?
 3838        else {
 3839            return Ok(None);
 3840        };
 3841
 3842        for other_adapter in delegate.registered_lsp_adapters() {
 3843            if other_adapter.name() == adapter.name() {
 3844                continue;
 3845            }
 3846            if let Ok(Some(target_config)) = other_adapter
 3847                .clone()
 3848                .additional_initialization_options(adapter.name(), delegate)
 3849                .await
 3850            {
 3851                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3852            }
 3853        }
 3854
 3855        Ok(Some(initialization_config))
 3856    }
 3857
 3858    async fn workspace_configuration_for_adapter(
 3859        adapter: Arc<dyn LspAdapter>,
 3860        delegate: &Arc<dyn LspAdapterDelegate>,
 3861        toolchain: Option<Toolchain>,
 3862        requested_uri: Option<Uri>,
 3863        cx: &mut AsyncApp,
 3864    ) -> Result<serde_json::Value> {
 3865        let mut workspace_config = adapter
 3866            .clone()
 3867            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3868            .await?;
 3869
 3870        for other_adapter in delegate.registered_lsp_adapters() {
 3871            if other_adapter.name() == adapter.name() {
 3872                continue;
 3873            }
 3874            if let Ok(Some(target_config)) = other_adapter
 3875                .clone()
 3876                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3877                .await
 3878            {
 3879                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3880            }
 3881        }
 3882
 3883        Ok(workspace_config)
 3884    }
 3885
 3886    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3887        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3888            Some(server.clone())
 3889        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3890            Some(Arc::clone(server))
 3891        } else {
 3892            None
 3893        }
 3894    }
 3895}
 3896
 3897fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3898    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3899        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3900            language_server_id: server.server_id(),
 3901            name: Some(server.name()),
 3902            message: proto::update_language_server::Variant::MetadataUpdated(
 3903                proto::ServerMetadataUpdated {
 3904                    capabilities: Some(capabilities),
 3905                    binary: Some(proto::LanguageServerBinaryInfo {
 3906                        path: server.binary().path.to_string_lossy().into_owned(),
 3907                        arguments: server
 3908                            .binary()
 3909                            .arguments
 3910                            .iter()
 3911                            .map(|arg| arg.to_string_lossy().into_owned())
 3912                            .collect(),
 3913                    }),
 3914                    configuration: serde_json::to_string(server.configuration()).ok(),
 3915                    workspace_folders: server
 3916                        .workspace_folders()
 3917                        .iter()
 3918                        .map(|uri| uri.to_string())
 3919                        .collect(),
 3920                },
 3921            ),
 3922        });
 3923    }
 3924}
 3925
 3926#[derive(Debug)]
 3927pub struct FormattableBuffer {
 3928    handle: Entity<Buffer>,
 3929    abs_path: Option<PathBuf>,
 3930    env: Option<HashMap<String, String>>,
 3931    ranges: Option<Vec<Range<Anchor>>>,
 3932}
 3933
 3934pub struct RemoteLspStore {
 3935    upstream_client: Option<AnyProtoClient>,
 3936    upstream_project_id: u64,
 3937}
 3938
 3939pub(crate) enum LspStoreMode {
 3940    Local(LocalLspStore),   // ssh host and collab host
 3941    Remote(RemoteLspStore), // collab guest
 3942}
 3943
 3944impl LspStoreMode {
 3945    fn is_local(&self) -> bool {
 3946        matches!(self, LspStoreMode::Local(_))
 3947    }
 3948}
 3949
 3950pub struct LspStore {
 3951    mode: LspStoreMode,
 3952    last_formatting_failure: Option<String>,
 3953    downstream_client: Option<(AnyProtoClient, u64)>,
 3954    nonce: u128,
 3955    buffer_store: Entity<BufferStore>,
 3956    worktree_store: Entity<WorktreeStore>,
 3957    pub languages: Arc<LanguageRegistry>,
 3958    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3959    active_entry: Option<ProjectEntryId>,
 3960    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3961    _maintain_buffer_languages: Task<()>,
 3962    diagnostic_summaries:
 3963        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3964    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3965    semantic_token_config: SemanticTokenConfig,
 3966    lsp_data: HashMap<BufferId, BufferLspData>,
 3967    buffer_reload_tasks: HashMap<BufferId, Task<anyhow::Result<()>>>,
 3968    next_hint_id: Arc<AtomicUsize>,
 3969}
 3970
 3971#[derive(Debug)]
 3972pub struct BufferLspData {
 3973    buffer_version: Global,
 3974    document_colors: Option<DocumentColorData>,
 3975    code_lens: Option<CodeLensData>,
 3976    semantic_tokens: Option<SemanticTokensData>,
 3977    folding_ranges: Option<FoldingRangeData>,
 3978    document_symbols: Option<DocumentSymbolsData>,
 3979    inlay_hints: BufferInlayHints,
 3980    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3981    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3982}
 3983
 3984#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3985struct LspKey {
 3986    request_type: TypeId,
 3987    server_queried: Option<LanguageServerId>,
 3988}
 3989
 3990impl BufferLspData {
 3991    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3992        Self {
 3993            buffer_version: buffer.read(cx).version(),
 3994            document_colors: None,
 3995            code_lens: None,
 3996            semantic_tokens: None,
 3997            folding_ranges: None,
 3998            document_symbols: None,
 3999            inlay_hints: BufferInlayHints::new(buffer, cx),
 4000            lsp_requests: HashMap::default(),
 4001            chunk_lsp_requests: HashMap::default(),
 4002        }
 4003    }
 4004
 4005    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 4006        if let Some(document_colors) = &mut self.document_colors {
 4007            document_colors.remove_server_data(for_server);
 4008        }
 4009
 4010        if let Some(code_lens) = &mut self.code_lens {
 4011            code_lens.remove_server_data(for_server);
 4012        }
 4013
 4014        self.inlay_hints.remove_server_data(for_server);
 4015
 4016        if let Some(semantic_tokens) = &mut self.semantic_tokens {
 4017            semantic_tokens.remove_server_data(for_server);
 4018        }
 4019
 4020        if let Some(folding_ranges) = &mut self.folding_ranges {
 4021            folding_ranges.ranges.remove(&for_server);
 4022        }
 4023
 4024        if let Some(document_symbols) = &mut self.document_symbols {
 4025            document_symbols.remove_server_data(for_server);
 4026        }
 4027    }
 4028
 4029    #[cfg(any(test, feature = "test-support"))]
 4030    pub fn inlay_hints(&self) -> &BufferInlayHints {
 4031        &self.inlay_hints
 4032    }
 4033}
 4034
 4035#[derive(Debug)]
 4036pub enum LspStoreEvent {
 4037    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 4038    LanguageServerRemoved(LanguageServerId),
 4039    LanguageServerUpdate {
 4040        language_server_id: LanguageServerId,
 4041        name: Option<LanguageServerName>,
 4042        message: proto::update_language_server::Variant,
 4043    },
 4044    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 4045    LanguageServerPrompt(LanguageServerPromptRequest),
 4046    LanguageDetected {
 4047        buffer: Entity<Buffer>,
 4048        new_language: Option<Arc<Language>>,
 4049    },
 4050    Notification(String),
 4051    RefreshInlayHints {
 4052        server_id: LanguageServerId,
 4053        request_id: Option<usize>,
 4054    },
 4055    RefreshSemanticTokens {
 4056        server_id: LanguageServerId,
 4057        request_id: Option<usize>,
 4058    },
 4059    RefreshCodeLens,
 4060    DiagnosticsUpdated {
 4061        server_id: LanguageServerId,
 4062        paths: Vec<ProjectPath>,
 4063    },
 4064    DiskBasedDiagnosticsStarted {
 4065        language_server_id: LanguageServerId,
 4066    },
 4067    DiskBasedDiagnosticsFinished {
 4068        language_server_id: LanguageServerId,
 4069    },
 4070    SnippetEdit {
 4071        buffer_id: BufferId,
 4072        edits: Vec<(lsp::Range, Snippet)>,
 4073        most_recent_edit: clock::Lamport,
 4074    },
 4075    WorkspaceEditApplied(ProjectTransaction),
 4076}
 4077
 4078#[derive(Clone, Debug, Serialize)]
 4079pub struct LanguageServerStatus {
 4080    pub name: LanguageServerName,
 4081    pub server_version: Option<SharedString>,
 4082    pub server_readable_version: Option<SharedString>,
 4083    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 4084    pub has_pending_diagnostic_updates: bool,
 4085    pub progress_tokens: HashSet<ProgressToken>,
 4086    pub worktree: Option<WorktreeId>,
 4087    pub binary: Option<LanguageServerBinary>,
 4088    pub configuration: Option<Value>,
 4089    pub workspace_folders: BTreeSet<Uri>,
 4090    pub process_id: Option<u32>,
 4091}
 4092
 4093#[derive(Clone, Debug)]
 4094struct CoreSymbol {
 4095    pub language_server_name: LanguageServerName,
 4096    pub source_worktree_id: WorktreeId,
 4097    pub source_language_server_id: LanguageServerId,
 4098    pub path: SymbolLocation,
 4099    pub name: String,
 4100    pub kind: lsp::SymbolKind,
 4101    pub range: Range<Unclipped<PointUtf16>>,
 4102    pub container_name: Option<String>,
 4103}
 4104
 4105#[derive(Clone, Debug, PartialEq, Eq)]
 4106pub enum SymbolLocation {
 4107    InProject(ProjectPath),
 4108    OutsideProject {
 4109        abs_path: Arc<Path>,
 4110        signature: [u8; 32],
 4111    },
 4112}
 4113
 4114impl SymbolLocation {
 4115    fn file_name(&self) -> Option<&str> {
 4116        match self {
 4117            Self::InProject(path) => path.path.file_name(),
 4118            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 4119        }
 4120    }
 4121}
 4122
 4123impl LspStore {
 4124    pub fn init(client: &AnyProtoClient) {
 4125        client.add_entity_request_handler(Self::handle_lsp_query);
 4126        client.add_entity_message_handler(Self::handle_lsp_query_response);
 4127        client.add_entity_request_handler(Self::handle_restart_language_servers);
 4128        client.add_entity_request_handler(Self::handle_stop_language_servers);
 4129        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 4130        client.add_entity_message_handler(Self::handle_start_language_server);
 4131        client.add_entity_message_handler(Self::handle_update_language_server);
 4132        client.add_entity_message_handler(Self::handle_language_server_log);
 4133        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 4134        client.add_entity_request_handler(Self::handle_format_buffers);
 4135        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 4136        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 4137        client.add_entity_request_handler(Self::handle_apply_code_action);
 4138        client.add_entity_request_handler(Self::handle_get_project_symbols);
 4139        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 4140        client.add_entity_request_handler(Self::handle_get_color_presentation);
 4141        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 4142        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 4143        client.add_entity_request_handler(Self::handle_refresh_semantic_tokens);
 4144        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 4145        client.add_entity_request_handler(Self::handle_on_type_formatting);
 4146        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 4147        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 4148        client.add_entity_request_handler(Self::handle_rename_project_entry);
 4149        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 4150        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 4151        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 4152        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 4153        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 4154        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 4155        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 4156
 4157        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 4158        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 4159        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 4160        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 4161        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 4162        client.add_entity_request_handler(
 4163            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 4164        );
 4165        client.add_entity_request_handler(
 4166            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 4167        );
 4168        client.add_entity_request_handler(
 4169            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 4170        );
 4171    }
 4172
 4173    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 4174        match &self.mode {
 4175            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 4176            _ => None,
 4177        }
 4178    }
 4179
 4180    pub fn as_local(&self) -> Option<&LocalLspStore> {
 4181        match &self.mode {
 4182            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4183            _ => None,
 4184        }
 4185    }
 4186
 4187    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 4188        match &mut self.mode {
 4189            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4190            _ => None,
 4191        }
 4192    }
 4193
 4194    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4195        match &self.mode {
 4196            LspStoreMode::Remote(RemoteLspStore {
 4197                upstream_client: Some(upstream_client),
 4198                upstream_project_id,
 4199                ..
 4200            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4201
 4202            LspStoreMode::Remote(RemoteLspStore {
 4203                upstream_client: None,
 4204                ..
 4205            }) => None,
 4206            LspStoreMode::Local(_) => None,
 4207        }
 4208    }
 4209
 4210    pub fn new_local(
 4211        buffer_store: Entity<BufferStore>,
 4212        worktree_store: Entity<WorktreeStore>,
 4213        prettier_store: Entity<PrettierStore>,
 4214        toolchain_store: Entity<LocalToolchainStore>,
 4215        environment: Entity<ProjectEnvironment>,
 4216        manifest_tree: Entity<ManifestTree>,
 4217        languages: Arc<LanguageRegistry>,
 4218        http_client: Arc<dyn HttpClient>,
 4219        fs: Arc<dyn Fs>,
 4220        cx: &mut Context<Self>,
 4221    ) -> Self {
 4222        let yarn = YarnPathStore::new(fs.clone(), cx);
 4223        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4224            .detach();
 4225        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4226            .detach();
 4227        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4228            .detach();
 4229        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4230            .detach();
 4231        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4232            .detach();
 4233        subscribe_to_binary_statuses(&languages, cx).detach();
 4234
 4235        let _maintain_workspace_config = {
 4236            let (sender, receiver) = watch::channel();
 4237            (Self::maintain_workspace_config(receiver, cx), sender)
 4238        };
 4239
 4240        Self {
 4241            mode: LspStoreMode::Local(LocalLspStore {
 4242                weak: cx.weak_entity(),
 4243                worktree_store: worktree_store.clone(),
 4244
 4245                supplementary_language_servers: Default::default(),
 4246                languages: languages.clone(),
 4247                language_server_ids: Default::default(),
 4248                language_servers: Default::default(),
 4249                last_workspace_edits_by_language_server: Default::default(),
 4250                language_server_watched_paths: Default::default(),
 4251                language_server_paths_watched_for_rename: Default::default(),
 4252                language_server_dynamic_registrations: Default::default(),
 4253                buffers_being_formatted: Default::default(),
 4254                buffers_to_refresh_hash_set: HashSet::default(),
 4255                buffers_to_refresh_queue: VecDeque::new(),
 4256                _background_diagnostics_worker: Task::ready(()).shared(),
 4257                buffer_snapshots: Default::default(),
 4258                prettier_store,
 4259                environment,
 4260                http_client,
 4261                fs,
 4262                yarn,
 4263                next_diagnostic_group_id: Default::default(),
 4264                diagnostics: Default::default(),
 4265                _subscription: cx.on_app_quit(|this, _| {
 4266                    this.as_local_mut()
 4267                        .unwrap()
 4268                        .shutdown_language_servers_on_quit()
 4269                }),
 4270                lsp_tree: LanguageServerTree::new(
 4271                    manifest_tree,
 4272                    languages.clone(),
 4273                    toolchain_store.clone(),
 4274                ),
 4275                toolchain_store,
 4276                registered_buffers: HashMap::default(),
 4277                buffers_opened_in_servers: HashMap::default(),
 4278                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4279                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4280                restricted_worktrees_tasks: HashMap::default(),
 4281                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4282                    .manifest_file_names(),
 4283            }),
 4284            last_formatting_failure: None,
 4285            downstream_client: None,
 4286            buffer_store,
 4287            worktree_store,
 4288            languages: languages.clone(),
 4289            language_server_statuses: Default::default(),
 4290            nonce: StdRng::from_os_rng().random(),
 4291            diagnostic_summaries: HashMap::default(),
 4292            lsp_server_capabilities: HashMap::default(),
 4293            semantic_token_config: SemanticTokenConfig::new(cx),
 4294            lsp_data: HashMap::default(),
 4295            buffer_reload_tasks: HashMap::default(),
 4296            next_hint_id: Arc::default(),
 4297            active_entry: None,
 4298            _maintain_workspace_config,
 4299            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4300        }
 4301    }
 4302
 4303    fn send_lsp_proto_request<R: LspCommand>(
 4304        &self,
 4305        buffer: Entity<Buffer>,
 4306        client: AnyProtoClient,
 4307        upstream_project_id: u64,
 4308        request: R,
 4309        cx: &mut Context<LspStore>,
 4310    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4311        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4312            return Task::ready(Ok(R::Response::default()));
 4313        }
 4314        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4315        cx.spawn(async move |this, cx| {
 4316            let response = client.request(message).await?;
 4317            let this = this.upgrade().context("project dropped")?;
 4318            request
 4319                .response_from_proto(response, this, buffer, cx.clone())
 4320                .await
 4321        })
 4322    }
 4323
 4324    pub(super) fn new_remote(
 4325        buffer_store: Entity<BufferStore>,
 4326        worktree_store: Entity<WorktreeStore>,
 4327        languages: Arc<LanguageRegistry>,
 4328        upstream_client: AnyProtoClient,
 4329        project_id: u64,
 4330        cx: &mut Context<Self>,
 4331    ) -> Self {
 4332        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4333            .detach();
 4334        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4335            .detach();
 4336        subscribe_to_binary_statuses(&languages, cx).detach();
 4337        let _maintain_workspace_config = {
 4338            let (sender, receiver) = watch::channel();
 4339            (Self::maintain_workspace_config(receiver, cx), sender)
 4340        };
 4341        Self {
 4342            mode: LspStoreMode::Remote(RemoteLspStore {
 4343                upstream_client: Some(upstream_client),
 4344                upstream_project_id: project_id,
 4345            }),
 4346            downstream_client: None,
 4347            last_formatting_failure: None,
 4348            buffer_store,
 4349            worktree_store,
 4350            languages: languages.clone(),
 4351            language_server_statuses: Default::default(),
 4352            nonce: StdRng::from_os_rng().random(),
 4353            diagnostic_summaries: HashMap::default(),
 4354            lsp_server_capabilities: HashMap::default(),
 4355            semantic_token_config: SemanticTokenConfig::new(cx),
 4356            next_hint_id: Arc::default(),
 4357            lsp_data: HashMap::default(),
 4358            buffer_reload_tasks: HashMap::default(),
 4359            active_entry: None,
 4360
 4361            _maintain_workspace_config,
 4362            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4363        }
 4364    }
 4365
 4366    fn on_buffer_store_event(
 4367        &mut self,
 4368        _: Entity<BufferStore>,
 4369        event: &BufferStoreEvent,
 4370        cx: &mut Context<Self>,
 4371    ) {
 4372        match event {
 4373            BufferStoreEvent::BufferAdded(buffer) => {
 4374                self.on_buffer_added(buffer, cx).log_err();
 4375            }
 4376            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4377                let buffer_id = buffer.read(cx).remote_id();
 4378                if let Some(local) = self.as_local_mut()
 4379                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4380                {
 4381                    local.reset_buffer(buffer, old_file, cx);
 4382
 4383                    if local.registered_buffers.contains_key(&buffer_id) {
 4384                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4385                    }
 4386                }
 4387
 4388                self.detect_language_for_buffer(buffer, cx);
 4389                if let Some(local) = self.as_local_mut() {
 4390                    local.initialize_buffer(buffer, cx);
 4391                    if local.registered_buffers.contains_key(&buffer_id) {
 4392                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4393                    }
 4394                }
 4395            }
 4396            _ => {}
 4397        }
 4398    }
 4399
 4400    fn on_worktree_store_event(
 4401        &mut self,
 4402        _: Entity<WorktreeStore>,
 4403        event: &WorktreeStoreEvent,
 4404        cx: &mut Context<Self>,
 4405    ) {
 4406        match event {
 4407            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4408                if !worktree.read(cx).is_local() {
 4409                    return;
 4410                }
 4411                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4412                    worktree::Event::UpdatedEntries(changes) => {
 4413                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4414                    }
 4415                    worktree::Event::UpdatedGitRepositories(_)
 4416                    | worktree::Event::DeletedEntry(_)
 4417                    | worktree::Event::Deleted => {}
 4418                })
 4419                .detach()
 4420            }
 4421            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4422            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4423                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4424            }
 4425            WorktreeStoreEvent::WorktreeUpdatedEntries(worktree_id, changes) => {
 4426                self.invalidate_diagnostic_summaries_for_removed_entries(*worktree_id, changes, cx);
 4427            }
 4428            WorktreeStoreEvent::WorktreeReleased(..)
 4429            | WorktreeStoreEvent::WorktreeOrderChanged
 4430            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4431            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4432        }
 4433    }
 4434
 4435    fn on_prettier_store_event(
 4436        &mut self,
 4437        _: Entity<PrettierStore>,
 4438        event: &PrettierStoreEvent,
 4439        cx: &mut Context<Self>,
 4440    ) {
 4441        match event {
 4442            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4443                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4444            }
 4445            PrettierStoreEvent::LanguageServerAdded {
 4446                new_server_id,
 4447                name,
 4448                prettier_server,
 4449            } => {
 4450                self.register_supplementary_language_server(
 4451                    *new_server_id,
 4452                    name.clone(),
 4453                    prettier_server.clone(),
 4454                    cx,
 4455                );
 4456            }
 4457        }
 4458    }
 4459
 4460    fn on_toolchain_store_event(
 4461        &mut self,
 4462        _: Entity<LocalToolchainStore>,
 4463        event: &ToolchainStoreEvent,
 4464        _: &mut Context<Self>,
 4465    ) {
 4466        if let ToolchainStoreEvent::ToolchainActivated = event {
 4467            self.request_workspace_config_refresh()
 4468        }
 4469    }
 4470
 4471    fn request_workspace_config_refresh(&mut self) {
 4472        *self._maintain_workspace_config.1.borrow_mut() = ();
 4473    }
 4474
 4475    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4476        self.as_local().map(|local| local.prettier_store.clone())
 4477    }
 4478
 4479    fn on_buffer_event(
 4480        &mut self,
 4481        buffer: Entity<Buffer>,
 4482        event: &language::BufferEvent,
 4483        cx: &mut Context<Self>,
 4484    ) {
 4485        match event {
 4486            language::BufferEvent::Edited { .. } => {
 4487                self.on_buffer_edited(buffer, cx);
 4488            }
 4489
 4490            language::BufferEvent::Saved => {
 4491                self.on_buffer_saved(buffer, cx);
 4492            }
 4493
 4494            language::BufferEvent::Reloaded => {
 4495                self.on_buffer_reloaded(buffer, cx);
 4496            }
 4497
 4498            _ => {}
 4499        }
 4500    }
 4501
 4502    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4503        buffer
 4504            .read(cx)
 4505            .set_language_registry(self.languages.clone());
 4506
 4507        cx.subscribe(buffer, |this, buffer, event, cx| {
 4508            this.on_buffer_event(buffer, event, cx);
 4509        })
 4510        .detach();
 4511
 4512        self.parse_modeline(buffer, cx);
 4513        self.detect_language_for_buffer(buffer, cx);
 4514        if let Some(local) = self.as_local_mut() {
 4515            local.initialize_buffer(buffer, cx);
 4516        }
 4517
 4518        Ok(())
 4519    }
 4520
 4521    pub fn refresh_background_diagnostics_for_buffers(
 4522        &mut self,
 4523        buffers: HashSet<BufferId>,
 4524        cx: &mut Context<Self>,
 4525    ) -> Shared<Task<()>> {
 4526        let Some(local) = self.as_local_mut() else {
 4527            return Task::ready(()).shared();
 4528        };
 4529        for buffer in buffers {
 4530            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4531                local.buffers_to_refresh_queue.push_back(buffer);
 4532                if local.buffers_to_refresh_queue.len() == 1 {
 4533                    local._background_diagnostics_worker =
 4534                        Self::background_diagnostics_worker(cx).shared();
 4535                }
 4536            }
 4537        }
 4538
 4539        local._background_diagnostics_worker.clone()
 4540    }
 4541
 4542    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4543        let buffer_store = self.buffer_store.clone();
 4544        let local = self.as_local_mut()?;
 4545        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4546            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4547            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4548                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4549            }
 4550        }
 4551        None
 4552    }
 4553
 4554    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4555        cx.spawn(async move |this, cx| {
 4556            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4557                task.await.log_err();
 4558            }
 4559        })
 4560    }
 4561
 4562    fn on_buffer_reloaded(&mut self, buffer: Entity<Buffer>, cx: &mut Context<Self>) {
 4563        if self.parse_modeline(&buffer, cx) {
 4564            self.detect_language_for_buffer(&buffer, cx);
 4565        }
 4566
 4567        let buffer_id = buffer.read(cx).remote_id();
 4568        let task = self.pull_diagnostics_for_buffer(buffer, cx);
 4569        self.buffer_reload_tasks.insert(buffer_id, task);
 4570    }
 4571
 4572    pub(crate) fn register_buffer_with_language_servers(
 4573        &mut self,
 4574        buffer: &Entity<Buffer>,
 4575        only_register_servers: HashSet<LanguageServerSelector>,
 4576        ignore_refcounts: bool,
 4577        cx: &mut Context<Self>,
 4578    ) -> OpenLspBufferHandle {
 4579        let buffer_id = buffer.read(cx).remote_id();
 4580        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4581        if let Some(local) = self.as_local_mut() {
 4582            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4583            if !ignore_refcounts {
 4584                *refcount += 1;
 4585            }
 4586
 4587            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4588            // 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
 4589            // 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
 4590            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4591            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4592                return handle;
 4593            };
 4594            if !file.is_local() {
 4595                return handle;
 4596            }
 4597
 4598            if ignore_refcounts || *refcount == 1 {
 4599                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4600            }
 4601            if !ignore_refcounts {
 4602                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4603                    let refcount = {
 4604                        let local = lsp_store.as_local_mut().unwrap();
 4605                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4606                            debug_panic!("bad refcounting");
 4607                            return;
 4608                        };
 4609
 4610                        *refcount -= 1;
 4611                        *refcount
 4612                    };
 4613                    if refcount == 0 {
 4614                        lsp_store.lsp_data.remove(&buffer_id);
 4615                        lsp_store.buffer_reload_tasks.remove(&buffer_id);
 4616                        let local = lsp_store.as_local_mut().unwrap();
 4617                        local.registered_buffers.remove(&buffer_id);
 4618
 4619                        local.buffers_opened_in_servers.remove(&buffer_id);
 4620                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4621                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4622
 4623                            let buffer_abs_path = file.abs_path(cx);
 4624                            for (_, buffer_pull_diagnostics_result_ids) in
 4625                                &mut local.buffer_pull_diagnostics_result_ids
 4626                            {
 4627                                buffer_pull_diagnostics_result_ids.retain(
 4628                                    |_, buffer_result_ids| {
 4629                                        buffer_result_ids.remove(&buffer_abs_path);
 4630                                        !buffer_result_ids.is_empty()
 4631                                    },
 4632                                );
 4633                            }
 4634
 4635                            let diagnostic_updates = local
 4636                                .language_servers
 4637                                .keys()
 4638                                .cloned()
 4639                                .map(|server_id| DocumentDiagnosticsUpdate {
 4640                                    diagnostics: DocumentDiagnostics {
 4641                                        document_abs_path: buffer_abs_path.clone(),
 4642                                        version: None,
 4643                                        diagnostics: Vec::new(),
 4644                                    },
 4645                                    result_id: None,
 4646                                    registration_id: None,
 4647                                    server_id,
 4648                                    disk_based_sources: Cow::Borrowed(&[]),
 4649                                })
 4650                                .collect::<Vec<_>>();
 4651
 4652                            lsp_store
 4653                                .merge_diagnostic_entries(
 4654                                    diagnostic_updates,
 4655                                    |_, diagnostic, _| {
 4656                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4657                                    },
 4658                                    cx,
 4659                                )
 4660                                .context("Clearing diagnostics for the closed buffer")
 4661                                .log_err();
 4662                        }
 4663                    }
 4664                })
 4665                .detach();
 4666            }
 4667        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4668            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4669            cx.background_spawn(async move {
 4670                upstream_client
 4671                    .request(proto::RegisterBufferWithLanguageServers {
 4672                        project_id: upstream_project_id,
 4673                        buffer_id,
 4674                        only_servers: only_register_servers
 4675                            .into_iter()
 4676                            .map(|selector| {
 4677                                let selector = match selector {
 4678                                    LanguageServerSelector::Id(language_server_id) => {
 4679                                        proto::language_server_selector::Selector::ServerId(
 4680                                            language_server_id.to_proto(),
 4681                                        )
 4682                                    }
 4683                                    LanguageServerSelector::Name(language_server_name) => {
 4684                                        proto::language_server_selector::Selector::Name(
 4685                                            language_server_name.to_string(),
 4686                                        )
 4687                                    }
 4688                                };
 4689                                proto::LanguageServerSelector {
 4690                                    selector: Some(selector),
 4691                                }
 4692                            })
 4693                            .collect(),
 4694                    })
 4695                    .await
 4696            })
 4697            .detach();
 4698        } else {
 4699            // Our remote connection got closed
 4700        }
 4701        handle
 4702    }
 4703
 4704    fn maintain_buffer_languages(
 4705        languages: Arc<LanguageRegistry>,
 4706        cx: &mut Context<Self>,
 4707    ) -> Task<()> {
 4708        let mut subscription = languages.subscribe();
 4709        let mut prev_reload_count = languages.reload_count();
 4710        cx.spawn(async move |this, cx| {
 4711            while let Some(()) = subscription.next().await {
 4712                if let Some(this) = this.upgrade() {
 4713                    // If the language registry has been reloaded, then remove and
 4714                    // re-assign the languages on all open buffers.
 4715                    let reload_count = languages.reload_count();
 4716                    if reload_count > prev_reload_count {
 4717                        prev_reload_count = reload_count;
 4718                        this.update(cx, |this, cx| {
 4719                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4720                                for buffer in buffer_store.buffers() {
 4721                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4722                                    {
 4723                                        buffer.update(cx, |buffer, cx| {
 4724                                            buffer.set_language_async(None, cx)
 4725                                        });
 4726                                        if let Some(local) = this.as_local_mut() {
 4727                                            local.reset_buffer(&buffer, &f, cx);
 4728
 4729                                            if local
 4730                                                .registered_buffers
 4731                                                .contains_key(&buffer.read(cx).remote_id())
 4732                                                && let Some(file_url) =
 4733                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4734                                            {
 4735                                                local.unregister_buffer_from_language_servers(
 4736                                                    &buffer, &file_url, cx,
 4737                                                );
 4738                                            }
 4739                                        }
 4740                                    }
 4741                                }
 4742                            });
 4743                        });
 4744                    }
 4745
 4746                    this.update(cx, |this, cx| {
 4747                        let mut plain_text_buffers = Vec::new();
 4748                        let mut buffers_with_unknown_injections = Vec::new();
 4749                        for handle in this.buffer_store.read(cx).buffers() {
 4750                            let buffer = handle.read(cx);
 4751                            if buffer.language().is_none()
 4752                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4753                            {
 4754                                plain_text_buffers.push(handle);
 4755                            } else if buffer.contains_unknown_injections() {
 4756                                buffers_with_unknown_injections.push(handle);
 4757                            }
 4758                        }
 4759
 4760                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4761                        // and reused later in the invisible worktrees.
 4762                        plain_text_buffers.sort_by_key(|buffer| {
 4763                            Reverse(
 4764                                File::from_dyn(buffer.read(cx).file())
 4765                                    .map(|file| file.worktree.read(cx).is_visible()),
 4766                            )
 4767                        });
 4768
 4769                        for buffer in plain_text_buffers {
 4770                            this.detect_language_for_buffer(&buffer, cx);
 4771                            if let Some(local) = this.as_local_mut() {
 4772                                local.initialize_buffer(&buffer, cx);
 4773                                if local
 4774                                    .registered_buffers
 4775                                    .contains_key(&buffer.read(cx).remote_id())
 4776                                {
 4777                                    local.register_buffer_with_language_servers(
 4778                                        &buffer,
 4779                                        HashSet::default(),
 4780                                        cx,
 4781                                    );
 4782                                }
 4783                            }
 4784                        }
 4785
 4786                        for buffer in buffers_with_unknown_injections {
 4787                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4788                        }
 4789                    });
 4790                }
 4791            }
 4792        })
 4793    }
 4794
 4795    fn parse_modeline(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<Self>) -> bool {
 4796        let buffer = buffer_handle.read(cx);
 4797        let content = buffer.as_rope();
 4798
 4799        let modeline_settings = {
 4800            let settings_store = cx.global::<SettingsStore>();
 4801            let modeline_lines = settings_store
 4802                .raw_user_settings()
 4803                .and_then(|s| s.content.modeline_lines)
 4804                .or(settings_store.raw_default_settings().modeline_lines)
 4805                .unwrap_or(5);
 4806
 4807            const MAX_MODELINE_BYTES: usize = 1024;
 4808
 4809            let first_bytes =
 4810                content.clip_offset(content.len().min(MAX_MODELINE_BYTES), Bias::Left);
 4811            let mut first_lines = Vec::new();
 4812            let mut lines = content.chunks_in_range(0..first_bytes).lines();
 4813            for _ in 0..modeline_lines {
 4814                if let Some(line) = lines.next() {
 4815                    first_lines.push(line.to_string());
 4816                } else {
 4817                    break;
 4818                }
 4819            }
 4820            let first_lines_ref: Vec<_> = first_lines.iter().map(|line| line.as_str()).collect();
 4821
 4822            let last_start =
 4823                content.clip_offset(content.len().saturating_sub(MAX_MODELINE_BYTES), Bias::Left);
 4824            let mut last_lines = Vec::new();
 4825            let mut lines = content
 4826                .reversed_chunks_in_range(last_start..content.len())
 4827                .lines();
 4828            for _ in 0..modeline_lines {
 4829                if let Some(line) = lines.next() {
 4830                    last_lines.push(line.to_string());
 4831                } else {
 4832                    break;
 4833                }
 4834            }
 4835            let last_lines_ref: Vec<_> =
 4836                last_lines.iter().rev().map(|line| line.as_str()).collect();
 4837            modeline::parse_modeline(&first_lines_ref, &last_lines_ref)
 4838        };
 4839
 4840        log::debug!("Parsed modeline settings: {:?}", modeline_settings);
 4841
 4842        buffer_handle.update(cx, |buffer, _cx| buffer.set_modeline(modeline_settings))
 4843    }
 4844
 4845    fn detect_language_for_buffer(
 4846        &mut self,
 4847        buffer_handle: &Entity<Buffer>,
 4848        cx: &mut Context<Self>,
 4849    ) -> Option<language::AvailableLanguage> {
 4850        // If the buffer has a language, set it and start the language server if we haven't already.
 4851        let buffer = buffer_handle.read(cx);
 4852        let file = buffer.file()?;
 4853        let content = buffer.as_rope();
 4854        let modeline_settings = buffer.modeline().map(Arc::as_ref);
 4855
 4856        let available_language = if let Some(ModelineSettings {
 4857            mode: Some(mode_name),
 4858            ..
 4859        }) = modeline_settings
 4860        {
 4861            self.languages
 4862                .available_language_for_modeline_name(mode_name)
 4863        } else {
 4864            self.languages.language_for_file(file, Some(content), cx)
 4865        };
 4866        if let Some(available_language) = &available_language {
 4867            if let Some(Ok(Ok(new_language))) = self
 4868                .languages
 4869                .load_language(available_language)
 4870                .now_or_never()
 4871            {
 4872                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4873            }
 4874        } else {
 4875            cx.emit(LspStoreEvent::LanguageDetected {
 4876                buffer: buffer_handle.clone(),
 4877                new_language: None,
 4878            });
 4879        }
 4880
 4881        available_language
 4882    }
 4883
 4884    pub(crate) fn set_language_for_buffer(
 4885        &mut self,
 4886        buffer_entity: &Entity<Buffer>,
 4887        new_language: Arc<Language>,
 4888        cx: &mut Context<Self>,
 4889    ) {
 4890        let buffer = buffer_entity.read(cx);
 4891        let buffer_file = buffer.file().cloned();
 4892        let buffer_id = buffer.remote_id();
 4893        if let Some(local_store) = self.as_local_mut()
 4894            && local_store.registered_buffers.contains_key(&buffer_id)
 4895            && let Some(abs_path) =
 4896                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4897            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4898        {
 4899            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4900        }
 4901        buffer_entity.update(cx, |buffer, cx| {
 4902            if buffer
 4903                .language()
 4904                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4905            {
 4906                buffer.set_language_async(Some(new_language.clone()), cx);
 4907            }
 4908        });
 4909
 4910        let settings = LanguageSettings::resolve(
 4911            Some(&buffer_entity.read(cx)),
 4912            Some(&new_language.name()),
 4913            cx,
 4914        )
 4915        .into_owned();
 4916        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4917
 4918        let worktree_id = if let Some(file) = buffer_file {
 4919            let worktree = file.worktree.clone();
 4920
 4921            if let Some(local) = self.as_local_mut()
 4922                && local.registered_buffers.contains_key(&buffer_id)
 4923            {
 4924                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4925            }
 4926            Some(worktree.read(cx).id())
 4927        } else {
 4928            None
 4929        };
 4930
 4931        if settings.prettier.allowed
 4932            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4933        {
 4934            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4935            if let Some(prettier_store) = prettier_store {
 4936                prettier_store.update(cx, |prettier_store, cx| {
 4937                    prettier_store.install_default_prettier(
 4938                        worktree_id,
 4939                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4940                        cx,
 4941                    )
 4942                })
 4943            }
 4944        }
 4945
 4946        cx.emit(LspStoreEvent::LanguageDetected {
 4947            buffer: buffer_entity.clone(),
 4948            new_language: Some(new_language),
 4949        })
 4950    }
 4951
 4952    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4953        self.buffer_store.clone()
 4954    }
 4955
 4956    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4957        self.active_entry = active_entry;
 4958    }
 4959
 4960    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4961        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4962            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4963        {
 4964            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4965                summaries
 4966                    .iter()
 4967                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4968            });
 4969            if let Some(summary) = summaries.next() {
 4970                client
 4971                    .send(proto::UpdateDiagnosticSummary {
 4972                        project_id: downstream_project_id,
 4973                        worktree_id: worktree.id().to_proto(),
 4974                        summary: Some(summary),
 4975                        more_summaries: summaries.collect(),
 4976                    })
 4977                    .log_err();
 4978            }
 4979        }
 4980    }
 4981
 4982    fn is_capable_for_proto_request<R>(
 4983        &self,
 4984        buffer: &Entity<Buffer>,
 4985        request: &R,
 4986        cx: &App,
 4987    ) -> bool
 4988    where
 4989        R: LspCommand,
 4990    {
 4991        self.check_if_capable_for_proto_request(
 4992            buffer,
 4993            |capabilities| {
 4994                request.check_capabilities(AdapterServerCapabilities {
 4995                    server_capabilities: capabilities.clone(),
 4996                    code_action_kinds: None,
 4997                })
 4998            },
 4999            cx,
 5000        )
 5001    }
 5002
 5003    fn check_if_capable_for_proto_request<F>(
 5004        &self,
 5005        buffer: &Entity<Buffer>,
 5006        check: F,
 5007        cx: &App,
 5008    ) -> bool
 5009    where
 5010        F: FnMut(&lsp::ServerCapabilities) -> bool,
 5011    {
 5012        let Some(language) = buffer.read(cx).language().cloned() else {
 5013            return false;
 5014        };
 5015        let registered_language_servers = self
 5016            .languages
 5017            .lsp_adapters(&language.name())
 5018            .into_iter()
 5019            .map(|lsp_adapter| lsp_adapter.name())
 5020            .collect::<HashSet<_>>();
 5021        self.language_server_statuses
 5022            .iter()
 5023            .filter_map(|(server_id, server_status)| {
 5024                // Include servers that are either registered for this language OR
 5025                // available to be loaded (for SSH remote mode where adapters like
 5026                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 5027                // but only loaded on the server side)
 5028                let is_relevant = registered_language_servers.contains(&server_status.name)
 5029                    || self.languages.is_lsp_adapter_available(&server_status.name);
 5030                is_relevant.then_some(server_id)
 5031            })
 5032            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 5033            .any(check)
 5034    }
 5035
 5036    fn all_capable_for_proto_request<F>(
 5037        &self,
 5038        buffer: &Entity<Buffer>,
 5039        mut check: F,
 5040        cx: &App,
 5041    ) -> Vec<(lsp::LanguageServerId, lsp::LanguageServerName)>
 5042    where
 5043        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 5044    {
 5045        let Some(language) = buffer.read(cx).language().cloned() else {
 5046            return Vec::default();
 5047        };
 5048        let registered_language_servers = self
 5049            .languages
 5050            .lsp_adapters(&language.name())
 5051            .into_iter()
 5052            .map(|lsp_adapter| lsp_adapter.name())
 5053            .collect::<HashSet<_>>();
 5054        self.language_server_statuses
 5055            .iter()
 5056            .filter_map(|(server_id, server_status)| {
 5057                // Include servers that are either registered for this language OR
 5058                // available to be loaded (for SSH remote mode where adapters like
 5059                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 5060                // but only loaded on the server side)
 5061                let is_relevant = registered_language_servers.contains(&server_status.name)
 5062                    || self.languages.is_lsp_adapter_available(&server_status.name);
 5063                is_relevant.then_some((server_id, &server_status.name))
 5064            })
 5065            .filter_map(|(server_id, server_name)| {
 5066                self.lsp_server_capabilities
 5067                    .get(server_id)
 5068                    .map(|c| (server_id, server_name, c))
 5069            })
 5070            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 5071            .map(|(server_id, server_name, _)| (*server_id, server_name.clone()))
 5072            .collect()
 5073    }
 5074
 5075    pub fn request_lsp<R>(
 5076        &mut self,
 5077        buffer: Entity<Buffer>,
 5078        server: LanguageServerToQuery,
 5079        request: R,
 5080        cx: &mut Context<Self>,
 5081    ) -> Task<Result<R::Response>>
 5082    where
 5083        R: LspCommand,
 5084        <R::LspRequest as lsp::request::Request>::Result: Send,
 5085        <R::LspRequest as lsp::request::Request>::Params: Send,
 5086    {
 5087        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 5088            return self.send_lsp_proto_request(
 5089                buffer,
 5090                upstream_client,
 5091                upstream_project_id,
 5092                request,
 5093                cx,
 5094            );
 5095        }
 5096
 5097        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 5098            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 5099                local
 5100                    .language_servers_for_buffer(buffer, cx)
 5101                    .find(|(_, server)| {
 5102                        request.check_capabilities(server.adapter_server_capabilities())
 5103                    })
 5104                    .map(|(_, server)| server.clone())
 5105            }),
 5106            LanguageServerToQuery::Other(id) => self
 5107                .language_server_for_local_buffer(buffer, id, cx)
 5108                .and_then(|(_, server)| {
 5109                    request
 5110                        .check_capabilities(server.adapter_server_capabilities())
 5111                        .then(|| Arc::clone(server))
 5112                }),
 5113        }) else {
 5114            return Task::ready(Ok(Default::default()));
 5115        };
 5116
 5117        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 5118
 5119        let Some(file) = file else {
 5120            return Task::ready(Ok(Default::default()));
 5121        };
 5122
 5123        let lsp_params = match request.to_lsp_params_or_response(
 5124            &file.abs_path(cx),
 5125            buffer.read(cx),
 5126            &language_server,
 5127            cx,
 5128        ) {
 5129            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 5130            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 5131            Err(err) => {
 5132                let message = format!(
 5133                    "{} via {} failed: {}",
 5134                    request.display_name(),
 5135                    language_server.name(),
 5136                    err
 5137                );
 5138                // rust-analyzer likes to error with this when its still loading up
 5139                if !message.ends_with("content modified") {
 5140                    log::warn!("{message}");
 5141                }
 5142                return Task::ready(Err(anyhow!(message)));
 5143            }
 5144        };
 5145
 5146        let status = request.status();
 5147        let request_timeout = ProjectSettings::get_global(cx)
 5148            .global_lsp_settings
 5149            .get_request_timeout();
 5150
 5151        cx.spawn(async move |this, cx| {
 5152            let lsp_request = language_server.request::<R::LspRequest>(lsp_params, request_timeout);
 5153
 5154            let id = lsp_request.id();
 5155            let _cleanup = if status.is_some() {
 5156                cx.update(|cx| {
 5157                    this.update(cx, |this, cx| {
 5158                        this.on_lsp_work_start(
 5159                            language_server.server_id(),
 5160                            ProgressToken::Number(id),
 5161                            LanguageServerProgress {
 5162                                is_disk_based_diagnostics_progress: false,
 5163                                is_cancellable: false,
 5164                                title: None,
 5165                                message: status.clone(),
 5166                                percentage: None,
 5167                                last_update_at: cx.background_executor().now(),
 5168                            },
 5169                            cx,
 5170                        );
 5171                    })
 5172                })
 5173                .log_err();
 5174
 5175                Some(defer(|| {
 5176                    cx.update(|cx| {
 5177                        this.update(cx, |this, cx| {
 5178                            this.on_lsp_work_end(
 5179                                language_server.server_id(),
 5180                                ProgressToken::Number(id),
 5181                                cx,
 5182                            );
 5183                        })
 5184                    })
 5185                    .log_err();
 5186                }))
 5187            } else {
 5188                None
 5189            };
 5190
 5191            let result = lsp_request.await.into_response();
 5192
 5193            let response = result.map_err(|err| {
 5194                let message = format!(
 5195                    "{} via {} failed: {}",
 5196                    request.display_name(),
 5197                    language_server.name(),
 5198                    err
 5199                );
 5200                // rust-analyzer likes to error with this when its still loading up
 5201                if !message.ends_with("content modified") {
 5202                    log::warn!("{message}");
 5203                }
 5204                anyhow::anyhow!(message)
 5205            })?;
 5206
 5207            request
 5208                .response_from_lsp(
 5209                    response,
 5210                    this.upgrade().context("no app context")?,
 5211                    buffer,
 5212                    language_server.server_id(),
 5213                    cx.clone(),
 5214                )
 5215                .await
 5216        })
 5217    }
 5218
 5219    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 5220        let mut language_formatters_to_check = Vec::new();
 5221        for buffer in self.buffer_store.read(cx).buffers() {
 5222            let buffer = buffer.read(cx);
 5223            let settings = LanguageSettings::for_buffer(buffer, cx);
 5224            if buffer.language().is_some() {
 5225                let buffer_file = File::from_dyn(buffer.file());
 5226                language_formatters_to_check.push((
 5227                    buffer_file.map(|f| f.worktree_id(cx)),
 5228                    settings.into_owned(),
 5229                ));
 5230            }
 5231        }
 5232
 5233        self.request_workspace_config_refresh();
 5234
 5235        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 5236            prettier_store.update(cx, |prettier_store, cx| {
 5237                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 5238            })
 5239        }
 5240
 5241        let new_semantic_token_rules = crate::project_settings::ProjectSettings::get_global(cx)
 5242            .global_lsp_settings
 5243            .semantic_token_rules
 5244            .clone();
 5245        self.semantic_token_config
 5246            .update_rules(new_semantic_token_rules);
 5247        // Always clear cached stylizers so that changes to language-specific
 5248        // semantic token rules (e.g. from extension install/uninstall) are
 5249        // picked up. Stylizers are recreated lazily, so this is cheap.
 5250        self.semantic_token_config.clear_stylizers();
 5251
 5252        let new_global_semantic_tokens_mode =
 5253            all_language_settings(None, cx).defaults.semantic_tokens;
 5254        if self
 5255            .semantic_token_config
 5256            .update_global_mode(new_global_semantic_tokens_mode)
 5257        {
 5258            self.restart_all_language_servers(cx);
 5259        }
 5260
 5261        cx.notify();
 5262    }
 5263
 5264    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 5265        let buffer_store = self.buffer_store.clone();
 5266        let Some(local) = self.as_local_mut() else {
 5267            return;
 5268        };
 5269        let mut adapters = BTreeMap::default();
 5270        let get_adapter = {
 5271            let languages = local.languages.clone();
 5272            let environment = local.environment.clone();
 5273            let weak = local.weak.clone();
 5274            let worktree_store = local.worktree_store.clone();
 5275            let http_client = local.http_client.clone();
 5276            let fs = local.fs.clone();
 5277            move |worktree_id, cx: &mut App| {
 5278                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 5279                Some(LocalLspAdapterDelegate::new(
 5280                    languages.clone(),
 5281                    &environment,
 5282                    weak.clone(),
 5283                    &worktree,
 5284                    http_client.clone(),
 5285                    fs.clone(),
 5286                    cx,
 5287                ))
 5288            }
 5289        };
 5290
 5291        let mut messages_to_report = Vec::new();
 5292        let (new_tree, to_stop) = {
 5293            let mut rebase = local.lsp_tree.rebase();
 5294            let buffers = buffer_store
 5295                .read(cx)
 5296                .buffers()
 5297                .filter_map(|buffer| {
 5298                    let raw_buffer = buffer.read(cx);
 5299                    if !local
 5300                        .registered_buffers
 5301                        .contains_key(&raw_buffer.remote_id())
 5302                    {
 5303                        return None;
 5304                    }
 5305                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5306                    let language = raw_buffer.language().cloned()?;
 5307                    Some((file, language, raw_buffer.remote_id()))
 5308                })
 5309                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5310            for (file, language, buffer_id) in buffers {
 5311                let worktree_id = file.worktree_id(cx);
 5312                let Some(worktree) = local
 5313                    .worktree_store
 5314                    .read(cx)
 5315                    .worktree_for_id(worktree_id, cx)
 5316                else {
 5317                    continue;
 5318                };
 5319
 5320                if let Some((_, apply)) = local.reuse_existing_language_server(
 5321                    rebase.server_tree(),
 5322                    &worktree,
 5323                    &language.name(),
 5324                    cx,
 5325                ) {
 5326                    (apply)(rebase.server_tree());
 5327                } else if let Some(lsp_delegate) = adapters
 5328                    .entry(worktree_id)
 5329                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5330                    .clone()
 5331                {
 5332                    let delegate =
 5333                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5334                    let path = file
 5335                        .path()
 5336                        .parent()
 5337                        .map(Arc::from)
 5338                        .unwrap_or_else(|| file.path().clone());
 5339                    let worktree_path = ProjectPath { worktree_id, path };
 5340                    let abs_path = file.abs_path(cx);
 5341                    let nodes = rebase
 5342                        .walk(
 5343                            worktree_path,
 5344                            language.name(),
 5345                            language.manifest(),
 5346                            delegate.clone(),
 5347                            cx,
 5348                        )
 5349                        .collect::<Vec<_>>();
 5350                    for node in nodes {
 5351                        let server_id = node.server_id_or_init(|disposition| {
 5352                            let path = &disposition.path;
 5353                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5354                            let key = LanguageServerSeed {
 5355                                worktree_id,
 5356                                name: disposition.server_name.clone(),
 5357                                settings: LanguageServerSeedSettings {
 5358                                    binary: disposition.settings.binary.clone(),
 5359                                    initialization_options: disposition
 5360                                        .settings
 5361                                        .initialization_options
 5362                                        .clone(),
 5363                                },
 5364                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5365                                    path.worktree_id,
 5366                                    &path.path,
 5367                                    language.name(),
 5368                                ),
 5369                            };
 5370                            local.language_server_ids.remove(&key);
 5371
 5372                            let server_id = local.get_or_insert_language_server(
 5373                                &worktree,
 5374                                lsp_delegate.clone(),
 5375                                disposition,
 5376                                &language.name(),
 5377                                cx,
 5378                            );
 5379                            if let Some(state) = local.language_servers.get(&server_id)
 5380                                && let Ok(uri) = uri
 5381                            {
 5382                                state.add_workspace_folder(uri);
 5383                            };
 5384                            server_id
 5385                        });
 5386
 5387                        if let Some(language_server_id) = server_id {
 5388                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5389                                language_server_id,
 5390                                name: node.name(),
 5391                                message:
 5392                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5393                                        proto::RegisteredForBuffer {
 5394                                            buffer_abs_path: abs_path
 5395                                                .to_string_lossy()
 5396                                                .into_owned(),
 5397                                            buffer_id: buffer_id.to_proto(),
 5398                                        },
 5399                                    ),
 5400                            });
 5401                        }
 5402                    }
 5403                } else {
 5404                    continue;
 5405                }
 5406            }
 5407            rebase.finish()
 5408        };
 5409        for message in messages_to_report {
 5410            cx.emit(message);
 5411        }
 5412        local.lsp_tree = new_tree;
 5413        for (id, _) in to_stop {
 5414            self.stop_local_language_server(id, cx).detach();
 5415        }
 5416    }
 5417
 5418    pub fn apply_code_action(
 5419        &self,
 5420        buffer_handle: Entity<Buffer>,
 5421        mut action: CodeAction,
 5422        push_to_history: bool,
 5423        cx: &mut Context<Self>,
 5424    ) -> Task<Result<ProjectTransaction>> {
 5425        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5426            let request = proto::ApplyCodeAction {
 5427                project_id,
 5428                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5429                action: Some(Self::serialize_code_action(&action)),
 5430            };
 5431            let buffer_store = self.buffer_store();
 5432            cx.spawn(async move |_, cx| {
 5433                let response = upstream_client
 5434                    .request(request)
 5435                    .await?
 5436                    .transaction
 5437                    .context("missing transaction")?;
 5438
 5439                buffer_store
 5440                    .update(cx, |buffer_store, cx| {
 5441                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5442                    })
 5443                    .await
 5444            })
 5445        } else if self.mode.is_local() {
 5446            let Some((_, lang_server, request_timeout)) = buffer_handle.update(cx, |buffer, cx| {
 5447                let request_timeout = ProjectSettings::get_global(cx)
 5448                    .global_lsp_settings
 5449                    .get_request_timeout();
 5450                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5451                    .map(|(adapter, server)| (adapter.clone(), server.clone(), request_timeout))
 5452            }) else {
 5453                return Task::ready(Ok(ProjectTransaction::default()));
 5454            };
 5455
 5456            cx.spawn(async move |this, cx| {
 5457                LocalLspStore::try_resolve_code_action(&lang_server, &mut action, request_timeout)
 5458                    .await
 5459                    .context("resolving a code action")?;
 5460                if let Some(edit) = action.lsp_action.edit()
 5461                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5462                        return LocalLspStore::deserialize_workspace_edit(
 5463                            this.upgrade().context("no app present")?,
 5464                            edit.clone(),
 5465                            push_to_history,
 5466
 5467                            lang_server.clone(),
 5468                            cx,
 5469                        )
 5470                        .await;
 5471                    }
 5472
 5473                let Some(command) = action.lsp_action.command() else {
 5474                    return Ok(ProjectTransaction::default())
 5475                };
 5476
 5477                let server_capabilities = lang_server.capabilities();
 5478                let available_commands = server_capabilities
 5479                    .execute_command_provider
 5480                    .as_ref()
 5481                    .map(|options| options.commands.as_slice())
 5482                    .unwrap_or_default();
 5483
 5484                if !available_commands.contains(&command.command) {
 5485                    log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5486                    return Ok(ProjectTransaction::default())
 5487                }
 5488
 5489                let request_timeout = cx.update(|app|
 5490                    ProjectSettings::get_global(app)
 5491                    .global_lsp_settings
 5492                    .get_request_timeout()
 5493                );
 5494
 5495                this.update(cx, |this, _| {
 5496                    this.as_local_mut()
 5497                        .unwrap()
 5498                        .last_workspace_edits_by_language_server
 5499                        .remove(&lang_server.server_id());
 5500                })?;
 5501
 5502                let _result = lang_server
 5503                    .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5504                        command: command.command.clone(),
 5505                        arguments: command.arguments.clone().unwrap_or_default(),
 5506                        ..lsp::ExecuteCommandParams::default()
 5507                    }, request_timeout)
 5508                    .await.into_response()
 5509                    .context("execute command")?;
 5510
 5511                return this.update(cx, |this, _| {
 5512                    this.as_local_mut()
 5513                        .unwrap()
 5514                        .last_workspace_edits_by_language_server
 5515                        .remove(&lang_server.server_id())
 5516                        .unwrap_or_default()
 5517                });
 5518            })
 5519        } else {
 5520            Task::ready(Err(anyhow!("no upstream client and not local")))
 5521        }
 5522    }
 5523
 5524    pub fn apply_code_action_kind(
 5525        &mut self,
 5526        buffers: HashSet<Entity<Buffer>>,
 5527        kind: CodeActionKind,
 5528        push_to_history: bool,
 5529        cx: &mut Context<Self>,
 5530    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5531        if self.as_local().is_some() {
 5532            cx.spawn(async move |lsp_store, cx| {
 5533                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5534                let result = LocalLspStore::execute_code_action_kind_locally(
 5535                    lsp_store.clone(),
 5536                    buffers,
 5537                    kind,
 5538                    push_to_history,
 5539                    cx,
 5540                )
 5541                .await;
 5542                lsp_store.update(cx, |lsp_store, _| {
 5543                    lsp_store.update_last_formatting_failure(&result);
 5544                })?;
 5545                result
 5546            })
 5547        } else if let Some((client, project_id)) = self.upstream_client() {
 5548            let buffer_store = self.buffer_store();
 5549            cx.spawn(async move |lsp_store, cx| {
 5550                let result = client
 5551                    .request(proto::ApplyCodeActionKind {
 5552                        project_id,
 5553                        kind: kind.as_str().to_owned(),
 5554                        buffer_ids: buffers
 5555                            .iter()
 5556                            .map(|buffer| {
 5557                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5558                            })
 5559                            .collect(),
 5560                    })
 5561                    .await
 5562                    .and_then(|result| result.transaction.context("missing transaction"));
 5563                lsp_store.update(cx, |lsp_store, _| {
 5564                    lsp_store.update_last_formatting_failure(&result);
 5565                })?;
 5566
 5567                let transaction_response = result?;
 5568                buffer_store
 5569                    .update(cx, |buffer_store, cx| {
 5570                        buffer_store.deserialize_project_transaction(
 5571                            transaction_response,
 5572                            push_to_history,
 5573                            cx,
 5574                        )
 5575                    })
 5576                    .await
 5577            })
 5578        } else {
 5579            Task::ready(Ok(ProjectTransaction::default()))
 5580        }
 5581    }
 5582
 5583    pub fn resolved_hint(
 5584        &mut self,
 5585        buffer_id: BufferId,
 5586        id: InlayId,
 5587        cx: &mut Context<Self>,
 5588    ) -> Option<ResolvedHint> {
 5589        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5590
 5591        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5592        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5593        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5594        let (server_id, resolve_data) = match &hint.resolve_state {
 5595            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5596            ResolveState::Resolving => {
 5597                return Some(ResolvedHint::Resolving(
 5598                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5599                ));
 5600            }
 5601            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5602        };
 5603
 5604        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5605        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5606        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5607            id,
 5608            cx.spawn(async move |lsp_store, cx| {
 5609                let resolved_hint = resolve_task.await;
 5610                lsp_store
 5611                    .update(cx, |lsp_store, _| {
 5612                        if let Some(old_inlay_hint) = lsp_store
 5613                            .lsp_data
 5614                            .get_mut(&buffer_id)
 5615                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5616                        {
 5617                            match resolved_hint {
 5618                                Ok(resolved_hint) => {
 5619                                    *old_inlay_hint = resolved_hint;
 5620                                }
 5621                                Err(e) => {
 5622                                    old_inlay_hint.resolve_state =
 5623                                        ResolveState::CanResolve(server_id, resolve_data);
 5624                                    log::error!("Inlay hint resolve failed: {e:#}");
 5625                                }
 5626                            }
 5627                        }
 5628                    })
 5629                    .ok();
 5630            })
 5631            .shared(),
 5632        );
 5633        debug_assert!(
 5634            previous_task.is_none(),
 5635            "Did not change hint's resolve state after spawning its resolve"
 5636        );
 5637        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5638        None
 5639    }
 5640
 5641    pub(crate) fn linked_edits(
 5642        &mut self,
 5643        buffer: &Entity<Buffer>,
 5644        position: Anchor,
 5645        cx: &mut Context<Self>,
 5646    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5647        let snapshot = buffer.read(cx).snapshot();
 5648        let scope = snapshot.language_scope_at(position);
 5649        let Some(server_id) = self
 5650            .as_local()
 5651            .and_then(|local| {
 5652                buffer.update(cx, |buffer, cx| {
 5653                    local
 5654                        .language_servers_for_buffer(buffer, cx)
 5655                        .filter(|(_, server)| {
 5656                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5657                        })
 5658                        .filter(|(adapter, _)| {
 5659                            scope
 5660                                .as_ref()
 5661                                .map(|scope| scope.language_allowed(&adapter.name))
 5662                                .unwrap_or(true)
 5663                        })
 5664                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5665                        .next()
 5666                })
 5667            })
 5668            .or_else(|| {
 5669                self.upstream_client()
 5670                    .is_some()
 5671                    .then_some(LanguageServerToQuery::FirstCapable)
 5672            })
 5673            .filter(|_| {
 5674                maybe!({
 5675                    buffer.read(cx).language_at(position)?;
 5676                    Some(
 5677                        LanguageSettings::for_buffer_at(&buffer.read(cx), position, cx)
 5678                            .linked_edits,
 5679                    )
 5680                }) == Some(true)
 5681            })
 5682        else {
 5683            return Task::ready(Ok(Vec::new()));
 5684        };
 5685
 5686        self.request_lsp(
 5687            buffer.clone(),
 5688            server_id,
 5689            LinkedEditingRange { position },
 5690            cx,
 5691        )
 5692    }
 5693
 5694    fn apply_on_type_formatting(
 5695        &mut self,
 5696        buffer: Entity<Buffer>,
 5697        position: Anchor,
 5698        trigger: String,
 5699        cx: &mut Context<Self>,
 5700    ) -> Task<Result<Option<Transaction>>> {
 5701        if let Some((client, project_id)) = self.upstream_client() {
 5702            if !self.check_if_capable_for_proto_request(
 5703                &buffer,
 5704                |capabilities| {
 5705                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5706                },
 5707                cx,
 5708            ) {
 5709                return Task::ready(Ok(None));
 5710            }
 5711            let request = proto::OnTypeFormatting {
 5712                project_id,
 5713                buffer_id: buffer.read(cx).remote_id().into(),
 5714                position: Some(serialize_anchor(&position)),
 5715                trigger,
 5716                version: serialize_version(&buffer.read(cx).version()),
 5717            };
 5718            cx.background_spawn(async move {
 5719                client
 5720                    .request(request)
 5721                    .await?
 5722                    .transaction
 5723                    .map(language::proto::deserialize_transaction)
 5724                    .transpose()
 5725            })
 5726        } else if let Some(local) = self.as_local_mut() {
 5727            let buffer_id = buffer.read(cx).remote_id();
 5728            local.buffers_being_formatted.insert(buffer_id);
 5729            cx.spawn(async move |this, cx| {
 5730                let _cleanup = defer({
 5731                    let this = this.clone();
 5732                    let mut cx = cx.clone();
 5733                    move || {
 5734                        this.update(&mut cx, |this, _| {
 5735                            if let Some(local) = this.as_local_mut() {
 5736                                local.buffers_being_formatted.remove(&buffer_id);
 5737                            }
 5738                        })
 5739                        .ok();
 5740                    }
 5741                });
 5742
 5743                buffer
 5744                    .update(cx, |buffer, _| {
 5745                        buffer.wait_for_edits(Some(position.timestamp()))
 5746                    })
 5747                    .await?;
 5748                this.update(cx, |this, cx| {
 5749                    let position = position.to_point_utf16(buffer.read(cx));
 5750                    this.on_type_format(buffer, position, trigger, false, cx)
 5751                })?
 5752                .await
 5753            })
 5754        } else {
 5755            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5756        }
 5757    }
 5758
 5759    pub fn on_type_format<T: ToPointUtf16>(
 5760        &mut self,
 5761        buffer: Entity<Buffer>,
 5762        position: T,
 5763        trigger: String,
 5764        push_to_history: bool,
 5765        cx: &mut Context<Self>,
 5766    ) -> Task<Result<Option<Transaction>>> {
 5767        let position = position.to_point_utf16(buffer.read(cx));
 5768        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5769    }
 5770
 5771    fn on_type_format_impl(
 5772        &mut self,
 5773        buffer: Entity<Buffer>,
 5774        position: PointUtf16,
 5775        trigger: String,
 5776        push_to_history: bool,
 5777        cx: &mut Context<Self>,
 5778    ) -> Task<Result<Option<Transaction>>> {
 5779        let options = buffer.update(cx, |buffer, cx| {
 5780            lsp_command::lsp_formatting_options(
 5781                LanguageSettings::for_buffer_at(buffer, position, cx).as_ref(),
 5782            )
 5783        });
 5784
 5785        cx.spawn(async move |this, cx| {
 5786            if let Some(waiter) =
 5787                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5788            {
 5789                waiter.await?;
 5790            }
 5791            cx.update(|cx| {
 5792                this.update(cx, |this, cx| {
 5793                    this.request_lsp(
 5794                        buffer.clone(),
 5795                        LanguageServerToQuery::FirstCapable,
 5796                        OnTypeFormatting {
 5797                            position,
 5798                            trigger,
 5799                            options,
 5800                            push_to_history,
 5801                        },
 5802                        cx,
 5803                    )
 5804                })
 5805            })?
 5806            .await
 5807        })
 5808    }
 5809
 5810    pub fn definitions(
 5811        &mut self,
 5812        buffer: &Entity<Buffer>,
 5813        position: PointUtf16,
 5814        cx: &mut Context<Self>,
 5815    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5816        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5817            let request = GetDefinitions { position };
 5818            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5819                return Task::ready(Ok(None));
 5820            }
 5821
 5822            let request_timeout = ProjectSettings::get_global(cx)
 5823                .global_lsp_settings
 5824                .get_request_timeout();
 5825
 5826            let request_task = upstream_client.request_lsp(
 5827                project_id,
 5828                None,
 5829                request_timeout,
 5830                cx.background_executor().clone(),
 5831                request.to_proto(project_id, buffer.read(cx)),
 5832            );
 5833            let buffer = buffer.clone();
 5834            cx.spawn(async move |weak_lsp_store, cx| {
 5835                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5836                    return Ok(None);
 5837                };
 5838                let Some(responses) = request_task.await? else {
 5839                    return Ok(None);
 5840                };
 5841                let actions = join_all(responses.payload.into_iter().map(|response| {
 5842                    GetDefinitions { position }.response_from_proto(
 5843                        response.response,
 5844                        lsp_store.clone(),
 5845                        buffer.clone(),
 5846                        cx.clone(),
 5847                    )
 5848                }))
 5849                .await;
 5850
 5851                Ok(Some(
 5852                    actions
 5853                        .into_iter()
 5854                        .collect::<Result<Vec<Vec<_>>>>()?
 5855                        .into_iter()
 5856                        .flatten()
 5857                        .dedup()
 5858                        .collect(),
 5859                ))
 5860            })
 5861        } else {
 5862            let definitions_task = self.request_multiple_lsp_locally(
 5863                buffer,
 5864                Some(position),
 5865                GetDefinitions { position },
 5866                cx,
 5867            );
 5868            cx.background_spawn(async move {
 5869                Ok(Some(
 5870                    definitions_task
 5871                        .await
 5872                        .into_iter()
 5873                        .flat_map(|(_, definitions)| definitions)
 5874                        .dedup()
 5875                        .collect(),
 5876                ))
 5877            })
 5878        }
 5879    }
 5880
 5881    pub fn declarations(
 5882        &mut self,
 5883        buffer: &Entity<Buffer>,
 5884        position: PointUtf16,
 5885        cx: &mut Context<Self>,
 5886    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5887        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5888            let request = GetDeclarations { position };
 5889            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5890                return Task::ready(Ok(None));
 5891            }
 5892            let request_timeout = ProjectSettings::get_global(cx)
 5893                .global_lsp_settings
 5894                .get_request_timeout();
 5895            let request_task = upstream_client.request_lsp(
 5896                project_id,
 5897                None,
 5898                request_timeout,
 5899                cx.background_executor().clone(),
 5900                request.to_proto(project_id, buffer.read(cx)),
 5901            );
 5902            let buffer = buffer.clone();
 5903            cx.spawn(async move |weak_lsp_store, cx| {
 5904                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5905                    return Ok(None);
 5906                };
 5907                let Some(responses) = request_task.await? else {
 5908                    return Ok(None);
 5909                };
 5910                let actions = join_all(responses.payload.into_iter().map(|response| {
 5911                    GetDeclarations { position }.response_from_proto(
 5912                        response.response,
 5913                        lsp_store.clone(),
 5914                        buffer.clone(),
 5915                        cx.clone(),
 5916                    )
 5917                }))
 5918                .await;
 5919
 5920                Ok(Some(
 5921                    actions
 5922                        .into_iter()
 5923                        .collect::<Result<Vec<Vec<_>>>>()?
 5924                        .into_iter()
 5925                        .flatten()
 5926                        .dedup()
 5927                        .collect(),
 5928                ))
 5929            })
 5930        } else {
 5931            let declarations_task = self.request_multiple_lsp_locally(
 5932                buffer,
 5933                Some(position),
 5934                GetDeclarations { position },
 5935                cx,
 5936            );
 5937            cx.background_spawn(async move {
 5938                Ok(Some(
 5939                    declarations_task
 5940                        .await
 5941                        .into_iter()
 5942                        .flat_map(|(_, declarations)| declarations)
 5943                        .dedup()
 5944                        .collect(),
 5945                ))
 5946            })
 5947        }
 5948    }
 5949
 5950    pub fn type_definitions(
 5951        &mut self,
 5952        buffer: &Entity<Buffer>,
 5953        position: PointUtf16,
 5954        cx: &mut Context<Self>,
 5955    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5956        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5957            let request = GetTypeDefinitions { position };
 5958            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5959                return Task::ready(Ok(None));
 5960            }
 5961            let request_timeout = ProjectSettings::get_global(cx)
 5962                .global_lsp_settings
 5963                .get_request_timeout();
 5964            let request_task = upstream_client.request_lsp(
 5965                project_id,
 5966                None,
 5967                request_timeout,
 5968                cx.background_executor().clone(),
 5969                request.to_proto(project_id, buffer.read(cx)),
 5970            );
 5971            let buffer = buffer.clone();
 5972            cx.spawn(async move |weak_lsp_store, cx| {
 5973                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5974                    return Ok(None);
 5975                };
 5976                let Some(responses) = request_task.await? else {
 5977                    return Ok(None);
 5978                };
 5979                let actions = join_all(responses.payload.into_iter().map(|response| {
 5980                    GetTypeDefinitions { position }.response_from_proto(
 5981                        response.response,
 5982                        lsp_store.clone(),
 5983                        buffer.clone(),
 5984                        cx.clone(),
 5985                    )
 5986                }))
 5987                .await;
 5988
 5989                Ok(Some(
 5990                    actions
 5991                        .into_iter()
 5992                        .collect::<Result<Vec<Vec<_>>>>()?
 5993                        .into_iter()
 5994                        .flatten()
 5995                        .dedup()
 5996                        .collect(),
 5997                ))
 5998            })
 5999        } else {
 6000            let type_definitions_task = self.request_multiple_lsp_locally(
 6001                buffer,
 6002                Some(position),
 6003                GetTypeDefinitions { position },
 6004                cx,
 6005            );
 6006            cx.background_spawn(async move {
 6007                Ok(Some(
 6008                    type_definitions_task
 6009                        .await
 6010                        .into_iter()
 6011                        .flat_map(|(_, type_definitions)| type_definitions)
 6012                        .dedup()
 6013                        .collect(),
 6014                ))
 6015            })
 6016        }
 6017    }
 6018
 6019    pub fn implementations(
 6020        &mut self,
 6021        buffer: &Entity<Buffer>,
 6022        position: PointUtf16,
 6023        cx: &mut Context<Self>,
 6024    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 6025        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6026            let request = GetImplementations { position };
 6027            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6028                return Task::ready(Ok(None));
 6029            }
 6030
 6031            let request_timeout = ProjectSettings::get_global(cx)
 6032                .global_lsp_settings
 6033                .get_request_timeout();
 6034            let request_task = upstream_client.request_lsp(
 6035                project_id,
 6036                None,
 6037                request_timeout,
 6038                cx.background_executor().clone(),
 6039                request.to_proto(project_id, buffer.read(cx)),
 6040            );
 6041            let buffer = buffer.clone();
 6042            cx.spawn(async move |weak_lsp_store, cx| {
 6043                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6044                    return Ok(None);
 6045                };
 6046                let Some(responses) = request_task.await? else {
 6047                    return Ok(None);
 6048                };
 6049                let actions = join_all(responses.payload.into_iter().map(|response| {
 6050                    GetImplementations { position }.response_from_proto(
 6051                        response.response,
 6052                        lsp_store.clone(),
 6053                        buffer.clone(),
 6054                        cx.clone(),
 6055                    )
 6056                }))
 6057                .await;
 6058
 6059                Ok(Some(
 6060                    actions
 6061                        .into_iter()
 6062                        .collect::<Result<Vec<Vec<_>>>>()?
 6063                        .into_iter()
 6064                        .flatten()
 6065                        .dedup()
 6066                        .collect(),
 6067                ))
 6068            })
 6069        } else {
 6070            let implementations_task = self.request_multiple_lsp_locally(
 6071                buffer,
 6072                Some(position),
 6073                GetImplementations { position },
 6074                cx,
 6075            );
 6076            cx.background_spawn(async move {
 6077                Ok(Some(
 6078                    implementations_task
 6079                        .await
 6080                        .into_iter()
 6081                        .flat_map(|(_, implementations)| implementations)
 6082                        .dedup()
 6083                        .collect(),
 6084                ))
 6085            })
 6086        }
 6087    }
 6088
 6089    pub fn references(
 6090        &mut self,
 6091        buffer: &Entity<Buffer>,
 6092        position: PointUtf16,
 6093        cx: &mut Context<Self>,
 6094    ) -> Task<Result<Option<Vec<Location>>>> {
 6095        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6096            let request = GetReferences { position };
 6097            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6098                return Task::ready(Ok(None));
 6099            }
 6100
 6101            let request_timeout = ProjectSettings::get_global(cx)
 6102                .global_lsp_settings
 6103                .get_request_timeout();
 6104            let request_task = upstream_client.request_lsp(
 6105                project_id,
 6106                None,
 6107                request_timeout,
 6108                cx.background_executor().clone(),
 6109                request.to_proto(project_id, buffer.read(cx)),
 6110            );
 6111            let buffer = buffer.clone();
 6112            cx.spawn(async move |weak_lsp_store, cx| {
 6113                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6114                    return Ok(None);
 6115                };
 6116                let Some(responses) = request_task.await? else {
 6117                    return Ok(None);
 6118                };
 6119
 6120                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 6121                    GetReferences { position }.response_from_proto(
 6122                        lsp_response.response,
 6123                        lsp_store.clone(),
 6124                        buffer.clone(),
 6125                        cx.clone(),
 6126                    )
 6127                }))
 6128                .await
 6129                .into_iter()
 6130                .collect::<Result<Vec<Vec<_>>>>()?
 6131                .into_iter()
 6132                .flatten()
 6133                .dedup()
 6134                .collect();
 6135                Ok(Some(locations))
 6136            })
 6137        } else {
 6138            let references_task = self.request_multiple_lsp_locally(
 6139                buffer,
 6140                Some(position),
 6141                GetReferences { position },
 6142                cx,
 6143            );
 6144            cx.background_spawn(async move {
 6145                Ok(Some(
 6146                    references_task
 6147                        .await
 6148                        .into_iter()
 6149                        .flat_map(|(_, references)| references)
 6150                        .dedup()
 6151                        .collect(),
 6152                ))
 6153            })
 6154        }
 6155    }
 6156
 6157    pub fn code_actions(
 6158        &mut self,
 6159        buffer: &Entity<Buffer>,
 6160        range: Range<Anchor>,
 6161        kinds: Option<Vec<CodeActionKind>>,
 6162        cx: &mut Context<Self>,
 6163    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6164        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6165            let request = GetCodeActions {
 6166                range: range.clone(),
 6167                kinds: kinds.clone(),
 6168            };
 6169            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6170                return Task::ready(Ok(None));
 6171            }
 6172            let request_timeout = ProjectSettings::get_global(cx)
 6173                .global_lsp_settings
 6174                .get_request_timeout();
 6175            let request_task = upstream_client.request_lsp(
 6176                project_id,
 6177                None,
 6178                request_timeout,
 6179                cx.background_executor().clone(),
 6180                request.to_proto(project_id, buffer.read(cx)),
 6181            );
 6182            let buffer = buffer.clone();
 6183            cx.spawn(async move |weak_lsp_store, cx| {
 6184                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6185                    return Ok(None);
 6186                };
 6187                let Some(responses) = request_task.await? else {
 6188                    return Ok(None);
 6189                };
 6190                let actions = join_all(responses.payload.into_iter().map(|response| {
 6191                    GetCodeActions {
 6192                        range: range.clone(),
 6193                        kinds: kinds.clone(),
 6194                    }
 6195                    .response_from_proto(
 6196                        response.response,
 6197                        lsp_store.clone(),
 6198                        buffer.clone(),
 6199                        cx.clone(),
 6200                    )
 6201                }))
 6202                .await;
 6203
 6204                Ok(Some(
 6205                    actions
 6206                        .into_iter()
 6207                        .collect::<Result<Vec<Vec<_>>>>()?
 6208                        .into_iter()
 6209                        .flatten()
 6210                        .collect(),
 6211                ))
 6212            })
 6213        } else {
 6214            let all_actions_task = self.request_multiple_lsp_locally(
 6215                buffer,
 6216                Some(range.start),
 6217                GetCodeActions { range, kinds },
 6218                cx,
 6219            );
 6220            cx.background_spawn(async move {
 6221                Ok(Some(
 6222                    all_actions_task
 6223                        .await
 6224                        .into_iter()
 6225                        .flat_map(|(_, actions)| actions)
 6226                        .collect(),
 6227                ))
 6228            })
 6229        }
 6230    }
 6231
 6232    #[inline(never)]
 6233    pub fn completions(
 6234        &self,
 6235        buffer: &Entity<Buffer>,
 6236        position: PointUtf16,
 6237        context: CompletionContext,
 6238        cx: &mut Context<Self>,
 6239    ) -> Task<Result<Vec<CompletionResponse>>> {
 6240        let language_registry = self.languages.clone();
 6241
 6242        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6243            let snapshot = buffer.read(cx).snapshot();
 6244            let offset = position.to_offset(&snapshot);
 6245            let scope = snapshot.language_scope_at(offset);
 6246            let capable_lsps = self.all_capable_for_proto_request(
 6247                buffer,
 6248                |server_name, capabilities| {
 6249                    capabilities.completion_provider.is_some()
 6250                        && scope
 6251                            .as_ref()
 6252                            .map(|scope| scope.language_allowed(server_name))
 6253                            .unwrap_or(true)
 6254                },
 6255                cx,
 6256            );
 6257            if capable_lsps.is_empty() {
 6258                return Task::ready(Ok(Vec::new()));
 6259            }
 6260
 6261            let language = buffer.read(cx).language().cloned();
 6262
 6263            let buffer = buffer.clone();
 6264
 6265            cx.spawn(async move |this, cx| {
 6266                let requests = join_all(
 6267                    capable_lsps
 6268                        .into_iter()
 6269                        .map(|(id, server_name)| {
 6270                            let request = GetCompletions {
 6271                                position,
 6272                                context: context.clone(),
 6273                                server_id: Some(id),
 6274                            };
 6275                            let buffer = buffer.clone();
 6276                            let language = language.clone();
 6277                            let lsp_adapter = language.as_ref().and_then(|language| {
 6278                                let adapters = language_registry.lsp_adapters(&language.name());
 6279                                adapters
 6280                                    .iter()
 6281                                    .find(|adapter| adapter.name() == server_name)
 6282                                    .or_else(|| adapters.first())
 6283                                    .cloned()
 6284                            });
 6285                            let upstream_client = upstream_client.clone();
 6286                            let response = this
 6287                                .update(cx, |this, cx| {
 6288                                    this.send_lsp_proto_request(
 6289                                        buffer,
 6290                                        upstream_client,
 6291                                        project_id,
 6292                                        request,
 6293                                        cx,
 6294                                    )
 6295                                })
 6296                                .log_err();
 6297                            async move {
 6298                                let response = response?.await.log_err()?;
 6299
 6300                                let completions = populate_labels_for_completions(
 6301                                    response.completions,
 6302                                    language,
 6303                                    lsp_adapter,
 6304                                )
 6305                                .await;
 6306
 6307                                Some(CompletionResponse {
 6308                                    completions,
 6309                                    display_options: CompletionDisplayOptions::default(),
 6310                                    is_incomplete: response.is_incomplete,
 6311                                })
 6312                            }
 6313                        })
 6314                        .collect::<Vec<_>>(),
 6315                );
 6316                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6317            })
 6318        } else if let Some(local) = self.as_local() {
 6319            let snapshot = buffer.read(cx).snapshot();
 6320            let offset = position.to_offset(&snapshot);
 6321            let scope = snapshot.language_scope_at(offset);
 6322            let language = snapshot.language().cloned();
 6323            let completion_settings = LanguageSettings::for_buffer(&buffer.read(cx), cx)
 6324                .completions
 6325                .clone();
 6326            if !completion_settings.lsp {
 6327                return Task::ready(Ok(Vec::new()));
 6328            }
 6329
 6330            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6331                local
 6332                    .language_servers_for_buffer(buffer, cx)
 6333                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6334                    .filter(|(adapter, _)| {
 6335                        scope
 6336                            .as_ref()
 6337                            .map(|scope| scope.language_allowed(&adapter.name))
 6338                            .unwrap_or(true)
 6339                    })
 6340                    .map(|(_, server)| server.server_id())
 6341                    .collect()
 6342            });
 6343
 6344            let buffer = buffer.clone();
 6345            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6346            let lsp_timeout = if lsp_timeout > 0 {
 6347                Some(Duration::from_millis(lsp_timeout))
 6348            } else {
 6349                None
 6350            };
 6351            cx.spawn(async move |this,  cx| {
 6352                let mut tasks = Vec::with_capacity(server_ids.len());
 6353                this.update(cx, |lsp_store, cx| {
 6354                    for server_id in server_ids {
 6355                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6356                        let lsp_timeout = lsp_timeout
 6357                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6358                        let mut timeout = cx.background_spawn(async move {
 6359                            match lsp_timeout {
 6360                                Some(lsp_timeout) => {
 6361                                    lsp_timeout.await;
 6362                                    true
 6363                                },
 6364                                None => false,
 6365                            }
 6366                        }).fuse();
 6367                        let mut lsp_request = lsp_store.request_lsp(
 6368                            buffer.clone(),
 6369                            LanguageServerToQuery::Other(server_id),
 6370                            GetCompletions {
 6371                                position,
 6372                                context: context.clone(),
 6373                                server_id: Some(server_id),
 6374                            },
 6375                            cx,
 6376                        ).fuse();
 6377                        let new_task = cx.background_spawn(async move {
 6378                            select_biased! {
 6379                                response = lsp_request => anyhow::Ok(Some(response?)),
 6380                                timeout_happened = timeout => {
 6381                                    if timeout_happened {
 6382                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6383                                        Ok(None)
 6384                                    } else {
 6385                                        let completions = lsp_request.await?;
 6386                                        Ok(Some(completions))
 6387                                    }
 6388                                },
 6389                            }
 6390                        });
 6391                        tasks.push((lsp_adapter, new_task));
 6392                    }
 6393                })?;
 6394
 6395                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6396                    let completion_response = task.await.ok()??;
 6397                    let completions = populate_labels_for_completions(
 6398                            completion_response.completions,
 6399                            language.clone(),
 6400                            lsp_adapter,
 6401                        )
 6402                        .await;
 6403                    Some(CompletionResponse {
 6404                        completions,
 6405                        display_options: CompletionDisplayOptions::default(),
 6406                        is_incomplete: completion_response.is_incomplete,
 6407                    })
 6408                });
 6409
 6410                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6411
 6412                Ok(responses.into_iter().flatten().collect())
 6413            })
 6414        } else {
 6415            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6416        }
 6417    }
 6418
 6419    pub fn resolve_completions(
 6420        &self,
 6421        buffer: Entity<Buffer>,
 6422        completion_indices: Vec<usize>,
 6423        completions: Rc<RefCell<Box<[Completion]>>>,
 6424        cx: &mut Context<Self>,
 6425    ) -> Task<Result<bool>> {
 6426        let client = self.upstream_client();
 6427        let buffer_id = buffer.read(cx).remote_id();
 6428        let buffer_snapshot = buffer.read(cx).snapshot();
 6429
 6430        if !self.check_if_capable_for_proto_request(
 6431            &buffer,
 6432            GetCompletions::can_resolve_completions,
 6433            cx,
 6434        ) {
 6435            return Task::ready(Ok(false));
 6436        }
 6437        cx.spawn(async move |lsp_store, cx| {
 6438            let request_timeout = cx.update(|app| {
 6439                ProjectSettings::get_global(app)
 6440                    .global_lsp_settings
 6441                    .get_request_timeout()
 6442            });
 6443
 6444            let mut did_resolve = false;
 6445            if let Some((client, project_id)) = client {
 6446                for completion_index in completion_indices {
 6447                    let server_id = {
 6448                        let completion = &completions.borrow()[completion_index];
 6449                        completion.source.server_id()
 6450                    };
 6451                    if let Some(server_id) = server_id {
 6452                        if Self::resolve_completion_remote(
 6453                            project_id,
 6454                            server_id,
 6455                            buffer_id,
 6456                            completions.clone(),
 6457                            completion_index,
 6458                            client.clone(),
 6459                        )
 6460                        .await
 6461                        .log_err()
 6462                        .is_some()
 6463                        {
 6464                            did_resolve = true;
 6465                        }
 6466                    } else {
 6467                        resolve_word_completion(
 6468                            &buffer_snapshot,
 6469                            &mut completions.borrow_mut()[completion_index],
 6470                        );
 6471                    }
 6472                }
 6473            } else {
 6474                for completion_index in completion_indices {
 6475                    let server_id = {
 6476                        let completion = &completions.borrow()[completion_index];
 6477                        completion.source.server_id()
 6478                    };
 6479                    if let Some(server_id) = server_id {
 6480                        let server_and_adapter = lsp_store
 6481                            .read_with(cx, |lsp_store, _| {
 6482                                let server = lsp_store.language_server_for_id(server_id)?;
 6483                                let adapter =
 6484                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6485                                Some((server, adapter))
 6486                            })
 6487                            .ok()
 6488                            .flatten();
 6489                        let Some((server, adapter)) = server_and_adapter else {
 6490                            continue;
 6491                        };
 6492
 6493                        let resolved = Self::resolve_completion_local(
 6494                            server,
 6495                            completions.clone(),
 6496                            completion_index,
 6497                            request_timeout,
 6498                        )
 6499                        .await
 6500                        .log_err()
 6501                        .is_some();
 6502                        if resolved {
 6503                            Self::regenerate_completion_labels(
 6504                                adapter,
 6505                                &buffer_snapshot,
 6506                                completions.clone(),
 6507                                completion_index,
 6508                            )
 6509                            .await
 6510                            .log_err();
 6511                            did_resolve = true;
 6512                        }
 6513                    } else {
 6514                        resolve_word_completion(
 6515                            &buffer_snapshot,
 6516                            &mut completions.borrow_mut()[completion_index],
 6517                        );
 6518                    }
 6519                }
 6520            }
 6521
 6522            Ok(did_resolve)
 6523        })
 6524    }
 6525
 6526    async fn resolve_completion_local(
 6527        server: Arc<lsp::LanguageServer>,
 6528        completions: Rc<RefCell<Box<[Completion]>>>,
 6529        completion_index: usize,
 6530        request_timeout: Duration,
 6531    ) -> Result<()> {
 6532        let server_id = server.server_id();
 6533        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6534            return Ok(());
 6535        }
 6536
 6537        let request = {
 6538            let completion = &completions.borrow()[completion_index];
 6539            match &completion.source {
 6540                CompletionSource::Lsp {
 6541                    lsp_completion,
 6542                    resolved,
 6543                    server_id: completion_server_id,
 6544                    ..
 6545                } => {
 6546                    if *resolved {
 6547                        return Ok(());
 6548                    }
 6549                    anyhow::ensure!(
 6550                        server_id == *completion_server_id,
 6551                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6552                    );
 6553                    server.request::<lsp::request::ResolveCompletionItem>(
 6554                        *lsp_completion.clone(),
 6555                        request_timeout,
 6556                    )
 6557                }
 6558                CompletionSource::BufferWord { .. }
 6559                | CompletionSource::Dap { .. }
 6560                | CompletionSource::Custom => {
 6561                    return Ok(());
 6562                }
 6563            }
 6564        };
 6565        let resolved_completion = request
 6566            .await
 6567            .into_response()
 6568            .context("resolve completion")?;
 6569
 6570        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6571        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6572
 6573        let mut completions = completions.borrow_mut();
 6574        let completion = &mut completions[completion_index];
 6575        if let CompletionSource::Lsp {
 6576            lsp_completion,
 6577            resolved,
 6578            server_id: completion_server_id,
 6579            ..
 6580        } = &mut completion.source
 6581        {
 6582            if *resolved {
 6583                return Ok(());
 6584            }
 6585            anyhow::ensure!(
 6586                server_id == *completion_server_id,
 6587                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6588            );
 6589            **lsp_completion = resolved_completion;
 6590            *resolved = true;
 6591        }
 6592        Ok(())
 6593    }
 6594
 6595    async fn regenerate_completion_labels(
 6596        adapter: Arc<CachedLspAdapter>,
 6597        snapshot: &BufferSnapshot,
 6598        completions: Rc<RefCell<Box<[Completion]>>>,
 6599        completion_index: usize,
 6600    ) -> Result<()> {
 6601        let completion_item = completions.borrow()[completion_index]
 6602            .source
 6603            .lsp_completion(true)
 6604            .map(Cow::into_owned);
 6605        if let Some(lsp_documentation) = completion_item
 6606            .as_ref()
 6607            .and_then(|completion_item| completion_item.documentation.clone())
 6608        {
 6609            let mut completions = completions.borrow_mut();
 6610            let completion = &mut completions[completion_index];
 6611            completion.documentation = Some(lsp_documentation.into());
 6612        } else {
 6613            let mut completions = completions.borrow_mut();
 6614            let completion = &mut completions[completion_index];
 6615            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6616        }
 6617
 6618        let mut new_label = match completion_item {
 6619            Some(completion_item) => {
 6620                // Some language servers always return `detail` lazily via resolve, regardless of
 6621                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6622                // See: https://github.com/yioneko/vtsls/issues/213
 6623                let language = snapshot.language();
 6624                match language {
 6625                    Some(language) => {
 6626                        adapter
 6627                            .labels_for_completions(
 6628                                std::slice::from_ref(&completion_item),
 6629                                language,
 6630                            )
 6631                            .await?
 6632                    }
 6633                    None => Vec::new(),
 6634                }
 6635                .pop()
 6636                .flatten()
 6637                .unwrap_or_else(|| {
 6638                    CodeLabel::fallback_for_completion(
 6639                        &completion_item,
 6640                        language.map(|language| language.as_ref()),
 6641                    )
 6642                })
 6643            }
 6644            None => CodeLabel::plain(
 6645                completions.borrow()[completion_index].new_text.clone(),
 6646                None,
 6647            ),
 6648        };
 6649        ensure_uniform_list_compatible_label(&mut new_label);
 6650
 6651        let mut completions = completions.borrow_mut();
 6652        let completion = &mut completions[completion_index];
 6653        if completion.label.filter_text() == new_label.filter_text() {
 6654            completion.label = new_label;
 6655        } else {
 6656            log::error!(
 6657                "Resolved completion changed display label from {} to {}. \
 6658                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6659                completion.label.text(),
 6660                new_label.text(),
 6661                completion.label.filter_text(),
 6662                new_label.filter_text()
 6663            );
 6664        }
 6665
 6666        Ok(())
 6667    }
 6668
 6669    async fn resolve_completion_remote(
 6670        project_id: u64,
 6671        server_id: LanguageServerId,
 6672        buffer_id: BufferId,
 6673        completions: Rc<RefCell<Box<[Completion]>>>,
 6674        completion_index: usize,
 6675        client: AnyProtoClient,
 6676    ) -> Result<()> {
 6677        let lsp_completion = {
 6678            let completion = &completions.borrow()[completion_index];
 6679            match &completion.source {
 6680                CompletionSource::Lsp {
 6681                    lsp_completion,
 6682                    resolved,
 6683                    server_id: completion_server_id,
 6684                    ..
 6685                } => {
 6686                    anyhow::ensure!(
 6687                        server_id == *completion_server_id,
 6688                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6689                    );
 6690                    if *resolved {
 6691                        return Ok(());
 6692                    }
 6693                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6694                }
 6695                CompletionSource::Custom
 6696                | CompletionSource::Dap { .. }
 6697                | CompletionSource::BufferWord { .. } => {
 6698                    return Ok(());
 6699                }
 6700            }
 6701        };
 6702        let request = proto::ResolveCompletionDocumentation {
 6703            project_id,
 6704            language_server_id: server_id.0 as u64,
 6705            lsp_completion,
 6706            buffer_id: buffer_id.into(),
 6707        };
 6708
 6709        let response = client
 6710            .request(request)
 6711            .await
 6712            .context("completion documentation resolve proto request")?;
 6713        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6714
 6715        let documentation = if response.documentation.is_empty() {
 6716            CompletionDocumentation::Undocumented
 6717        } else if response.documentation_is_markdown {
 6718            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6719        } else if response.documentation.lines().count() <= 1 {
 6720            CompletionDocumentation::SingleLine(response.documentation.into())
 6721        } else {
 6722            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6723        };
 6724
 6725        let mut completions = completions.borrow_mut();
 6726        let completion = &mut completions[completion_index];
 6727        completion.documentation = Some(documentation);
 6728        if let CompletionSource::Lsp {
 6729            insert_range,
 6730            lsp_completion,
 6731            resolved,
 6732            server_id: completion_server_id,
 6733            lsp_defaults: _,
 6734        } = &mut completion.source
 6735        {
 6736            let completion_insert_range = response
 6737                .old_insert_start
 6738                .and_then(deserialize_anchor)
 6739                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6740            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6741
 6742            if *resolved {
 6743                return Ok(());
 6744            }
 6745            anyhow::ensure!(
 6746                server_id == *completion_server_id,
 6747                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6748            );
 6749            **lsp_completion = resolved_lsp_completion;
 6750            *resolved = true;
 6751        }
 6752
 6753        let replace_range = response
 6754            .old_replace_start
 6755            .and_then(deserialize_anchor)
 6756            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6757        if let Some((old_replace_start, old_replace_end)) = replace_range
 6758            && !response.new_text.is_empty()
 6759        {
 6760            completion.new_text = response.new_text;
 6761            completion.replace_range = old_replace_start..old_replace_end;
 6762        }
 6763
 6764        Ok(())
 6765    }
 6766
 6767    pub fn apply_additional_edits_for_completion(
 6768        &self,
 6769        buffer_handle: Entity<Buffer>,
 6770        completions: Rc<RefCell<Box<[Completion]>>>,
 6771        completion_index: usize,
 6772        push_to_history: bool,
 6773        all_commit_ranges: Vec<Range<language::Anchor>>,
 6774        cx: &mut Context<Self>,
 6775    ) -> Task<Result<Option<Transaction>>> {
 6776        if let Some((client, project_id)) = self.upstream_client() {
 6777            let buffer = buffer_handle.read(cx);
 6778            let buffer_id = buffer.remote_id();
 6779            cx.spawn(async move |_, cx| {
 6780                let request = {
 6781                    let completion = completions.borrow()[completion_index].clone();
 6782                    proto::ApplyCompletionAdditionalEdits {
 6783                        project_id,
 6784                        buffer_id: buffer_id.into(),
 6785                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6786                            replace_range: completion.replace_range,
 6787                            new_text: completion.new_text,
 6788                            source: completion.source,
 6789                        })),
 6790                        all_commit_ranges: all_commit_ranges
 6791                            .iter()
 6792                            .cloned()
 6793                            .map(language::proto::serialize_anchor_range)
 6794                            .collect(),
 6795                    }
 6796                };
 6797
 6798                let Some(transaction) = client.request(request).await?.transaction else {
 6799                    return Ok(None);
 6800                };
 6801
 6802                let transaction = language::proto::deserialize_transaction(transaction)?;
 6803                buffer_handle
 6804                    .update(cx, |buffer, _| {
 6805                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6806                    })
 6807                    .await?;
 6808                if push_to_history {
 6809                    buffer_handle.update(cx, |buffer, _| {
 6810                        buffer.push_transaction(transaction.clone(), Instant::now());
 6811                        buffer.finalize_last_transaction();
 6812                    });
 6813                }
 6814                Ok(Some(transaction))
 6815            })
 6816        } else {
 6817            let request_timeout = ProjectSettings::get_global(cx)
 6818                .global_lsp_settings
 6819                .get_request_timeout();
 6820
 6821            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6822                let completion = &completions.borrow()[completion_index];
 6823                let server_id = completion.source.server_id()?;
 6824                Some(
 6825                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6826                        .1
 6827                        .clone(),
 6828                )
 6829            }) else {
 6830                return Task::ready(Ok(None));
 6831            };
 6832
 6833            cx.spawn(async move |this, cx| {
 6834                Self::resolve_completion_local(
 6835                    server.clone(),
 6836                    completions.clone(),
 6837                    completion_index,
 6838                    request_timeout,
 6839                )
 6840                .await
 6841                .context("resolving completion")?;
 6842                let completion = completions.borrow()[completion_index].clone();
 6843                let additional_text_edits = completion
 6844                    .source
 6845                    .lsp_completion(true)
 6846                    .as_ref()
 6847                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6848                if let Some(edits) = additional_text_edits {
 6849                    let edits = this
 6850                        .update(cx, |this, cx| {
 6851                            this.as_local_mut().unwrap().edits_from_lsp(
 6852                                &buffer_handle,
 6853                                edits,
 6854                                server.server_id(),
 6855                                None,
 6856                                cx,
 6857                            )
 6858                        })?
 6859                        .await?;
 6860
 6861                    buffer_handle.update(cx, |buffer, cx| {
 6862                        buffer.finalize_last_transaction();
 6863                        buffer.start_transaction();
 6864
 6865                        for (range, text) in edits {
 6866                            let primary = &completion.replace_range;
 6867
 6868                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6869                            // and the primary completion is just an insertion (empty range), then this is likely
 6870                            // an auto-import scenario and should not be considered overlapping
 6871                            // https://github.com/zed-industries/zed/issues/26136
 6872                            let is_file_start_auto_import = {
 6873                                let snapshot = buffer.snapshot();
 6874                                let primary_start_point = primary.start.to_point(&snapshot);
 6875                                let range_start_point = range.start.to_point(&snapshot);
 6876
 6877                                let result = primary_start_point.row == 0
 6878                                    && primary_start_point.column == 0
 6879                                    && range_start_point.row == 0
 6880                                    && range_start_point.column == 0;
 6881
 6882                                result
 6883                            };
 6884
 6885                            let has_overlap = if is_file_start_auto_import {
 6886                                false
 6887                            } else {
 6888                                all_commit_ranges.iter().any(|commit_range| {
 6889                                    let start_within =
 6890                                        commit_range.start.cmp(&range.start, buffer).is_le()
 6891                                            && commit_range.end.cmp(&range.start, buffer).is_ge();
 6892                                    let end_within =
 6893                                        range.start.cmp(&commit_range.end, buffer).is_le()
 6894                                            && range.end.cmp(&commit_range.end, buffer).is_ge();
 6895                                    start_within || end_within
 6896                                })
 6897                            };
 6898
 6899                            //Skip additional edits which overlap with the primary completion edit
 6900                            //https://github.com/zed-industries/zed/pull/1871
 6901                            if !has_overlap {
 6902                                buffer.edit([(range, text)], None, cx);
 6903                            }
 6904                        }
 6905
 6906                        let transaction = if buffer.end_transaction(cx).is_some() {
 6907                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6908                            if !push_to_history {
 6909                                buffer.forget_transaction(transaction.id);
 6910                            }
 6911                            Some(transaction)
 6912                        } else {
 6913                            None
 6914                        };
 6915                        Ok(transaction)
 6916                    })
 6917                } else {
 6918                    Ok(None)
 6919                }
 6920            })
 6921        }
 6922    }
 6923
 6924    pub fn pull_diagnostics(
 6925        &mut self,
 6926        buffer: Entity<Buffer>,
 6927        cx: &mut Context<Self>,
 6928    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6929        let buffer_id = buffer.read(cx).remote_id();
 6930
 6931        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6932            let mut suitable_capabilities = None;
 6933            // Are we capable for proto request?
 6934            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6935                &buffer,
 6936                |capabilities| {
 6937                    if let Some(caps) = &capabilities.diagnostic_provider {
 6938                        suitable_capabilities = Some(caps.clone());
 6939                        true
 6940                    } else {
 6941                        false
 6942                    }
 6943                },
 6944                cx,
 6945            );
 6946            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6947            let Some(dynamic_caps) = suitable_capabilities else {
 6948                return Task::ready(Ok(None));
 6949            };
 6950            assert!(any_server_has_diagnostics_provider);
 6951
 6952            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6953            let request = GetDocumentDiagnostics {
 6954                previous_result_id: None,
 6955                identifier,
 6956                registration_id: None,
 6957            };
 6958            let request_timeout = ProjectSettings::get_global(cx)
 6959                .global_lsp_settings
 6960                .get_request_timeout();
 6961            let request_task = client.request_lsp(
 6962                upstream_project_id,
 6963                None,
 6964                request_timeout,
 6965                cx.background_executor().clone(),
 6966                request.to_proto(upstream_project_id, buffer.read(cx)),
 6967            );
 6968            cx.background_spawn(async move {
 6969                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6970                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6971                // Do not attempt to further process the dummy responses here.
 6972                let _response = request_task.await?;
 6973                Ok(None)
 6974            })
 6975        } else {
 6976            let servers = buffer.update(cx, |buffer, cx| {
 6977                self.running_language_servers_for_local_buffer(buffer, cx)
 6978                    .map(|(_, server)| server.clone())
 6979                    .collect::<Vec<_>>()
 6980            });
 6981
 6982            let pull_diagnostics = servers
 6983                .into_iter()
 6984                .flat_map(|server| {
 6985                    let result = maybe!({
 6986                        let local = self.as_local()?;
 6987                        let server_id = server.server_id();
 6988                        let providers_with_identifiers = local
 6989                            .language_server_dynamic_registrations
 6990                            .get(&server_id)
 6991                            .into_iter()
 6992                            .flat_map(|registrations| registrations.diagnostics.clone())
 6993                            .collect::<Vec<_>>();
 6994                        Some(
 6995                            providers_with_identifiers
 6996                                .into_iter()
 6997                                .map(|(registration_id, dynamic_caps)| {
 6998                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6999                                    let registration_id = registration_id.map(SharedString::from);
 7000                                    let result_id = self.result_id_for_buffer_pull(
 7001                                        server_id,
 7002                                        buffer_id,
 7003                                        &registration_id,
 7004                                        cx,
 7005                                    );
 7006                                    self.request_lsp(
 7007                                        buffer.clone(),
 7008                                        LanguageServerToQuery::Other(server_id),
 7009                                        GetDocumentDiagnostics {
 7010                                            previous_result_id: result_id,
 7011                                            registration_id,
 7012                                            identifier,
 7013                                        },
 7014                                        cx,
 7015                                    )
 7016                                })
 7017                                .collect::<Vec<_>>(),
 7018                        )
 7019                    });
 7020
 7021                    result.unwrap_or_default()
 7022                })
 7023                .collect::<Vec<_>>();
 7024
 7025            cx.background_spawn(async move {
 7026                let mut responses = Vec::new();
 7027                for diagnostics in join_all(pull_diagnostics).await {
 7028                    responses.extend(diagnostics?);
 7029                }
 7030                Ok(Some(responses))
 7031            })
 7032        }
 7033    }
 7034
 7035    pub fn applicable_inlay_chunks(
 7036        &mut self,
 7037        buffer: &Entity<Buffer>,
 7038        ranges: &[Range<text::Anchor>],
 7039        cx: &mut Context<Self>,
 7040    ) -> Vec<Range<BufferRow>> {
 7041        let buffer_snapshot = buffer.read(cx).snapshot();
 7042        let ranges = ranges
 7043            .iter()
 7044            .map(|range| range.to_point(&buffer_snapshot))
 7045            .collect::<Vec<_>>();
 7046
 7047        self.latest_lsp_data(buffer, cx)
 7048            .inlay_hints
 7049            .applicable_chunks(ranges.as_slice())
 7050            .map(|chunk| chunk.row_range())
 7051            .collect()
 7052    }
 7053
 7054    pub fn invalidate_inlay_hints<'a>(
 7055        &'a mut self,
 7056        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 7057    ) {
 7058        for buffer_id in for_buffers {
 7059            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 7060                lsp_data.inlay_hints.clear();
 7061            }
 7062        }
 7063    }
 7064
 7065    pub fn inlay_hints(
 7066        &mut self,
 7067        invalidate: InvalidationStrategy,
 7068        buffer: Entity<Buffer>,
 7069        ranges: Vec<Range<text::Anchor>>,
 7070        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 7071        cx: &mut Context<Self>,
 7072    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 7073        let next_hint_id = self.next_hint_id.clone();
 7074        let lsp_data = self.latest_lsp_data(&buffer, cx);
 7075        let query_version = lsp_data.buffer_version.clone();
 7076        let mut lsp_refresh_requested = false;
 7077        let for_server = if let InvalidationStrategy::RefreshRequested {
 7078            server_id,
 7079            request_id,
 7080        } = invalidate
 7081        {
 7082            let invalidated = lsp_data
 7083                .inlay_hints
 7084                .invalidate_for_server_refresh(server_id, request_id);
 7085            lsp_refresh_requested = invalidated;
 7086            Some(server_id)
 7087        } else {
 7088            None
 7089        };
 7090        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 7091        let known_chunks = known_chunks
 7092            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 7093            .map(|(_, known_chunks)| known_chunks)
 7094            .unwrap_or_default();
 7095
 7096        let buffer_snapshot = buffer.read(cx).snapshot();
 7097        let ranges = ranges
 7098            .iter()
 7099            .map(|range| range.to_point(&buffer_snapshot))
 7100            .collect::<Vec<_>>();
 7101
 7102        let mut hint_fetch_tasks = Vec::new();
 7103        let mut cached_inlay_hints = None;
 7104        let mut ranges_to_query = None;
 7105        let applicable_chunks = existing_inlay_hints
 7106            .applicable_chunks(ranges.as_slice())
 7107            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7108            .collect::<Vec<_>>();
 7109        if applicable_chunks.is_empty() {
 7110            return HashMap::default();
 7111        }
 7112
 7113        for row_chunk in applicable_chunks {
 7114            match (
 7115                existing_inlay_hints
 7116                    .cached_hints(&row_chunk)
 7117                    .filter(|_| !lsp_refresh_requested)
 7118                    .cloned(),
 7119                existing_inlay_hints
 7120                    .fetched_hints(&row_chunk)
 7121                    .as_ref()
 7122                    .filter(|_| !lsp_refresh_requested)
 7123                    .cloned(),
 7124            ) {
 7125                (None, None) => {
 7126                    let chunk_range = row_chunk.anchor_range();
 7127                    ranges_to_query
 7128                        .get_or_insert_with(Vec::new)
 7129                        .push((row_chunk, chunk_range));
 7130                }
 7131                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7132                (Some(cached_hints), None) => {
 7133                    for (server_id, cached_hints) in cached_hints {
 7134                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7135                            cached_inlay_hints
 7136                                .get_or_insert_with(HashMap::default)
 7137                                .entry(row_chunk.row_range())
 7138                                .or_insert_with(HashMap::default)
 7139                                .entry(server_id)
 7140                                .or_insert_with(Vec::new)
 7141                                .extend(cached_hints);
 7142                        }
 7143                    }
 7144                }
 7145                (Some(cached_hints), Some(fetched_hints)) => {
 7146                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7147                    for (server_id, cached_hints) in cached_hints {
 7148                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7149                            cached_inlay_hints
 7150                                .get_or_insert_with(HashMap::default)
 7151                                .entry(row_chunk.row_range())
 7152                                .or_insert_with(HashMap::default)
 7153                                .entry(server_id)
 7154                                .or_insert_with(Vec::new)
 7155                                .extend(cached_hints);
 7156                        }
 7157                    }
 7158                }
 7159            }
 7160        }
 7161
 7162        if hint_fetch_tasks.is_empty()
 7163            && ranges_to_query
 7164                .as_ref()
 7165                .is_none_or(|ranges| ranges.is_empty())
 7166            && let Some(cached_inlay_hints) = cached_inlay_hints
 7167        {
 7168            cached_inlay_hints
 7169                .into_iter()
 7170                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7171                .collect()
 7172        } else {
 7173            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7174                // When a server refresh was requested, other servers' cached hints
 7175                // are unaffected by the refresh and must be included in the result.
 7176                // Otherwise apply_fetched_hints (with should_invalidate()=true)
 7177                // removes all visible hints but only adds back the requesting
 7178                // server's new hints, permanently losing other servers' hints.
 7179                let other_servers_cached: CacheInlayHints = if lsp_refresh_requested {
 7180                    lsp_data
 7181                        .inlay_hints
 7182                        .cached_hints(&chunk)
 7183                        .cloned()
 7184                        .unwrap_or_default()
 7185                } else {
 7186                    HashMap::default()
 7187                };
 7188
 7189                let next_hint_id = next_hint_id.clone();
 7190                let buffer = buffer.clone();
 7191                let query_version = query_version.clone();
 7192                let new_inlay_hints = cx
 7193                    .spawn(async move |lsp_store, cx| {
 7194                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7195                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7196                        })?;
 7197                        new_fetch_task
 7198                            .await
 7199                            .and_then(|new_hints_by_server| {
 7200                                lsp_store.update(cx, |lsp_store, cx| {
 7201                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7202                                    let update_cache = lsp_data.buffer_version == query_version;
 7203                                    if new_hints_by_server.is_empty() {
 7204                                        if update_cache {
 7205                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7206                                        }
 7207                                        other_servers_cached
 7208                                    } else {
 7209                                        let mut result = other_servers_cached;
 7210                                        for (server_id, new_hints) in new_hints_by_server {
 7211                                            let new_hints = new_hints
 7212                                                .into_iter()
 7213                                                .map(|new_hint| {
 7214                                                    (
 7215                                                        InlayId::Hint(next_hint_id.fetch_add(
 7216                                                            1,
 7217                                                            atomic::Ordering::AcqRel,
 7218                                                        )),
 7219                                                        new_hint,
 7220                                                    )
 7221                                                })
 7222                                                .collect::<Vec<_>>();
 7223                                            if update_cache {
 7224                                                lsp_data.inlay_hints.insert_new_hints(
 7225                                                    chunk,
 7226                                                    server_id,
 7227                                                    new_hints.clone(),
 7228                                                );
 7229                                            }
 7230                                            result.insert(server_id, new_hints);
 7231                                        }
 7232                                        result
 7233                                    }
 7234                                })
 7235                            })
 7236                            .map_err(Arc::new)
 7237                    })
 7238                    .shared();
 7239
 7240                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7241                *fetch_task = Some(new_inlay_hints.clone());
 7242                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7243            }
 7244
 7245            cached_inlay_hints
 7246                .unwrap_or_default()
 7247                .into_iter()
 7248                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7249                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7250                    (
 7251                        chunk.row_range(),
 7252                        cx.spawn(async move |_, _| {
 7253                            hints_fetch.await.map_err(|e| {
 7254                                if e.error_code() != ErrorCode::Internal {
 7255                                    anyhow!(e.error_code())
 7256                                } else {
 7257                                    anyhow!("{e:#}")
 7258                                }
 7259                            })
 7260                        }),
 7261                    )
 7262                }))
 7263                .collect()
 7264        }
 7265    }
 7266
 7267    fn fetch_inlay_hints(
 7268        &mut self,
 7269        for_server: Option<LanguageServerId>,
 7270        buffer: &Entity<Buffer>,
 7271        range: Range<Anchor>,
 7272        cx: &mut Context<Self>,
 7273    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7274        let request = InlayHints {
 7275            range: range.clone(),
 7276        };
 7277        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7278            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7279                return Task::ready(Ok(HashMap::default()));
 7280            }
 7281            let request_timeout = ProjectSettings::get_global(cx)
 7282                .global_lsp_settings
 7283                .get_request_timeout();
 7284            let request_task = upstream_client.request_lsp(
 7285                project_id,
 7286                for_server.map(|id| id.to_proto()),
 7287                request_timeout,
 7288                cx.background_executor().clone(),
 7289                request.to_proto(project_id, buffer.read(cx)),
 7290            );
 7291            let buffer = buffer.clone();
 7292            cx.spawn(async move |weak_lsp_store, cx| {
 7293                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7294                    return Ok(HashMap::default());
 7295                };
 7296                let Some(responses) = request_task.await? else {
 7297                    return Ok(HashMap::default());
 7298                };
 7299
 7300                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7301                    let lsp_store = lsp_store.clone();
 7302                    let buffer = buffer.clone();
 7303                    let cx = cx.clone();
 7304                    let request = request.clone();
 7305                    async move {
 7306                        (
 7307                            LanguageServerId::from_proto(response.server_id),
 7308                            request
 7309                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7310                                .await,
 7311                        )
 7312                    }
 7313                }))
 7314                .await;
 7315
 7316                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7317                let mut has_errors = false;
 7318                let inlay_hints = inlay_hints
 7319                    .into_iter()
 7320                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7321                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7322                        Err(e) => {
 7323                            has_errors = true;
 7324                            log::error!("{e:#}");
 7325                            None
 7326                        }
 7327                    })
 7328                    .map(|(server_id, mut new_hints)| {
 7329                        new_hints.retain(|hint| {
 7330                            hint.position.is_valid(&buffer_snapshot)
 7331                                && range.start.is_valid(&buffer_snapshot)
 7332                                && range.end.is_valid(&buffer_snapshot)
 7333                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7334                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7335                        });
 7336                        (server_id, new_hints)
 7337                    })
 7338                    .collect::<HashMap<_, _>>();
 7339                anyhow::ensure!(
 7340                    !has_errors || !inlay_hints.is_empty(),
 7341                    "Failed to fetch inlay hints"
 7342                );
 7343                Ok(inlay_hints)
 7344            })
 7345        } else {
 7346            let inlay_hints_task = match for_server {
 7347                Some(server_id) => {
 7348                    let server_task = self.request_lsp(
 7349                        buffer.clone(),
 7350                        LanguageServerToQuery::Other(server_id),
 7351                        request,
 7352                        cx,
 7353                    );
 7354                    cx.background_spawn(async move {
 7355                        let mut responses = Vec::new();
 7356                        match server_task.await {
 7357                            Ok(response) => responses.push((server_id, response)),
 7358                            // rust-analyzer likes to error with this when its still loading up
 7359                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7360                            Err(e) => log::error!(
 7361                                "Error handling response for inlay hints request: {e:#}"
 7362                            ),
 7363                        }
 7364                        responses
 7365                    })
 7366                }
 7367                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7368            };
 7369            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7370            cx.background_spawn(async move {
 7371                Ok(inlay_hints_task
 7372                    .await
 7373                    .into_iter()
 7374                    .map(|(server_id, mut new_hints)| {
 7375                        new_hints.retain(|hint| {
 7376                            hint.position.is_valid(&buffer_snapshot)
 7377                                && range.start.is_valid(&buffer_snapshot)
 7378                                && range.end.is_valid(&buffer_snapshot)
 7379                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7380                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7381                        });
 7382                        (server_id, new_hints)
 7383                    })
 7384                    .collect())
 7385            })
 7386        }
 7387    }
 7388
 7389    fn diagnostic_registration_exists(
 7390        &self,
 7391        server_id: LanguageServerId,
 7392        registration_id: &Option<SharedString>,
 7393    ) -> bool {
 7394        let Some(local) = self.as_local() else {
 7395            return false;
 7396        };
 7397        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7398        else {
 7399            return false;
 7400        };
 7401        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7402        registrations.diagnostics.contains_key(&registration_key)
 7403    }
 7404
 7405    pub fn pull_diagnostics_for_buffer(
 7406        &mut self,
 7407        buffer: Entity<Buffer>,
 7408        cx: &mut Context<Self>,
 7409    ) -> Task<anyhow::Result<()>> {
 7410        let diagnostics = self.pull_diagnostics(buffer, cx);
 7411        cx.spawn(async move |lsp_store, cx| {
 7412            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7413                return Ok(());
 7414            };
 7415            lsp_store.update(cx, |lsp_store, cx| {
 7416                if lsp_store.as_local().is_none() {
 7417                    return;
 7418                }
 7419
 7420                let mut unchanged_buffers = HashMap::default();
 7421                let server_diagnostics_updates = diagnostics
 7422                    .into_iter()
 7423                    .filter_map(|diagnostics_set| match diagnostics_set {
 7424                        LspPullDiagnostics::Response {
 7425                            server_id,
 7426                            uri,
 7427                            diagnostics,
 7428                            registration_id,
 7429                        } => Some((server_id, uri, diagnostics, registration_id)),
 7430                        LspPullDiagnostics::Default => None,
 7431                    })
 7432                    .filter(|(server_id, _, _, registration_id)| {
 7433                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7434                    })
 7435                    .fold(
 7436                        HashMap::default(),
 7437                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7438                            let (result_id, diagnostics) = match diagnostics {
 7439                                PulledDiagnostics::Unchanged { result_id } => {
 7440                                    unchanged_buffers
 7441                                        .entry(new_registration_id.clone())
 7442                                        .or_insert_with(HashSet::default)
 7443                                        .insert(uri.clone());
 7444                                    (Some(result_id), Vec::new())
 7445                                }
 7446                                PulledDiagnostics::Changed {
 7447                                    result_id,
 7448                                    diagnostics,
 7449                                } => (result_id, diagnostics),
 7450                            };
 7451                            let disk_based_sources = Cow::Owned(
 7452                                lsp_store
 7453                                    .language_server_adapter_for_id(server_id)
 7454                                    .as_ref()
 7455                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7456                                    .unwrap_or(&[])
 7457                                    .to_vec(),
 7458                            );
 7459                            acc.entry(server_id)
 7460                                .or_insert_with(HashMap::default)
 7461                                .entry(new_registration_id.clone())
 7462                                .or_insert_with(Vec::new)
 7463                                .push(DocumentDiagnosticsUpdate {
 7464                                    server_id,
 7465                                    diagnostics: lsp::PublishDiagnosticsParams {
 7466                                        uri,
 7467                                        diagnostics,
 7468                                        version: None,
 7469                                    },
 7470                                    result_id: result_id.map(SharedString::new),
 7471                                    disk_based_sources,
 7472                                    registration_id: new_registration_id,
 7473                                });
 7474                            acc
 7475                        },
 7476                    );
 7477
 7478                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7479                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7480                        lsp_store
 7481                            .merge_lsp_diagnostics(
 7482                                DiagnosticSourceKind::Pulled,
 7483                                diagnostic_updates,
 7484                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7485                                    DiagnosticSourceKind::Pulled => {
 7486                                        old_diagnostic.registration_id != registration_id
 7487                                            || unchanged_buffers
 7488                                                .get(&old_diagnostic.registration_id)
 7489                                                .is_some_and(|unchanged_buffers| {
 7490                                                    unchanged_buffers.contains(&document_uri)
 7491                                                })
 7492                                    }
 7493                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7494                                        true
 7495                                    }
 7496                                },
 7497                                cx,
 7498                            )
 7499                            .log_err();
 7500                    }
 7501                }
 7502            })
 7503        })
 7504    }
 7505
 7506    pub fn signature_help<T: ToPointUtf16>(
 7507        &mut self,
 7508        buffer: &Entity<Buffer>,
 7509        position: T,
 7510        cx: &mut Context<Self>,
 7511    ) -> Task<Option<Vec<SignatureHelp>>> {
 7512        let position = position.to_point_utf16(buffer.read(cx));
 7513
 7514        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7515            let request = GetSignatureHelp { position };
 7516            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7517                return Task::ready(None);
 7518            }
 7519            let request_timeout = ProjectSettings::get_global(cx)
 7520                .global_lsp_settings
 7521                .get_request_timeout();
 7522            let request_task = client.request_lsp(
 7523                upstream_project_id,
 7524                None,
 7525                request_timeout,
 7526                cx.background_executor().clone(),
 7527                request.to_proto(upstream_project_id, buffer.read(cx)),
 7528            );
 7529            let buffer = buffer.clone();
 7530            cx.spawn(async move |weak_lsp_store, cx| {
 7531                let lsp_store = weak_lsp_store.upgrade()?;
 7532                let signatures = join_all(
 7533                    request_task
 7534                        .await
 7535                        .log_err()
 7536                        .flatten()
 7537                        .map(|response| response.payload)
 7538                        .unwrap_or_default()
 7539                        .into_iter()
 7540                        .map(|response| {
 7541                            let response = GetSignatureHelp { position }.response_from_proto(
 7542                                response.response,
 7543                                lsp_store.clone(),
 7544                                buffer.clone(),
 7545                                cx.clone(),
 7546                            );
 7547                            async move { response.await.log_err().flatten() }
 7548                        }),
 7549                )
 7550                .await
 7551                .into_iter()
 7552                .flatten()
 7553                .collect();
 7554                Some(signatures)
 7555            })
 7556        } else {
 7557            let all_actions_task = self.request_multiple_lsp_locally(
 7558                buffer,
 7559                Some(position),
 7560                GetSignatureHelp { position },
 7561                cx,
 7562            );
 7563            cx.background_spawn(async move {
 7564                Some(
 7565                    all_actions_task
 7566                        .await
 7567                        .into_iter()
 7568                        .flat_map(|(_, actions)| actions)
 7569                        .collect::<Vec<_>>(),
 7570                )
 7571            })
 7572        }
 7573    }
 7574
 7575    pub fn hover(
 7576        &mut self,
 7577        buffer: &Entity<Buffer>,
 7578        position: PointUtf16,
 7579        cx: &mut Context<Self>,
 7580    ) -> Task<Option<Vec<Hover>>> {
 7581        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7582            let request = GetHover { position };
 7583            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7584                return Task::ready(None);
 7585            }
 7586            let request_timeout = ProjectSettings::get_global(cx)
 7587                .global_lsp_settings
 7588                .get_request_timeout();
 7589            let request_task = client.request_lsp(
 7590                upstream_project_id,
 7591                None,
 7592                request_timeout,
 7593                cx.background_executor().clone(),
 7594                request.to_proto(upstream_project_id, buffer.read(cx)),
 7595            );
 7596            let buffer = buffer.clone();
 7597            cx.spawn(async move |weak_lsp_store, cx| {
 7598                let lsp_store = weak_lsp_store.upgrade()?;
 7599                let hovers = join_all(
 7600                    request_task
 7601                        .await
 7602                        .log_err()
 7603                        .flatten()
 7604                        .map(|response| response.payload)
 7605                        .unwrap_or_default()
 7606                        .into_iter()
 7607                        .map(|response| {
 7608                            let response = GetHover { position }.response_from_proto(
 7609                                response.response,
 7610                                lsp_store.clone(),
 7611                                buffer.clone(),
 7612                                cx.clone(),
 7613                            );
 7614                            async move {
 7615                                response
 7616                                    .await
 7617                                    .log_err()
 7618                                    .flatten()
 7619                                    .and_then(remove_empty_hover_blocks)
 7620                            }
 7621                        }),
 7622                )
 7623                .await
 7624                .into_iter()
 7625                .flatten()
 7626                .collect();
 7627                Some(hovers)
 7628            })
 7629        } else {
 7630            let all_actions_task = self.request_multiple_lsp_locally(
 7631                buffer,
 7632                Some(position),
 7633                GetHover { position },
 7634                cx,
 7635            );
 7636            cx.background_spawn(async move {
 7637                Some(
 7638                    all_actions_task
 7639                        .await
 7640                        .into_iter()
 7641                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7642                        .collect::<Vec<Hover>>(),
 7643                )
 7644            })
 7645        }
 7646    }
 7647
 7648    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7649        let language_registry = self.languages.clone();
 7650
 7651        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7652            let request = upstream_client.request(proto::GetProjectSymbols {
 7653                project_id: *project_id,
 7654                query: query.to_string(),
 7655            });
 7656            cx.foreground_executor().spawn(async move {
 7657                let response = request.await?;
 7658                let mut symbols = Vec::new();
 7659                let core_symbols = response
 7660                    .symbols
 7661                    .into_iter()
 7662                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7663                    .collect::<Vec<_>>();
 7664                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7665                    .await;
 7666                Ok(symbols)
 7667            })
 7668        } else if let Some(local) = self.as_local() {
 7669            struct WorkspaceSymbolsResult {
 7670                server_id: LanguageServerId,
 7671                lsp_adapter: Arc<CachedLspAdapter>,
 7672                worktree: WeakEntity<Worktree>,
 7673                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7674            }
 7675
 7676            let mut requests = Vec::new();
 7677            let mut requested_servers = BTreeSet::new();
 7678            let request_timeout = ProjectSettings::get_global(cx)
 7679                .global_lsp_settings
 7680                .get_request_timeout();
 7681
 7682            for (seed, state) in local.language_server_ids.iter() {
 7683                let Some(worktree_handle) = self
 7684                    .worktree_store
 7685                    .read(cx)
 7686                    .worktree_for_id(seed.worktree_id, cx)
 7687                else {
 7688                    continue;
 7689                };
 7690
 7691                let worktree = worktree_handle.read(cx);
 7692                if !worktree.is_visible() {
 7693                    continue;
 7694                }
 7695
 7696                if !requested_servers.insert(state.id) {
 7697                    continue;
 7698                }
 7699
 7700                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7701                    Some(LanguageServerState::Running {
 7702                        adapter, server, ..
 7703                    }) => (adapter.clone(), server),
 7704
 7705                    _ => continue,
 7706                };
 7707
 7708                let supports_workspace_symbol_request =
 7709                    match server.capabilities().workspace_symbol_provider {
 7710                        Some(OneOf::Left(supported)) => supported,
 7711                        Some(OneOf::Right(_)) => true,
 7712                        None => false,
 7713                    };
 7714
 7715                if !supports_workspace_symbol_request {
 7716                    continue;
 7717                }
 7718
 7719                let worktree_handle = worktree_handle.clone();
 7720                let server_id = server.server_id();
 7721                requests.push(
 7722                    server
 7723                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7724                            lsp::WorkspaceSymbolParams {
 7725                                query: query.to_string(),
 7726                                ..Default::default()
 7727                            },
 7728                            request_timeout,
 7729                        )
 7730                        .map(move |response| {
 7731                            let lsp_symbols = response
 7732                                .into_response()
 7733                                .context("workspace symbols request")
 7734                                .log_err()
 7735                                .flatten()
 7736                                .map(|symbol_response| match symbol_response {
 7737                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7738                                        flat_responses
 7739                                            .into_iter()
 7740                                            .map(|lsp_symbol| {
 7741                                                (
 7742                                                    lsp_symbol.name,
 7743                                                    lsp_symbol.kind,
 7744                                                    lsp_symbol.location,
 7745                                                    lsp_symbol.container_name,
 7746                                                )
 7747                                            })
 7748                                            .collect::<Vec<_>>()
 7749                                    }
 7750                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7751                                        nested_responses
 7752                                            .into_iter()
 7753                                            .filter_map(|lsp_symbol| {
 7754                                                let location = match lsp_symbol.location {
 7755                                                    OneOf::Left(location) => location,
 7756                                                    OneOf::Right(_) => {
 7757                                                        log::error!(
 7758                                                            "Unexpected: client capabilities \
 7759                                                            forbid symbol resolutions in \
 7760                                                            workspace.symbol.resolveSupport"
 7761                                                        );
 7762                                                        return None;
 7763                                                    }
 7764                                                };
 7765                                                Some((
 7766                                                    lsp_symbol.name,
 7767                                                    lsp_symbol.kind,
 7768                                                    location,
 7769                                                    lsp_symbol.container_name,
 7770                                                ))
 7771                                            })
 7772                                            .collect::<Vec<_>>()
 7773                                    }
 7774                                })
 7775                                .unwrap_or_default();
 7776
 7777                            WorkspaceSymbolsResult {
 7778                                server_id,
 7779                                lsp_adapter,
 7780                                worktree: worktree_handle.downgrade(),
 7781                                lsp_symbols,
 7782                            }
 7783                        }),
 7784                );
 7785            }
 7786
 7787            cx.spawn(async move |this, cx| {
 7788                let responses = futures::future::join_all(requests).await;
 7789                let this = match this.upgrade() {
 7790                    Some(this) => this,
 7791                    None => return Ok(Vec::new()),
 7792                };
 7793
 7794                let mut symbols = Vec::new();
 7795                for result in responses {
 7796                    let core_symbols = this.update(cx, |this, cx| {
 7797                        result
 7798                            .lsp_symbols
 7799                            .into_iter()
 7800                            .filter_map(
 7801                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7802                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7803                                    let source_worktree = result.worktree.upgrade()?;
 7804                                    let source_worktree_id = source_worktree.read(cx).id();
 7805
 7806                                    let path = if let Some((tree, rel_path)) =
 7807                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7808                                    {
 7809                                        let worktree_id = tree.read(cx).id();
 7810                                        SymbolLocation::InProject(ProjectPath {
 7811                                            worktree_id,
 7812                                            path: rel_path,
 7813                                        })
 7814                                    } else {
 7815                                        SymbolLocation::OutsideProject {
 7816                                            signature: this.symbol_signature(&abs_path),
 7817                                            abs_path: abs_path.into(),
 7818                                        }
 7819                                    };
 7820
 7821                                    Some(CoreSymbol {
 7822                                        source_language_server_id: result.server_id,
 7823                                        language_server_name: result.lsp_adapter.name.clone(),
 7824                                        source_worktree_id,
 7825                                        path,
 7826                                        kind: symbol_kind,
 7827                                        name: collapse_newlines(&symbol_name, ""),
 7828                                        range: range_from_lsp(symbol_location.range),
 7829                                        container_name: container_name
 7830                                            .map(|c| collapse_newlines(&c, "")),
 7831                                    })
 7832                                },
 7833                            )
 7834                            .collect::<Vec<_>>()
 7835                    });
 7836
 7837                    populate_labels_for_symbols(
 7838                        core_symbols,
 7839                        &language_registry,
 7840                        Some(result.lsp_adapter),
 7841                        &mut symbols,
 7842                    )
 7843                    .await;
 7844                }
 7845
 7846                Ok(symbols)
 7847            })
 7848        } else {
 7849            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7850        }
 7851    }
 7852
 7853    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7854        let mut summary = DiagnosticSummary::default();
 7855        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7856            summary.error_count += path_summary.error_count;
 7857            summary.warning_count += path_summary.warning_count;
 7858        }
 7859        summary
 7860    }
 7861
 7862    /// Returns the diagnostic summary for a specific project path.
 7863    pub fn diagnostic_summary_for_path(
 7864        &self,
 7865        project_path: &ProjectPath,
 7866        _: &App,
 7867    ) -> DiagnosticSummary {
 7868        if let Some(summaries) = self
 7869            .diagnostic_summaries
 7870            .get(&project_path.worktree_id)
 7871            .and_then(|map| map.get(&project_path.path))
 7872        {
 7873            let (error_count, warning_count) = summaries.iter().fold(
 7874                (0, 0),
 7875                |(error_count, warning_count), (_language_server_id, summary)| {
 7876                    (
 7877                        error_count + summary.error_count,
 7878                        warning_count + summary.warning_count,
 7879                    )
 7880                },
 7881            );
 7882
 7883            DiagnosticSummary {
 7884                error_count,
 7885                warning_count,
 7886            }
 7887        } else {
 7888            DiagnosticSummary::default()
 7889        }
 7890    }
 7891
 7892    pub fn diagnostic_summaries<'a>(
 7893        &'a self,
 7894        include_ignored: bool,
 7895        cx: &'a App,
 7896    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7897        self.worktree_store
 7898            .read(cx)
 7899            .visible_worktrees(cx)
 7900            .filter_map(|worktree| {
 7901                let worktree = worktree.read(cx);
 7902                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7903            })
 7904            .flat_map(move |(worktree, summaries)| {
 7905                let worktree_id = worktree.id();
 7906                summaries
 7907                    .iter()
 7908                    .filter(move |(path, _)| {
 7909                        include_ignored
 7910                            || worktree
 7911                                .entry_for_path(path.as_ref())
 7912                                .is_some_and(|entry| !entry.is_ignored)
 7913                    })
 7914                    .flat_map(move |(path, summaries)| {
 7915                        summaries.iter().map(move |(server_id, summary)| {
 7916                            (
 7917                                ProjectPath {
 7918                                    worktree_id,
 7919                                    path: path.clone(),
 7920                                },
 7921                                *server_id,
 7922                                *summary,
 7923                            )
 7924                        })
 7925                    })
 7926            })
 7927    }
 7928
 7929    pub fn on_buffer_edited(
 7930        &mut self,
 7931        buffer: Entity<Buffer>,
 7932        cx: &mut Context<Self>,
 7933    ) -> Option<()> {
 7934        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7935            Some(
 7936                self.as_local()?
 7937                    .language_servers_for_buffer(buffer, cx)
 7938                    .map(|i| i.1.clone())
 7939                    .collect(),
 7940            )
 7941        })?;
 7942
 7943        let buffer = buffer.read(cx);
 7944        let file = File::from_dyn(buffer.file())?;
 7945        let abs_path = file.as_local()?.abs_path(cx);
 7946        let uri = lsp::Uri::from_file_path(&abs_path)
 7947            .ok()
 7948            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7949            .log_err()?;
 7950        let next_snapshot = buffer.text_snapshot();
 7951        for language_server in language_servers {
 7952            let language_server = language_server.clone();
 7953
 7954            let buffer_snapshots = self
 7955                .as_local_mut()?
 7956                .buffer_snapshots
 7957                .get_mut(&buffer.remote_id())
 7958                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7959            let previous_snapshot = buffer_snapshots.last()?;
 7960
 7961            let build_incremental_change = || {
 7962                buffer
 7963                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7964                        previous_snapshot.snapshot.version(),
 7965                    )
 7966                    .map(|edit| {
 7967                        let edit_start = edit.new.start.0;
 7968                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7969                        let new_text = next_snapshot
 7970                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7971                            .collect();
 7972                        lsp::TextDocumentContentChangeEvent {
 7973                            range: Some(lsp::Range::new(
 7974                                point_to_lsp(edit_start),
 7975                                point_to_lsp(edit_end),
 7976                            )),
 7977                            range_length: None,
 7978                            text: new_text,
 7979                        }
 7980                    })
 7981                    .collect()
 7982            };
 7983
 7984            let document_sync_kind = language_server
 7985                .capabilities()
 7986                .text_document_sync
 7987                .as_ref()
 7988                .and_then(|sync| match sync {
 7989                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7990                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7991                });
 7992
 7993            let content_changes: Vec<_> = match document_sync_kind {
 7994                Some(lsp::TextDocumentSyncKind::FULL) => {
 7995                    vec![lsp::TextDocumentContentChangeEvent {
 7996                        range: None,
 7997                        range_length: None,
 7998                        text: next_snapshot.text(),
 7999                    }]
 8000                }
 8001                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8002                _ => {
 8003                    #[cfg(any(test, feature = "test-support"))]
 8004                    {
 8005                        build_incremental_change()
 8006                    }
 8007
 8008                    #[cfg(not(any(test, feature = "test-support")))]
 8009                    {
 8010                        continue;
 8011                    }
 8012                }
 8013            };
 8014
 8015            let next_version = previous_snapshot.version + 1;
 8016            buffer_snapshots.push(LspBufferSnapshot {
 8017                version: next_version,
 8018                snapshot: next_snapshot.clone(),
 8019            });
 8020
 8021            language_server
 8022                .notify::<lsp::notification::DidChangeTextDocument>(
 8023                    lsp::DidChangeTextDocumentParams {
 8024                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8025                            uri.clone(),
 8026                            next_version,
 8027                        ),
 8028                        content_changes,
 8029                    },
 8030                )
 8031                .ok();
 8032            self.pull_workspace_diagnostics(language_server.server_id());
 8033        }
 8034
 8035        None
 8036    }
 8037
 8038    pub fn on_buffer_saved(
 8039        &mut self,
 8040        buffer: Entity<Buffer>,
 8041        cx: &mut Context<Self>,
 8042    ) -> Option<()> {
 8043        let file = File::from_dyn(buffer.read(cx).file())?;
 8044        let worktree_id = file.worktree_id(cx);
 8045        let abs_path = file.as_local()?.abs_path(cx);
 8046        let text_document = lsp::TextDocumentIdentifier {
 8047            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8048        };
 8049        let local = self.as_local()?;
 8050
 8051        for server in local.language_servers_for_worktree(worktree_id) {
 8052            if let Some(include_text) = include_text(server.as_ref()) {
 8053                let text = if include_text {
 8054                    Some(buffer.read(cx).text())
 8055                } else {
 8056                    None
 8057                };
 8058                server
 8059                    .notify::<lsp::notification::DidSaveTextDocument>(
 8060                        lsp::DidSaveTextDocumentParams {
 8061                            text_document: text_document.clone(),
 8062                            text,
 8063                        },
 8064                    )
 8065                    .ok();
 8066            }
 8067        }
 8068
 8069        let language_servers = buffer.update(cx, |buffer, cx| {
 8070            local.language_server_ids_for_buffer(buffer, cx)
 8071        });
 8072        for language_server_id in language_servers {
 8073            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8074        }
 8075
 8076        None
 8077    }
 8078
 8079    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8080        maybe!(async move {
 8081            let mut refreshed_servers = HashSet::default();
 8082            let servers = lsp_store
 8083                .update(cx, |lsp_store, cx| {
 8084                    let local = lsp_store.as_local()?;
 8085
 8086                    let servers = local
 8087                        .language_server_ids
 8088                        .iter()
 8089                        .filter_map(|(seed, state)| {
 8090                            let worktree = lsp_store
 8091                                .worktree_store
 8092                                .read(cx)
 8093                                .worktree_for_id(seed.worktree_id, cx);
 8094                            let delegate: Arc<dyn LspAdapterDelegate> =
 8095                                worktree.map(|worktree| {
 8096                                    LocalLspAdapterDelegate::new(
 8097                                        local.languages.clone(),
 8098                                        &local.environment,
 8099                                        cx.weak_entity(),
 8100                                        &worktree,
 8101                                        local.http_client.clone(),
 8102                                        local.fs.clone(),
 8103                                        cx,
 8104                                    )
 8105                                })?;
 8106                            let server_id = state.id;
 8107
 8108                            let states = local.language_servers.get(&server_id)?;
 8109
 8110                            match states {
 8111                                LanguageServerState::Starting { .. } => None,
 8112                                LanguageServerState::Running {
 8113                                    adapter, server, ..
 8114                                } => {
 8115                                    let adapter = adapter.clone();
 8116                                    let server = server.clone();
 8117                                    refreshed_servers.insert(server.name());
 8118                                    let toolchain = seed.toolchain.clone();
 8119                                    Some(cx.spawn(async move |_, cx| {
 8120                                        let settings =
 8121                                            LocalLspStore::workspace_configuration_for_adapter(
 8122                                                adapter.adapter.clone(),
 8123                                                &delegate,
 8124                                                toolchain,
 8125                                                None,
 8126                                                cx,
 8127                                            )
 8128                                            .await
 8129                                            .ok()?;
 8130                                        server
 8131                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8132                                                lsp::DidChangeConfigurationParams { settings },
 8133                                            )
 8134                                            .ok()?;
 8135                                        Some(())
 8136                                    }))
 8137                                }
 8138                            }
 8139                        })
 8140                        .collect::<Vec<_>>();
 8141
 8142                    Some(servers)
 8143                })
 8144                .ok()
 8145                .flatten()?;
 8146
 8147            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8148            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8149            // to stop and unregister its language server wrapper.
 8150            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8151            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8152            let _: Vec<Option<()>> = join_all(servers).await;
 8153
 8154            Some(())
 8155        })
 8156        .await;
 8157    }
 8158
 8159    fn maintain_workspace_config(
 8160        external_refresh_requests: watch::Receiver<()>,
 8161        cx: &mut Context<Self>,
 8162    ) -> Task<Result<()>> {
 8163        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8164        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8165
 8166        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8167            *settings_changed_tx.borrow_mut() = ();
 8168        });
 8169
 8170        let mut joint_future =
 8171            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8172        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8173        // - 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).
 8174        // - 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.
 8175        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8176        // - 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,
 8177        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8178        cx.spawn(async move |this, cx| {
 8179            while let Some(()) = joint_future.next().await {
 8180                this.update(cx, |this, cx| {
 8181                    this.refresh_server_tree(cx);
 8182                })
 8183                .ok();
 8184
 8185                Self::refresh_workspace_configurations(&this, cx).await;
 8186            }
 8187
 8188            drop(settings_observation);
 8189            anyhow::Ok(())
 8190        })
 8191    }
 8192
 8193    pub fn running_language_servers_for_local_buffer<'a>(
 8194        &'a self,
 8195        buffer: &Buffer,
 8196        cx: &mut App,
 8197    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8198        let local = self.as_local();
 8199        let language_server_ids = local
 8200            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8201            .unwrap_or_default();
 8202
 8203        language_server_ids
 8204            .into_iter()
 8205            .filter_map(
 8206                move |server_id| match local?.language_servers.get(&server_id)? {
 8207                    LanguageServerState::Running {
 8208                        adapter, server, ..
 8209                    } => Some((adapter, server)),
 8210                    _ => None,
 8211                },
 8212            )
 8213    }
 8214
 8215    pub fn language_servers_for_local_buffer(
 8216        &self,
 8217        buffer: &Buffer,
 8218        cx: &mut App,
 8219    ) -> Vec<LanguageServerId> {
 8220        let local = self.as_local();
 8221        local
 8222            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8223            .unwrap_or_default()
 8224    }
 8225
 8226    pub fn language_server_for_local_buffer<'a>(
 8227        &'a self,
 8228        buffer: &'a Buffer,
 8229        server_id: LanguageServerId,
 8230        cx: &'a mut App,
 8231    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8232        self.as_local()?
 8233            .language_servers_for_buffer(buffer, cx)
 8234            .find(|(_, s)| s.server_id() == server_id)
 8235    }
 8236
 8237    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8238        self.diagnostic_summaries.remove(&id_to_remove);
 8239        if let Some(local) = self.as_local_mut() {
 8240            let to_remove = local.remove_worktree(id_to_remove, cx);
 8241            for server in to_remove {
 8242                self.language_server_statuses.remove(&server);
 8243            }
 8244        }
 8245    }
 8246
 8247    fn invalidate_diagnostic_summaries_for_removed_entries(
 8248        &mut self,
 8249        worktree_id: WorktreeId,
 8250        changes: &UpdatedEntriesSet,
 8251        cx: &mut Context<Self>,
 8252    ) {
 8253        let Some(summaries_for_tree) = self.diagnostic_summaries.get_mut(&worktree_id) else {
 8254            return;
 8255        };
 8256
 8257        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
 8258        let mut cleared_server_ids: HashSet<LanguageServerId> = HashSet::default();
 8259        let downstream = self.downstream_client.clone();
 8260
 8261        for (path, _, _) in changes
 8262            .iter()
 8263            .filter(|(_, _, change)| *change == PathChange::Removed)
 8264        {
 8265            if let Some(summaries_by_server_id) = summaries_for_tree.remove(path) {
 8266                for (server_id, _) in &summaries_by_server_id {
 8267                    cleared_server_ids.insert(*server_id);
 8268                    if let Some((client, project_id)) = &downstream {
 8269                        client
 8270                            .send(proto::UpdateDiagnosticSummary {
 8271                                project_id: *project_id,
 8272                                worktree_id: worktree_id.to_proto(),
 8273                                summary: Some(proto::DiagnosticSummary {
 8274                                    path: path.as_ref().to_proto(),
 8275                                    language_server_id: server_id.0 as u64,
 8276                                    error_count: 0,
 8277                                    warning_count: 0,
 8278                                }),
 8279                                more_summaries: Vec::new(),
 8280                            })
 8281                            .ok();
 8282                    }
 8283                }
 8284                cleared_paths.push(ProjectPath {
 8285                    worktree_id,
 8286                    path: path.clone(),
 8287                });
 8288            }
 8289        }
 8290
 8291        if !cleared_paths.is_empty() {
 8292            for server_id in cleared_server_ids {
 8293                cx.emit(LspStoreEvent::DiagnosticsUpdated {
 8294                    server_id,
 8295                    paths: cleared_paths.clone(),
 8296                });
 8297            }
 8298        }
 8299    }
 8300
 8301    pub fn shared(
 8302        &mut self,
 8303        project_id: u64,
 8304        downstream_client: AnyProtoClient,
 8305        _: &mut Context<Self>,
 8306    ) {
 8307        self.downstream_client = Some((downstream_client.clone(), project_id));
 8308
 8309        for (server_id, status) in &self.language_server_statuses {
 8310            if let Some(server) = self.language_server_for_id(*server_id) {
 8311                downstream_client
 8312                    .send(proto::StartLanguageServer {
 8313                        project_id,
 8314                        server: Some(proto::LanguageServer {
 8315                            id: server_id.to_proto(),
 8316                            name: status.name.to_string(),
 8317                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8318                        }),
 8319                        capabilities: serde_json::to_string(&server.capabilities())
 8320                            .expect("serializing server LSP capabilities"),
 8321                    })
 8322                    .log_err();
 8323            }
 8324        }
 8325    }
 8326
 8327    pub fn disconnected_from_host(&mut self) {
 8328        self.downstream_client.take();
 8329    }
 8330
 8331    pub fn disconnected_from_ssh_remote(&mut self) {
 8332        if let LspStoreMode::Remote(RemoteLspStore {
 8333            upstream_client, ..
 8334        }) = &mut self.mode
 8335        {
 8336            upstream_client.take();
 8337        }
 8338    }
 8339
 8340    pub(crate) fn set_language_server_statuses_from_proto(
 8341        &mut self,
 8342        project: WeakEntity<Project>,
 8343        language_servers: Vec<proto::LanguageServer>,
 8344        server_capabilities: Vec<String>,
 8345        cx: &mut Context<Self>,
 8346    ) {
 8347        let lsp_logs = cx
 8348            .try_global::<GlobalLogStore>()
 8349            .map(|lsp_store| lsp_store.0.clone());
 8350
 8351        self.language_server_statuses = language_servers
 8352            .into_iter()
 8353            .zip(server_capabilities)
 8354            .map(|(server, server_capabilities)| {
 8355                let server_id = LanguageServerId(server.id as usize);
 8356                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8357                    self.lsp_server_capabilities
 8358                        .insert(server_id, server_capabilities);
 8359                }
 8360
 8361                let name = LanguageServerName::from_proto(server.name);
 8362                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8363
 8364                if let Some(lsp_logs) = &lsp_logs {
 8365                    lsp_logs.update(cx, |lsp_logs, cx| {
 8366                        lsp_logs.add_language_server(
 8367                            // Only remote clients get their language servers set from proto
 8368                            LanguageServerKind::Remote {
 8369                                project: project.clone(),
 8370                            },
 8371                            server_id,
 8372                            Some(name.clone()),
 8373                            worktree,
 8374                            None,
 8375                            cx,
 8376                        );
 8377                    });
 8378                }
 8379
 8380                (
 8381                    server_id,
 8382                    LanguageServerStatus {
 8383                        name,
 8384                        server_version: None,
 8385                        server_readable_version: None,
 8386                        pending_work: Default::default(),
 8387                        has_pending_diagnostic_updates: false,
 8388                        progress_tokens: Default::default(),
 8389                        worktree,
 8390                        binary: None,
 8391                        configuration: None,
 8392                        workspace_folders: BTreeSet::new(),
 8393                        process_id: None,
 8394                    },
 8395                )
 8396            })
 8397            .collect();
 8398    }
 8399
 8400    #[cfg(feature = "test-support")]
 8401    pub fn update_diagnostic_entries(
 8402        &mut self,
 8403        server_id: LanguageServerId,
 8404        abs_path: PathBuf,
 8405        result_id: Option<SharedString>,
 8406        version: Option<i32>,
 8407        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8408        cx: &mut Context<Self>,
 8409    ) -> anyhow::Result<()> {
 8410        self.merge_diagnostic_entries(
 8411            vec![DocumentDiagnosticsUpdate {
 8412                diagnostics: DocumentDiagnostics {
 8413                    diagnostics,
 8414                    document_abs_path: abs_path,
 8415                    version,
 8416                },
 8417                result_id,
 8418                server_id,
 8419                disk_based_sources: Cow::Borrowed(&[]),
 8420                registration_id: None,
 8421            }],
 8422            |_, _, _| false,
 8423            cx,
 8424        )?;
 8425        Ok(())
 8426    }
 8427
 8428    pub fn merge_diagnostic_entries<'a>(
 8429        &mut self,
 8430        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8431        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8432        cx: &mut Context<Self>,
 8433    ) -> anyhow::Result<()> {
 8434        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8435        let mut updated_diagnostics_paths = HashMap::default();
 8436        for mut update in diagnostic_updates {
 8437            let abs_path = &update.diagnostics.document_abs_path;
 8438            let server_id = update.server_id;
 8439            let Some((worktree, relative_path)) =
 8440                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8441            else {
 8442                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8443                return Ok(());
 8444            };
 8445
 8446            let worktree_id = worktree.read(cx).id();
 8447            let project_path = ProjectPath {
 8448                worktree_id,
 8449                path: relative_path,
 8450            };
 8451
 8452            let document_uri = lsp::Uri::from_file_path(abs_path)
 8453                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8454            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8455                let snapshot = buffer_handle.read(cx).snapshot();
 8456                let buffer = buffer_handle.read(cx);
 8457                let reused_diagnostics = buffer
 8458                    .buffer_diagnostics(Some(server_id))
 8459                    .iter()
 8460                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8461                    .map(|v| {
 8462                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8463                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8464                        DiagnosticEntry {
 8465                            range: start..end,
 8466                            diagnostic: v.diagnostic.clone(),
 8467                        }
 8468                    })
 8469                    .collect::<Vec<_>>();
 8470
 8471                self.as_local_mut()
 8472                    .context("cannot merge diagnostics on a remote LspStore")?
 8473                    .update_buffer_diagnostics(
 8474                        &buffer_handle,
 8475                        server_id,
 8476                        Some(update.registration_id),
 8477                        update.result_id,
 8478                        update.diagnostics.version,
 8479                        update.diagnostics.diagnostics.clone(),
 8480                        reused_diagnostics.clone(),
 8481                        cx,
 8482                    )?;
 8483
 8484                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8485            } else if let Some(local) = self.as_local() {
 8486                let reused_diagnostics = local
 8487                    .diagnostics
 8488                    .get(&worktree_id)
 8489                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8490                    .and_then(|diagnostics_by_server_id| {
 8491                        diagnostics_by_server_id
 8492                            .binary_search_by_key(&server_id, |e| e.0)
 8493                            .ok()
 8494                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8495                    })
 8496                    .into_iter()
 8497                    .flatten()
 8498                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8499
 8500                update
 8501                    .diagnostics
 8502                    .diagnostics
 8503                    .extend(reused_diagnostics.cloned());
 8504            }
 8505
 8506            let updated = worktree.update(cx, |worktree, cx| {
 8507                self.update_worktree_diagnostics(
 8508                    worktree.id(),
 8509                    server_id,
 8510                    project_path.path.clone(),
 8511                    update.diagnostics.diagnostics,
 8512                    cx,
 8513                )
 8514            })?;
 8515            match updated {
 8516                ControlFlow::Continue(new_summary) => {
 8517                    if let Some((project_id, new_summary)) = new_summary {
 8518                        match &mut diagnostics_summary {
 8519                            Some(diagnostics_summary) => {
 8520                                diagnostics_summary
 8521                                    .more_summaries
 8522                                    .push(proto::DiagnosticSummary {
 8523                                        path: project_path.path.as_ref().to_proto(),
 8524                                        language_server_id: server_id.0 as u64,
 8525                                        error_count: new_summary.error_count,
 8526                                        warning_count: new_summary.warning_count,
 8527                                    })
 8528                            }
 8529                            None => {
 8530                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8531                                    project_id,
 8532                                    worktree_id: worktree_id.to_proto(),
 8533                                    summary: Some(proto::DiagnosticSummary {
 8534                                        path: project_path.path.as_ref().to_proto(),
 8535                                        language_server_id: server_id.0 as u64,
 8536                                        error_count: new_summary.error_count,
 8537                                        warning_count: new_summary.warning_count,
 8538                                    }),
 8539                                    more_summaries: Vec::new(),
 8540                                })
 8541                            }
 8542                        }
 8543                    }
 8544                    updated_diagnostics_paths
 8545                        .entry(server_id)
 8546                        .or_insert_with(Vec::new)
 8547                        .push(project_path);
 8548                }
 8549                ControlFlow::Break(()) => {}
 8550            }
 8551        }
 8552
 8553        if let Some((diagnostics_summary, (downstream_client, _))) =
 8554            diagnostics_summary.zip(self.downstream_client.as_ref())
 8555        {
 8556            downstream_client.send(diagnostics_summary).log_err();
 8557        }
 8558        for (server_id, paths) in updated_diagnostics_paths {
 8559            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8560        }
 8561        Ok(())
 8562    }
 8563
 8564    fn update_worktree_diagnostics(
 8565        &mut self,
 8566        worktree_id: WorktreeId,
 8567        server_id: LanguageServerId,
 8568        path_in_worktree: Arc<RelPath>,
 8569        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8570        _: &mut Context<Worktree>,
 8571    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8572        let local = match &mut self.mode {
 8573            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8574            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8575        };
 8576
 8577        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8578        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8579        let summaries_by_server_id = summaries_for_tree
 8580            .entry(path_in_worktree.clone())
 8581            .or_default();
 8582
 8583        let old_summary = summaries_by_server_id
 8584            .remove(&server_id)
 8585            .unwrap_or_default();
 8586
 8587        let new_summary = DiagnosticSummary::new(&diagnostics);
 8588        if diagnostics.is_empty() {
 8589            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8590            {
 8591                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8592                    diagnostics_by_server_id.remove(ix);
 8593                }
 8594                if diagnostics_by_server_id.is_empty() {
 8595                    diagnostics_for_tree.remove(&path_in_worktree);
 8596                }
 8597            }
 8598        } else {
 8599            summaries_by_server_id.insert(server_id, new_summary);
 8600            let diagnostics_by_server_id = diagnostics_for_tree
 8601                .entry(path_in_worktree.clone())
 8602                .or_default();
 8603            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8604                Ok(ix) => {
 8605                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8606                }
 8607                Err(ix) => {
 8608                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8609                }
 8610            }
 8611        }
 8612
 8613        if !old_summary.is_empty() || !new_summary.is_empty() {
 8614            if let Some((_, project_id)) = &self.downstream_client {
 8615                Ok(ControlFlow::Continue(Some((
 8616                    *project_id,
 8617                    proto::DiagnosticSummary {
 8618                        path: path_in_worktree.to_proto(),
 8619                        language_server_id: server_id.0 as u64,
 8620                        error_count: new_summary.error_count as u32,
 8621                        warning_count: new_summary.warning_count as u32,
 8622                    },
 8623                ))))
 8624            } else {
 8625                Ok(ControlFlow::Continue(None))
 8626            }
 8627        } else {
 8628            Ok(ControlFlow::Break(()))
 8629        }
 8630    }
 8631
 8632    pub fn open_buffer_for_symbol(
 8633        &mut self,
 8634        symbol: &Symbol,
 8635        cx: &mut Context<Self>,
 8636    ) -> Task<Result<Entity<Buffer>>> {
 8637        if let Some((client, project_id)) = self.upstream_client() {
 8638            let request = client.request(proto::OpenBufferForSymbol {
 8639                project_id,
 8640                symbol: Some(Self::serialize_symbol(symbol)),
 8641            });
 8642            cx.spawn(async move |this, cx| {
 8643                let response = request.await?;
 8644                let buffer_id = BufferId::new(response.buffer_id)?;
 8645                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8646                    .await
 8647            })
 8648        } else if let Some(local) = self.as_local() {
 8649            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8650                seed.worktree_id == symbol.source_worktree_id
 8651                    && state.id == symbol.source_language_server_id
 8652                    && symbol.language_server_name == seed.name
 8653            });
 8654            if !is_valid {
 8655                return Task::ready(Err(anyhow!(
 8656                    "language server for worktree and language not found"
 8657                )));
 8658            };
 8659
 8660            let symbol_abs_path = match &symbol.path {
 8661                SymbolLocation::InProject(project_path) => self
 8662                    .worktree_store
 8663                    .read(cx)
 8664                    .absolutize(&project_path, cx)
 8665                    .context("no such worktree"),
 8666                SymbolLocation::OutsideProject {
 8667                    abs_path,
 8668                    signature: _,
 8669                } => Ok(abs_path.to_path_buf()),
 8670            };
 8671            let symbol_abs_path = match symbol_abs_path {
 8672                Ok(abs_path) => abs_path,
 8673                Err(err) => return Task::ready(Err(err)),
 8674            };
 8675            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8676                uri
 8677            } else {
 8678                return Task::ready(Err(anyhow!("invalid symbol path")));
 8679            };
 8680
 8681            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8682        } else {
 8683            Task::ready(Err(anyhow!("no upstream client or local store")))
 8684        }
 8685    }
 8686
 8687    pub(crate) fn open_local_buffer_via_lsp(
 8688        &mut self,
 8689        abs_path: lsp::Uri,
 8690        language_server_id: LanguageServerId,
 8691        cx: &mut Context<Self>,
 8692    ) -> Task<Result<Entity<Buffer>>> {
 8693        let path_style = self.worktree_store.read(cx).path_style();
 8694        cx.spawn(async move |lsp_store, cx| {
 8695            // Escape percent-encoded string.
 8696            let current_scheme = abs_path.scheme().to_owned();
 8697            // Uri is immutable, so we can't modify the scheme
 8698
 8699            let abs_path = abs_path
 8700                .to_file_path_ext(path_style)
 8701                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8702            let p = abs_path.clone();
 8703            let yarn_worktree = lsp_store
 8704                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8705                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8706                        cx.spawn(async move |this, cx| {
 8707                            let t = this
 8708                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8709                                .ok()?;
 8710                            t.await
 8711                        })
 8712                    }),
 8713                    None => Task::ready(None),
 8714                })?
 8715                .await;
 8716            let (worktree_root_target, known_relative_path) =
 8717                if let Some((zip_root, relative_path)) = yarn_worktree {
 8718                    (zip_root, Some(relative_path))
 8719                } else {
 8720                    (Arc::<Path>::from(abs_path.as_path()), None)
 8721                };
 8722            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8723                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8724                    worktree_store.find_worktree(&worktree_root_target, cx)
 8725                })
 8726            })?;
 8727            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8728                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8729                (result.0, relative_path, None)
 8730            } else {
 8731                let worktree = lsp_store
 8732                    .update(cx, |lsp_store, cx| {
 8733                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8734                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8735                        })
 8736                    })?
 8737                    .await?;
 8738                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8739                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8740                    lsp_store
 8741                        .update(cx, |lsp_store, cx| {
 8742                            if let Some(local) = lsp_store.as_local_mut() {
 8743                                local.register_language_server_for_invisible_worktree(
 8744                                    &worktree,
 8745                                    language_server_id,
 8746                                    cx,
 8747                                )
 8748                            }
 8749                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8750                                Some(status) => status.worktree,
 8751                                None => None,
 8752                            }
 8753                        })
 8754                        .ok()
 8755                        .flatten()
 8756                        .zip(Some(worktree_root.clone()))
 8757                } else {
 8758                    None
 8759                };
 8760                let relative_path = if let Some(known_path) = known_relative_path {
 8761                    known_path
 8762                } else {
 8763                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8764                        .into_arc()
 8765                };
 8766                (worktree, relative_path, source_ws)
 8767            };
 8768            let project_path = ProjectPath {
 8769                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8770                path: relative_path,
 8771            };
 8772            let buffer = lsp_store
 8773                .update(cx, |lsp_store, cx| {
 8774                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8775                        buffer_store.open_buffer(project_path, cx)
 8776                    })
 8777                })?
 8778                .await?;
 8779            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8780            if let Some((source_ws, worktree_root)) = source_ws {
 8781                buffer.update(cx, |buffer, cx| {
 8782                    let settings = WorktreeSettings::get(
 8783                        Some(
 8784                            (&ProjectPath {
 8785                                worktree_id: source_ws,
 8786                                path: Arc::from(RelPath::empty()),
 8787                            })
 8788                                .into(),
 8789                        ),
 8790                        cx,
 8791                    );
 8792                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8793                    if is_read_only {
 8794                        buffer.set_capability(Capability::ReadOnly, cx);
 8795                    }
 8796                });
 8797            }
 8798            Ok(buffer)
 8799        })
 8800    }
 8801
 8802    fn local_lsp_servers_for_buffer(
 8803        &self,
 8804        buffer: &Entity<Buffer>,
 8805        cx: &mut Context<Self>,
 8806    ) -> Vec<LanguageServerId> {
 8807        let Some(local) = self.as_local() else {
 8808            return Vec::new();
 8809        };
 8810
 8811        let snapshot = buffer.read(cx).snapshot();
 8812
 8813        buffer.update(cx, |buffer, cx| {
 8814            local
 8815                .language_servers_for_buffer(buffer, cx)
 8816                .map(|(_, server)| server.server_id())
 8817                .filter(|server_id| {
 8818                    self.as_local().is_none_or(|local| {
 8819                        local
 8820                            .buffers_opened_in_servers
 8821                            .get(&snapshot.remote_id())
 8822                            .is_some_and(|servers| servers.contains(server_id))
 8823                    })
 8824                })
 8825                .collect()
 8826        })
 8827    }
 8828
 8829    fn request_multiple_lsp_locally<P, R>(
 8830        &mut self,
 8831        buffer: &Entity<Buffer>,
 8832        position: Option<P>,
 8833        request: R,
 8834        cx: &mut Context<Self>,
 8835    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8836    where
 8837        P: ToOffset,
 8838        R: LspCommand + Clone,
 8839        <R::LspRequest as lsp::request::Request>::Result: Send,
 8840        <R::LspRequest as lsp::request::Request>::Params: Send,
 8841    {
 8842        let Some(local) = self.as_local() else {
 8843            return Task::ready(Vec::new());
 8844        };
 8845
 8846        let snapshot = buffer.read(cx).snapshot();
 8847        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8848
 8849        let server_ids = buffer.update(cx, |buffer, cx| {
 8850            local
 8851                .language_servers_for_buffer(buffer, cx)
 8852                .filter(|(adapter, _)| {
 8853                    scope
 8854                        .as_ref()
 8855                        .map(|scope| scope.language_allowed(&adapter.name))
 8856                        .unwrap_or(true)
 8857                })
 8858                .map(|(_, server)| server.server_id())
 8859                .filter(|server_id| {
 8860                    self.as_local().is_none_or(|local| {
 8861                        local
 8862                            .buffers_opened_in_servers
 8863                            .get(&snapshot.remote_id())
 8864                            .is_some_and(|servers| servers.contains(server_id))
 8865                    })
 8866                })
 8867                .collect::<Vec<_>>()
 8868        });
 8869
 8870        let mut response_results = server_ids
 8871            .into_iter()
 8872            .map(|server_id| {
 8873                let task = self.request_lsp(
 8874                    buffer.clone(),
 8875                    LanguageServerToQuery::Other(server_id),
 8876                    request.clone(),
 8877                    cx,
 8878                );
 8879                async move { (server_id, task.await) }
 8880            })
 8881            .collect::<FuturesUnordered<_>>();
 8882
 8883        cx.background_spawn(async move {
 8884            let mut responses = Vec::with_capacity(response_results.len());
 8885            while let Some((server_id, response_result)) = response_results.next().await {
 8886                match response_result {
 8887                    Ok(response) => responses.push((server_id, response)),
 8888                    // rust-analyzer likes to error with this when its still loading up
 8889                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8890                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8891                }
 8892            }
 8893            responses
 8894        })
 8895    }
 8896
 8897    async fn handle_lsp_get_completions(
 8898        this: Entity<Self>,
 8899        envelope: TypedEnvelope<proto::GetCompletions>,
 8900        mut cx: AsyncApp,
 8901    ) -> Result<proto::GetCompletionsResponse> {
 8902        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8903
 8904        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8905        let buffer_handle = this.update(&mut cx, |this, cx| {
 8906            this.buffer_store.read(cx).get_existing(buffer_id)
 8907        })?;
 8908        let request = GetCompletions::from_proto(
 8909            envelope.payload,
 8910            this.clone(),
 8911            buffer_handle.clone(),
 8912            cx.clone(),
 8913        )
 8914        .await?;
 8915
 8916        let server_to_query = match request.server_id {
 8917            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8918            None => LanguageServerToQuery::FirstCapable,
 8919        };
 8920
 8921        let response = this
 8922            .update(&mut cx, |this, cx| {
 8923                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8924            })
 8925            .await?;
 8926        this.update(&mut cx, |this, cx| {
 8927            Ok(GetCompletions::response_to_proto(
 8928                response,
 8929                this,
 8930                sender_id,
 8931                &buffer_handle.read(cx).version(),
 8932                cx,
 8933            ))
 8934        })
 8935    }
 8936
 8937    async fn handle_lsp_command<T: LspCommand>(
 8938        this: Entity<Self>,
 8939        envelope: TypedEnvelope<T::ProtoRequest>,
 8940        mut cx: AsyncApp,
 8941    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8942    where
 8943        <T::LspRequest as lsp::request::Request>::Params: Send,
 8944        <T::LspRequest as lsp::request::Request>::Result: Send,
 8945    {
 8946        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8947        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8948        let buffer_handle = this.update(&mut cx, |this, cx| {
 8949            this.buffer_store.read(cx).get_existing(buffer_id)
 8950        })?;
 8951        let request = T::from_proto(
 8952            envelope.payload,
 8953            this.clone(),
 8954            buffer_handle.clone(),
 8955            cx.clone(),
 8956        )
 8957        .await?;
 8958        let response = this
 8959            .update(&mut cx, |this, cx| {
 8960                this.request_lsp(
 8961                    buffer_handle.clone(),
 8962                    LanguageServerToQuery::FirstCapable,
 8963                    request,
 8964                    cx,
 8965                )
 8966            })
 8967            .await?;
 8968        this.update(&mut cx, |this, cx| {
 8969            Ok(T::response_to_proto(
 8970                response,
 8971                this,
 8972                sender_id,
 8973                &buffer_handle.read(cx).version(),
 8974                cx,
 8975            ))
 8976        })
 8977    }
 8978
 8979    async fn handle_lsp_query(
 8980        lsp_store: Entity<Self>,
 8981        envelope: TypedEnvelope<proto::LspQuery>,
 8982        mut cx: AsyncApp,
 8983    ) -> Result<proto::Ack> {
 8984        use proto::lsp_query::Request;
 8985        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8986        let lsp_query = envelope.payload;
 8987        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8988        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8989        match lsp_query.request.context("invalid LSP query request")? {
 8990            Request::GetReferences(get_references) => {
 8991                let position = get_references.position.clone().and_then(deserialize_anchor);
 8992                Self::query_lsp_locally::<GetReferences>(
 8993                    lsp_store,
 8994                    server_id,
 8995                    sender_id,
 8996                    lsp_request_id,
 8997                    get_references,
 8998                    position,
 8999                    &mut cx,
 9000                )
 9001                .await?;
 9002            }
 9003            Request::GetDocumentColor(get_document_color) => {
 9004                Self::query_lsp_locally::<GetDocumentColor>(
 9005                    lsp_store,
 9006                    server_id,
 9007                    sender_id,
 9008                    lsp_request_id,
 9009                    get_document_color,
 9010                    None,
 9011                    &mut cx,
 9012                )
 9013                .await?;
 9014            }
 9015            Request::GetFoldingRanges(get_folding_ranges) => {
 9016                Self::query_lsp_locally::<GetFoldingRanges>(
 9017                    lsp_store,
 9018                    server_id,
 9019                    sender_id,
 9020                    lsp_request_id,
 9021                    get_folding_ranges,
 9022                    None,
 9023                    &mut cx,
 9024                )
 9025                .await?;
 9026            }
 9027            Request::GetDocumentSymbols(get_document_symbols) => {
 9028                Self::query_lsp_locally::<GetDocumentSymbols>(
 9029                    lsp_store,
 9030                    server_id,
 9031                    sender_id,
 9032                    lsp_request_id,
 9033                    get_document_symbols,
 9034                    None,
 9035                    &mut cx,
 9036                )
 9037                .await?;
 9038            }
 9039            Request::GetHover(get_hover) => {
 9040                let position = get_hover.position.clone().and_then(deserialize_anchor);
 9041                Self::query_lsp_locally::<GetHover>(
 9042                    lsp_store,
 9043                    server_id,
 9044                    sender_id,
 9045                    lsp_request_id,
 9046                    get_hover,
 9047                    position,
 9048                    &mut cx,
 9049                )
 9050                .await?;
 9051            }
 9052            Request::GetCodeActions(get_code_actions) => {
 9053                Self::query_lsp_locally::<GetCodeActions>(
 9054                    lsp_store,
 9055                    server_id,
 9056                    sender_id,
 9057                    lsp_request_id,
 9058                    get_code_actions,
 9059                    None,
 9060                    &mut cx,
 9061                )
 9062                .await?;
 9063            }
 9064            Request::GetSignatureHelp(get_signature_help) => {
 9065                let position = get_signature_help
 9066                    .position
 9067                    .clone()
 9068                    .and_then(deserialize_anchor);
 9069                Self::query_lsp_locally::<GetSignatureHelp>(
 9070                    lsp_store,
 9071                    server_id,
 9072                    sender_id,
 9073                    lsp_request_id,
 9074                    get_signature_help,
 9075                    position,
 9076                    &mut cx,
 9077                )
 9078                .await?;
 9079            }
 9080            Request::GetCodeLens(get_code_lens) => {
 9081                Self::query_lsp_locally::<GetCodeLens>(
 9082                    lsp_store,
 9083                    server_id,
 9084                    sender_id,
 9085                    lsp_request_id,
 9086                    get_code_lens,
 9087                    None,
 9088                    &mut cx,
 9089                )
 9090                .await?;
 9091            }
 9092            Request::GetDefinition(get_definition) => {
 9093                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9094                Self::query_lsp_locally::<GetDefinitions>(
 9095                    lsp_store,
 9096                    server_id,
 9097                    sender_id,
 9098                    lsp_request_id,
 9099                    get_definition,
 9100                    position,
 9101                    &mut cx,
 9102                )
 9103                .await?;
 9104            }
 9105            Request::GetDeclaration(get_declaration) => {
 9106                let position = get_declaration
 9107                    .position
 9108                    .clone()
 9109                    .and_then(deserialize_anchor);
 9110                Self::query_lsp_locally::<GetDeclarations>(
 9111                    lsp_store,
 9112                    server_id,
 9113                    sender_id,
 9114                    lsp_request_id,
 9115                    get_declaration,
 9116                    position,
 9117                    &mut cx,
 9118                )
 9119                .await?;
 9120            }
 9121            Request::GetTypeDefinition(get_type_definition) => {
 9122                let position = get_type_definition
 9123                    .position
 9124                    .clone()
 9125                    .and_then(deserialize_anchor);
 9126                Self::query_lsp_locally::<GetTypeDefinitions>(
 9127                    lsp_store,
 9128                    server_id,
 9129                    sender_id,
 9130                    lsp_request_id,
 9131                    get_type_definition,
 9132                    position,
 9133                    &mut cx,
 9134                )
 9135                .await?;
 9136            }
 9137            Request::GetImplementation(get_implementation) => {
 9138                let position = get_implementation
 9139                    .position
 9140                    .clone()
 9141                    .and_then(deserialize_anchor);
 9142                Self::query_lsp_locally::<GetImplementations>(
 9143                    lsp_store,
 9144                    server_id,
 9145                    sender_id,
 9146                    lsp_request_id,
 9147                    get_implementation,
 9148                    position,
 9149                    &mut cx,
 9150                )
 9151                .await?;
 9152            }
 9153            Request::InlayHints(inlay_hints) => {
 9154                let query_start = inlay_hints
 9155                    .start
 9156                    .clone()
 9157                    .and_then(deserialize_anchor)
 9158                    .context("invalid inlay hints range start")?;
 9159                let query_end = inlay_hints
 9160                    .end
 9161                    .clone()
 9162                    .and_then(deserialize_anchor)
 9163                    .context("invalid inlay hints range end")?;
 9164                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9165                    &lsp_store,
 9166                    server_id,
 9167                    lsp_request_id,
 9168                    &inlay_hints,
 9169                    query_start..query_end,
 9170                    &mut cx,
 9171                )
 9172                .await
 9173                .context("preparing inlay hints request")?;
 9174                Self::query_lsp_locally::<InlayHints>(
 9175                    lsp_store,
 9176                    server_id,
 9177                    sender_id,
 9178                    lsp_request_id,
 9179                    inlay_hints,
 9180                    None,
 9181                    &mut cx,
 9182                )
 9183                .await
 9184                .context("querying for inlay hints")?
 9185            }
 9186            //////////////////////////////
 9187            // Below are LSP queries that need to fetch more data,
 9188            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 9189            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9190                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 9191                    &lsp_store,
 9192                    &get_document_diagnostics,
 9193                    &mut cx,
 9194                )
 9195                .await?;
 9196                lsp_store.update(&mut cx, |lsp_store, cx| {
 9197                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9198                    let key = LspKey {
 9199                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9200                        server_queried: server_id,
 9201                    };
 9202                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9203                    ) {
 9204                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9205                            lsp_requests.clear();
 9206                        };
 9207                    }
 9208
 9209                    lsp_data.lsp_requests.entry(key).or_default().insert(
 9210                        lsp_request_id,
 9211                        cx.spawn(async move |lsp_store, cx| {
 9212                            let diagnostics_pull = lsp_store
 9213                                .update(cx, |lsp_store, cx| {
 9214                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9215                                })
 9216                                .ok();
 9217                            if let Some(diagnostics_pull) = diagnostics_pull {
 9218                                match diagnostics_pull.await {
 9219                                    Ok(()) => {}
 9220                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9221                                };
 9222                            }
 9223                        }),
 9224                    );
 9225                });
 9226            }
 9227            Request::SemanticTokens(semantic_tokens) => {
 9228                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 9229                    &lsp_store,
 9230                    &semantic_tokens,
 9231                    &mut cx,
 9232                )
 9233                .await?;
 9234                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9235                lsp_store.update(&mut cx, |lsp_store, cx| {
 9236                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9237                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9238                        let key = LspKey {
 9239                            request_type: TypeId::of::<SemanticTokensFull>(),
 9240                            server_queried: server_id,
 9241                        };
 9242                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9243                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9244                                lsp_requests.clear();
 9245                            };
 9246                        }
 9247
 9248                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9249                            lsp_request_id,
 9250                            cx.spawn(async move |lsp_store, cx| {
 9251                                let tokens_fetch = lsp_store
 9252                                    .update(cx, |lsp_store, cx| {
 9253                                        lsp_store
 9254                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9255                                    })
 9256                                    .ok();
 9257                                if let Some(tokens_fetch) = tokens_fetch {
 9258                                    let new_tokens = tokens_fetch.await;
 9259                                    if let Some(new_tokens) = new_tokens {
 9260                                        lsp_store
 9261                                            .update(cx, |lsp_store, cx| {
 9262                                                let response = new_tokens
 9263                                                    .into_iter()
 9264                                                    .map(|(server_id, response)| {
 9265                                                        (
 9266                                                            server_id.to_proto(),
 9267                                                            SemanticTokensFull::response_to_proto(
 9268                                                                response,
 9269                                                                lsp_store,
 9270                                                                sender_id,
 9271                                                                &buffer_version,
 9272                                                                cx,
 9273                                                            ),
 9274                                                        )
 9275                                                    })
 9276                                                    .collect::<HashMap<_, _>>();
 9277                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9278                                                    project_id,
 9279                                                    lsp_request_id,
 9280                                                    response,
 9281                                                ) {
 9282                                                    Ok(()) => {}
 9283                                                    Err(e) => {
 9284                                                        log::error!(
 9285                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9286                                                        )
 9287                                                    }
 9288                                                }
 9289                                            })
 9290                                            .ok();
 9291                                    }
 9292                                }
 9293                            }),
 9294                        );
 9295                    }
 9296                });
 9297            }
 9298        }
 9299        Ok(proto::Ack {})
 9300    }
 9301
 9302    async fn handle_lsp_query_response(
 9303        lsp_store: Entity<Self>,
 9304        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9305        cx: AsyncApp,
 9306    ) -> Result<()> {
 9307        lsp_store.read_with(&cx, |lsp_store, _| {
 9308            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9309                upstream_client.handle_lsp_response(envelope.clone());
 9310            }
 9311        });
 9312        Ok(())
 9313    }
 9314
 9315    async fn handle_apply_code_action(
 9316        this: Entity<Self>,
 9317        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9318        mut cx: AsyncApp,
 9319    ) -> Result<proto::ApplyCodeActionResponse> {
 9320        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9321        let action =
 9322            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9323        let apply_code_action = this.update(&mut cx, |this, cx| {
 9324            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9325            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9326            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9327        })?;
 9328
 9329        let project_transaction = apply_code_action.await?;
 9330        let project_transaction = this.update(&mut cx, |this, cx| {
 9331            this.buffer_store.update(cx, |buffer_store, cx| {
 9332                buffer_store.serialize_project_transaction_for_peer(
 9333                    project_transaction,
 9334                    sender_id,
 9335                    cx,
 9336                )
 9337            })
 9338        });
 9339        Ok(proto::ApplyCodeActionResponse {
 9340            transaction: Some(project_transaction),
 9341        })
 9342    }
 9343
 9344    async fn handle_register_buffer_with_language_servers(
 9345        this: Entity<Self>,
 9346        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9347        mut cx: AsyncApp,
 9348    ) -> Result<proto::Ack> {
 9349        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9350        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9351        this.update(&mut cx, |this, cx| {
 9352            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9353                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9354                    project_id: upstream_project_id,
 9355                    buffer_id: buffer_id.to_proto(),
 9356                    only_servers: envelope.payload.only_servers,
 9357                });
 9358            }
 9359
 9360            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9361                anyhow::bail!("buffer is not open");
 9362            };
 9363
 9364            let handle = this.register_buffer_with_language_servers(
 9365                &buffer,
 9366                envelope
 9367                    .payload
 9368                    .only_servers
 9369                    .into_iter()
 9370                    .filter_map(|selector| {
 9371                        Some(match selector.selector? {
 9372                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9373                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9374                            }
 9375                            proto::language_server_selector::Selector::Name(name) => {
 9376                                LanguageServerSelector::Name(LanguageServerName(
 9377                                    SharedString::from(name),
 9378                                ))
 9379                            }
 9380                        })
 9381                    })
 9382                    .collect(),
 9383                false,
 9384                cx,
 9385            );
 9386            // Pull diagnostics for the buffer even if it was already registered.
 9387            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9388            // but it's unclear if we need it.
 9389            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9390                .detach();
 9391            this.buffer_store().update(cx, |buffer_store, _| {
 9392                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9393            });
 9394
 9395            Ok(())
 9396        })?;
 9397        Ok(proto::Ack {})
 9398    }
 9399
 9400    async fn handle_rename_project_entry(
 9401        this: Entity<Self>,
 9402        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9403        mut cx: AsyncApp,
 9404    ) -> Result<proto::ProjectEntryResponse> {
 9405        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9406        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9407        let new_path =
 9408            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9409
 9410        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9411            .update(&mut cx, |this, cx| {
 9412                let (worktree, entry) = this
 9413                    .worktree_store
 9414                    .read(cx)
 9415                    .worktree_and_entry_for_id(entry_id, cx)?;
 9416                let new_worktree = this
 9417                    .worktree_store
 9418                    .read(cx)
 9419                    .worktree_for_id(new_worktree_id, cx)?;
 9420                Some((
 9421                    this.worktree_store.clone(),
 9422                    worktree,
 9423                    new_worktree,
 9424                    entry.clone(),
 9425                ))
 9426            })
 9427            .context("worktree not found")?;
 9428        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9429            (worktree.absolutize(&old_entry.path), worktree.id())
 9430        });
 9431        let new_abs_path =
 9432            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9433
 9434        let _transaction = Self::will_rename_entry(
 9435            this.downgrade(),
 9436            old_worktree_id,
 9437            &old_abs_path,
 9438            &new_abs_path,
 9439            old_entry.is_dir(),
 9440            cx.clone(),
 9441        )
 9442        .await;
 9443        let response = WorktreeStore::handle_rename_project_entry(
 9444            worktree_store,
 9445            envelope.payload,
 9446            cx.clone(),
 9447        )
 9448        .await;
 9449        this.read_with(&cx, |this, _| {
 9450            this.did_rename_entry(
 9451                old_worktree_id,
 9452                &old_abs_path,
 9453                &new_abs_path,
 9454                old_entry.is_dir(),
 9455            );
 9456        });
 9457        response
 9458    }
 9459
 9460    async fn handle_update_diagnostic_summary(
 9461        this: Entity<Self>,
 9462        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9463        mut cx: AsyncApp,
 9464    ) -> Result<()> {
 9465        this.update(&mut cx, |lsp_store, cx| {
 9466            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9467            let mut updated_diagnostics_paths = HashMap::default();
 9468            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9469            for message_summary in envelope
 9470                .payload
 9471                .summary
 9472                .into_iter()
 9473                .chain(envelope.payload.more_summaries)
 9474            {
 9475                let project_path = ProjectPath {
 9476                    worktree_id,
 9477                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9478                };
 9479                let path = project_path.path.clone();
 9480                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9481                let summary = DiagnosticSummary {
 9482                    error_count: message_summary.error_count as usize,
 9483                    warning_count: message_summary.warning_count as usize,
 9484                };
 9485
 9486                if summary.is_empty() {
 9487                    if let Some(worktree_summaries) =
 9488                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9489                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9490                    {
 9491                        summaries.remove(&server_id);
 9492                        if summaries.is_empty() {
 9493                            worktree_summaries.remove(&path);
 9494                        }
 9495                    }
 9496                } else {
 9497                    lsp_store
 9498                        .diagnostic_summaries
 9499                        .entry(worktree_id)
 9500                        .or_default()
 9501                        .entry(path)
 9502                        .or_default()
 9503                        .insert(server_id, summary);
 9504                }
 9505
 9506                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9507                    match &mut diagnostics_summary {
 9508                        Some(diagnostics_summary) => {
 9509                            diagnostics_summary
 9510                                .more_summaries
 9511                                .push(proto::DiagnosticSummary {
 9512                                    path: project_path.path.as_ref().to_proto(),
 9513                                    language_server_id: server_id.0 as u64,
 9514                                    error_count: summary.error_count as u32,
 9515                                    warning_count: summary.warning_count as u32,
 9516                                })
 9517                        }
 9518                        None => {
 9519                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9520                                project_id: *project_id,
 9521                                worktree_id: worktree_id.to_proto(),
 9522                                summary: Some(proto::DiagnosticSummary {
 9523                                    path: project_path.path.as_ref().to_proto(),
 9524                                    language_server_id: server_id.0 as u64,
 9525                                    error_count: summary.error_count as u32,
 9526                                    warning_count: summary.warning_count as u32,
 9527                                }),
 9528                                more_summaries: Vec::new(),
 9529                            })
 9530                        }
 9531                    }
 9532                }
 9533                updated_diagnostics_paths
 9534                    .entry(server_id)
 9535                    .or_insert_with(Vec::new)
 9536                    .push(project_path);
 9537            }
 9538
 9539            if let Some((diagnostics_summary, (downstream_client, _))) =
 9540                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9541            {
 9542                downstream_client.send(diagnostics_summary).log_err();
 9543            }
 9544            for (server_id, paths) in updated_diagnostics_paths {
 9545                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9546            }
 9547            Ok(())
 9548        })
 9549    }
 9550
 9551    async fn handle_start_language_server(
 9552        lsp_store: Entity<Self>,
 9553        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9554        mut cx: AsyncApp,
 9555    ) -> Result<()> {
 9556        let server = envelope.payload.server.context("invalid server")?;
 9557        let server_capabilities =
 9558            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9559                .with_context(|| {
 9560                    format!(
 9561                        "incorrect server capabilities {}",
 9562                        envelope.payload.capabilities
 9563                    )
 9564                })?;
 9565        lsp_store.update(&mut cx, |lsp_store, cx| {
 9566            let server_id = LanguageServerId(server.id as usize);
 9567            let server_name = LanguageServerName::from_proto(server.name.clone());
 9568            lsp_store
 9569                .lsp_server_capabilities
 9570                .insert(server_id, server_capabilities);
 9571            lsp_store.language_server_statuses.insert(
 9572                server_id,
 9573                LanguageServerStatus {
 9574                    name: server_name.clone(),
 9575                    server_version: None,
 9576                    server_readable_version: None,
 9577                    pending_work: Default::default(),
 9578                    has_pending_diagnostic_updates: false,
 9579                    progress_tokens: Default::default(),
 9580                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9581                    binary: None,
 9582                    configuration: None,
 9583                    workspace_folders: BTreeSet::new(),
 9584                    process_id: None,
 9585                },
 9586            );
 9587            cx.emit(LspStoreEvent::LanguageServerAdded(
 9588                server_id,
 9589                server_name,
 9590                server.worktree_id.map(WorktreeId::from_proto),
 9591            ));
 9592            cx.notify();
 9593        });
 9594        Ok(())
 9595    }
 9596
 9597    async fn handle_update_language_server(
 9598        lsp_store: Entity<Self>,
 9599        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9600        mut cx: AsyncApp,
 9601    ) -> Result<()> {
 9602        lsp_store.update(&mut cx, |lsp_store, cx| {
 9603            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9604
 9605            match envelope.payload.variant.context("invalid variant")? {
 9606                proto::update_language_server::Variant::WorkStart(payload) => {
 9607                    lsp_store.on_lsp_work_start(
 9608                        language_server_id,
 9609                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9610                            .context("invalid progress token value")?,
 9611                        LanguageServerProgress {
 9612                            title: payload.title,
 9613                            is_disk_based_diagnostics_progress: false,
 9614                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9615                            message: payload.message,
 9616                            percentage: payload.percentage.map(|p| p as usize),
 9617                            last_update_at: cx.background_executor().now(),
 9618                        },
 9619                        cx,
 9620                    );
 9621                }
 9622                proto::update_language_server::Variant::WorkProgress(payload) => {
 9623                    lsp_store.on_lsp_work_progress(
 9624                        language_server_id,
 9625                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9626                            .context("invalid progress token value")?,
 9627                        LanguageServerProgress {
 9628                            title: None,
 9629                            is_disk_based_diagnostics_progress: false,
 9630                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9631                            message: payload.message,
 9632                            percentage: payload.percentage.map(|p| p as usize),
 9633                            last_update_at: cx.background_executor().now(),
 9634                        },
 9635                        cx,
 9636                    );
 9637                }
 9638
 9639                proto::update_language_server::Variant::WorkEnd(payload) => {
 9640                    lsp_store.on_lsp_work_end(
 9641                        language_server_id,
 9642                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9643                            .context("invalid progress token value")?,
 9644                        cx,
 9645                    );
 9646                }
 9647
 9648                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9649                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9650                }
 9651
 9652                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9653                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9654                }
 9655
 9656                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9657                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9658                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9659                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9660                        language_server_id,
 9661                        name: envelope
 9662                            .payload
 9663                            .server_name
 9664                            .map(SharedString::new)
 9665                            .map(LanguageServerName),
 9666                        message: non_lsp,
 9667                    });
 9668                }
 9669            }
 9670
 9671            Ok(())
 9672        })
 9673    }
 9674
 9675    async fn handle_language_server_log(
 9676        this: Entity<Self>,
 9677        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9678        mut cx: AsyncApp,
 9679    ) -> Result<()> {
 9680        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9681        let log_type = envelope
 9682            .payload
 9683            .log_type
 9684            .map(LanguageServerLogType::from_proto)
 9685            .context("invalid language server log type")?;
 9686
 9687        let message = envelope.payload.message;
 9688
 9689        this.update(&mut cx, |_, cx| {
 9690            cx.emit(LspStoreEvent::LanguageServerLog(
 9691                language_server_id,
 9692                log_type,
 9693                message,
 9694            ));
 9695        });
 9696        Ok(())
 9697    }
 9698
 9699    async fn handle_lsp_ext_cancel_flycheck(
 9700        lsp_store: Entity<Self>,
 9701        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9702        cx: AsyncApp,
 9703    ) -> Result<proto::Ack> {
 9704        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9705        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9706            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9707                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9708            } else {
 9709                None
 9710            }
 9711        });
 9712        if let Some(task) = task {
 9713            task.context("handling lsp ext cancel flycheck")?;
 9714        }
 9715
 9716        Ok(proto::Ack {})
 9717    }
 9718
 9719    async fn handle_lsp_ext_run_flycheck(
 9720        lsp_store: Entity<Self>,
 9721        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9722        mut cx: AsyncApp,
 9723    ) -> Result<proto::Ack> {
 9724        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9725        lsp_store.update(&mut cx, |lsp_store, cx| {
 9726            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9727                let text_document = if envelope.payload.current_file_only {
 9728                    let buffer_id = envelope
 9729                        .payload
 9730                        .buffer_id
 9731                        .map(|id| BufferId::new(id))
 9732                        .transpose()?;
 9733                    buffer_id
 9734                        .and_then(|buffer_id| {
 9735                            lsp_store
 9736                                .buffer_store()
 9737                                .read(cx)
 9738                                .get(buffer_id)
 9739                                .and_then(|buffer| {
 9740                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9741                                })
 9742                                .map(|path| make_text_document_identifier(&path))
 9743                        })
 9744                        .transpose()?
 9745                } else {
 9746                    None
 9747                };
 9748                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9749                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9750                )?;
 9751            }
 9752            anyhow::Ok(())
 9753        })?;
 9754
 9755        Ok(proto::Ack {})
 9756    }
 9757
 9758    async fn handle_lsp_ext_clear_flycheck(
 9759        lsp_store: Entity<Self>,
 9760        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9761        cx: AsyncApp,
 9762    ) -> Result<proto::Ack> {
 9763        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9764        lsp_store.read_with(&cx, |lsp_store, _| {
 9765            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9766                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9767            } else {
 9768                None
 9769            }
 9770        });
 9771
 9772        Ok(proto::Ack {})
 9773    }
 9774
 9775    pub fn disk_based_diagnostics_started(
 9776        &mut self,
 9777        language_server_id: LanguageServerId,
 9778        cx: &mut Context<Self>,
 9779    ) {
 9780        if let Some(language_server_status) =
 9781            self.language_server_statuses.get_mut(&language_server_id)
 9782        {
 9783            language_server_status.has_pending_diagnostic_updates = true;
 9784        }
 9785
 9786        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9787        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9788            language_server_id,
 9789            name: self
 9790                .language_server_adapter_for_id(language_server_id)
 9791                .map(|adapter| adapter.name()),
 9792            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9793                Default::default(),
 9794            ),
 9795        })
 9796    }
 9797
 9798    pub fn disk_based_diagnostics_finished(
 9799        &mut self,
 9800        language_server_id: LanguageServerId,
 9801        cx: &mut Context<Self>,
 9802    ) {
 9803        if let Some(language_server_status) =
 9804            self.language_server_statuses.get_mut(&language_server_id)
 9805        {
 9806            language_server_status.has_pending_diagnostic_updates = false;
 9807        }
 9808
 9809        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9810        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9811            language_server_id,
 9812            name: self
 9813                .language_server_adapter_for_id(language_server_id)
 9814                .map(|adapter| adapter.name()),
 9815            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9816                Default::default(),
 9817            ),
 9818        })
 9819    }
 9820
 9821    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9822    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9823    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9824    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9825    // the language server might take some time to publish diagnostics.
 9826    fn simulate_disk_based_diagnostics_events_if_needed(
 9827        &mut self,
 9828        language_server_id: LanguageServerId,
 9829        cx: &mut Context<Self>,
 9830    ) {
 9831        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9832
 9833        let Some(LanguageServerState::Running {
 9834            simulate_disk_based_diagnostics_completion,
 9835            adapter,
 9836            ..
 9837        }) = self
 9838            .as_local_mut()
 9839            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9840        else {
 9841            return;
 9842        };
 9843
 9844        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9845            return;
 9846        }
 9847
 9848        let prev_task =
 9849            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9850                cx.background_executor()
 9851                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9852                    .await;
 9853
 9854                this.update(cx, |this, cx| {
 9855                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9856
 9857                    if let Some(LanguageServerState::Running {
 9858                        simulate_disk_based_diagnostics_completion,
 9859                        ..
 9860                    }) = this.as_local_mut().and_then(|local_store| {
 9861                        local_store.language_servers.get_mut(&language_server_id)
 9862                    }) {
 9863                        *simulate_disk_based_diagnostics_completion = None;
 9864                    }
 9865                })
 9866                .ok();
 9867            }));
 9868
 9869        if prev_task.is_none() {
 9870            self.disk_based_diagnostics_started(language_server_id, cx);
 9871        }
 9872    }
 9873
 9874    pub fn language_server_statuses(
 9875        &self,
 9876    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9877        self.language_server_statuses
 9878            .iter()
 9879            .map(|(key, value)| (*key, value))
 9880    }
 9881
 9882    pub(super) fn did_rename_entry(
 9883        &self,
 9884        worktree_id: WorktreeId,
 9885        old_path: &Path,
 9886        new_path: &Path,
 9887        is_dir: bool,
 9888    ) {
 9889        maybe!({
 9890            let local_store = self.as_local()?;
 9891
 9892            let old_uri = lsp::Uri::from_file_path(old_path)
 9893                .ok()
 9894                .map(|uri| uri.to_string())?;
 9895            let new_uri = lsp::Uri::from_file_path(new_path)
 9896                .ok()
 9897                .map(|uri| uri.to_string())?;
 9898
 9899            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9900                let Some(filter) = local_store
 9901                    .language_server_paths_watched_for_rename
 9902                    .get(&language_server.server_id())
 9903                else {
 9904                    continue;
 9905                };
 9906
 9907                if filter.should_send_did_rename(&old_uri, is_dir) {
 9908                    language_server
 9909                        .notify::<DidRenameFiles>(RenameFilesParams {
 9910                            files: vec![FileRename {
 9911                                old_uri: old_uri.clone(),
 9912                                new_uri: new_uri.clone(),
 9913                            }],
 9914                        })
 9915                        .ok();
 9916                }
 9917            }
 9918            Some(())
 9919        });
 9920    }
 9921
 9922    pub(super) fn will_rename_entry(
 9923        this: WeakEntity<Self>,
 9924        worktree_id: WorktreeId,
 9925        old_path: &Path,
 9926        new_path: &Path,
 9927        is_dir: bool,
 9928        cx: AsyncApp,
 9929    ) -> Task<ProjectTransaction> {
 9930        let old_uri = lsp::Uri::from_file_path(old_path)
 9931            .ok()
 9932            .map(|uri| uri.to_string());
 9933        let new_uri = lsp::Uri::from_file_path(new_path)
 9934            .ok()
 9935            .map(|uri| uri.to_string());
 9936        cx.spawn(async move |cx| {
 9937            let mut tasks = vec![];
 9938            this.update(cx, |this, cx| {
 9939                let local_store = this.as_local()?;
 9940                let old_uri = old_uri?;
 9941                let new_uri = new_uri?;
 9942                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9943                    let Some(filter) = local_store
 9944                        .language_server_paths_watched_for_rename
 9945                        .get(&language_server.server_id())
 9946                    else {
 9947                        continue;
 9948                    };
 9949
 9950                    if !filter.should_send_will_rename(&old_uri, is_dir) {
 9951                        continue;
 9952                    }
 9953                    let request_timeout = ProjectSettings::get_global(cx)
 9954                        .global_lsp_settings
 9955                        .get_request_timeout();
 9956
 9957                    let apply_edit = cx.spawn({
 9958                        let old_uri = old_uri.clone();
 9959                        let new_uri = new_uri.clone();
 9960                        let language_server = language_server.clone();
 9961                        async move |this, cx| {
 9962                            let edit = language_server
 9963                                .request::<WillRenameFiles>(
 9964                                    RenameFilesParams {
 9965                                        files: vec![FileRename { old_uri, new_uri }],
 9966                                    },
 9967                                    request_timeout,
 9968                                )
 9969                                .await
 9970                                .into_response()
 9971                                .context("will rename files")
 9972                                .log_err()
 9973                                .flatten()?;
 9974
 9975                            LocalLspStore::deserialize_workspace_edit(
 9976                                this.upgrade()?,
 9977                                edit,
 9978                                false,
 9979                                language_server.clone(),
 9980                                cx,
 9981                            )
 9982                            .await
 9983                            .ok()
 9984                        }
 9985                    });
 9986                    tasks.push(apply_edit);
 9987                }
 9988                Some(())
 9989            })
 9990            .ok()
 9991            .flatten();
 9992            let mut merged_transaction = ProjectTransaction::default();
 9993            for task in tasks {
 9994                // Await on tasks sequentially so that the order of application of edits is deterministic
 9995                // (at least with regards to the order of registration of language servers)
 9996                if let Some(transaction) = task.await {
 9997                    for (buffer, buffer_transaction) in transaction.0 {
 9998                        merged_transaction.0.insert(buffer, buffer_transaction);
 9999                    }
10000                }
10001            }
10002            merged_transaction
10003        })
10004    }
10005
10006    fn lsp_notify_abs_paths_changed(
10007        &mut self,
10008        server_id: LanguageServerId,
10009        changes: Vec<PathEvent>,
10010    ) {
10011        maybe!({
10012            let server = self.language_server_for_id(server_id)?;
10013            let changes = changes
10014                .into_iter()
10015                .filter_map(|event| {
10016                    let typ = match event.kind? {
10017                        PathEventKind::Created => lsp::FileChangeType::CREATED,
10018                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
10019                        PathEventKind::Changed | PathEventKind::Rescan => {
10020                            lsp::FileChangeType::CHANGED
10021                        }
10022                    };
10023                    Some(lsp::FileEvent {
10024                        uri: file_path_to_lsp_url(&event.path).log_err()?,
10025                        typ,
10026                    })
10027                })
10028                .collect::<Vec<_>>();
10029            if !changes.is_empty() {
10030                server
10031                    .notify::<lsp::notification::DidChangeWatchedFiles>(
10032                        lsp::DidChangeWatchedFilesParams { changes },
10033                    )
10034                    .ok();
10035            }
10036            Some(())
10037        });
10038    }
10039
10040    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
10041        self.as_local()?.language_server_for_id(id)
10042    }
10043
10044    fn on_lsp_progress(
10045        &mut self,
10046        progress_params: lsp::ProgressParams,
10047        language_server_id: LanguageServerId,
10048        disk_based_diagnostics_progress_token: Option<String>,
10049        cx: &mut Context<Self>,
10050    ) {
10051        match progress_params.value {
10052            lsp::ProgressParamsValue::WorkDone(progress) => {
10053                self.handle_work_done_progress(
10054                    progress,
10055                    language_server_id,
10056                    disk_based_diagnostics_progress_token,
10057                    ProgressToken::from_lsp(progress_params.token),
10058                    cx,
10059                );
10060            }
10061            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
10062                let registration_id = match progress_params.token {
10063                    lsp::NumberOrString::Number(_) => None,
10064                    lsp::NumberOrString::String(token) => token
10065                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
10066                        .map(|(_, id)| id.to_owned()),
10067                };
10068                if let Some(LanguageServerState::Running {
10069                    workspace_diagnostics_refresh_tasks,
10070                    ..
10071                }) = self
10072                    .as_local_mut()
10073                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
10074                    && let Some(workspace_diagnostics) =
10075                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
10076                {
10077                    workspace_diagnostics.progress_tx.try_send(()).ok();
10078                    self.apply_workspace_diagnostic_report(
10079                        language_server_id,
10080                        report,
10081                        registration_id.map(SharedString::from),
10082                        cx,
10083                    )
10084                }
10085            }
10086        }
10087    }
10088
10089    fn handle_work_done_progress(
10090        &mut self,
10091        progress: lsp::WorkDoneProgress,
10092        language_server_id: LanguageServerId,
10093        disk_based_diagnostics_progress_token: Option<String>,
10094        token: ProgressToken,
10095        cx: &mut Context<Self>,
10096    ) {
10097        let language_server_status =
10098            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10099                status
10100            } else {
10101                return;
10102            };
10103
10104        if !language_server_status.progress_tokens.contains(&token) {
10105            return;
10106        }
10107
10108        let is_disk_based_diagnostics_progress =
10109            if let (Some(disk_based_token), ProgressToken::String(token)) =
10110                (&disk_based_diagnostics_progress_token, &token)
10111            {
10112                token.starts_with(disk_based_token)
10113            } else {
10114                false
10115            };
10116
10117        match progress {
10118            lsp::WorkDoneProgress::Begin(report) => {
10119                if is_disk_based_diagnostics_progress {
10120                    self.disk_based_diagnostics_started(language_server_id, cx);
10121                }
10122                self.on_lsp_work_start(
10123                    language_server_id,
10124                    token.clone(),
10125                    LanguageServerProgress {
10126                        title: Some(report.title),
10127                        is_disk_based_diagnostics_progress,
10128                        is_cancellable: report.cancellable.unwrap_or(false),
10129                        message: report.message.clone(),
10130                        percentage: report.percentage.map(|p| p as usize),
10131                        last_update_at: cx.background_executor().now(),
10132                    },
10133                    cx,
10134                );
10135            }
10136            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10137                language_server_id,
10138                token,
10139                LanguageServerProgress {
10140                    title: None,
10141                    is_disk_based_diagnostics_progress,
10142                    is_cancellable: report.cancellable.unwrap_or(false),
10143                    message: report.message,
10144                    percentage: report.percentage.map(|p| p as usize),
10145                    last_update_at: cx.background_executor().now(),
10146                },
10147                cx,
10148            ),
10149            lsp::WorkDoneProgress::End(_) => {
10150                language_server_status.progress_tokens.remove(&token);
10151                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10152                if is_disk_based_diagnostics_progress {
10153                    self.disk_based_diagnostics_finished(language_server_id, cx);
10154                }
10155            }
10156        }
10157    }
10158
10159    fn on_lsp_work_start(
10160        &mut self,
10161        language_server_id: LanguageServerId,
10162        token: ProgressToken,
10163        progress: LanguageServerProgress,
10164        cx: &mut Context<Self>,
10165    ) {
10166        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10167            status.pending_work.insert(token.clone(), progress.clone());
10168            cx.notify();
10169        }
10170        cx.emit(LspStoreEvent::LanguageServerUpdate {
10171            language_server_id,
10172            name: self
10173                .language_server_adapter_for_id(language_server_id)
10174                .map(|adapter| adapter.name()),
10175            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10176                token: Some(token.to_proto()),
10177                title: progress.title,
10178                message: progress.message,
10179                percentage: progress.percentage.map(|p| p as u32),
10180                is_cancellable: Some(progress.is_cancellable),
10181            }),
10182        })
10183    }
10184
10185    fn on_lsp_work_progress(
10186        &mut self,
10187        language_server_id: LanguageServerId,
10188        token: ProgressToken,
10189        progress: LanguageServerProgress,
10190        cx: &mut Context<Self>,
10191    ) {
10192        let mut did_update = false;
10193        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10194            match status.pending_work.entry(token.clone()) {
10195                btree_map::Entry::Vacant(entry) => {
10196                    entry.insert(progress.clone());
10197                    did_update = true;
10198                }
10199                btree_map::Entry::Occupied(mut entry) => {
10200                    let entry = entry.get_mut();
10201                    if (progress.last_update_at - entry.last_update_at)
10202                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10203                    {
10204                        entry.last_update_at = progress.last_update_at;
10205                        if progress.message.is_some() {
10206                            entry.message = progress.message.clone();
10207                        }
10208                        if progress.percentage.is_some() {
10209                            entry.percentage = progress.percentage;
10210                        }
10211                        if progress.is_cancellable != entry.is_cancellable {
10212                            entry.is_cancellable = progress.is_cancellable;
10213                        }
10214                        did_update = true;
10215                    }
10216                }
10217            }
10218        }
10219
10220        if did_update {
10221            cx.emit(LspStoreEvent::LanguageServerUpdate {
10222                language_server_id,
10223                name: self
10224                    .language_server_adapter_for_id(language_server_id)
10225                    .map(|adapter| adapter.name()),
10226                message: proto::update_language_server::Variant::WorkProgress(
10227                    proto::LspWorkProgress {
10228                        token: Some(token.to_proto()),
10229                        message: progress.message,
10230                        percentage: progress.percentage.map(|p| p as u32),
10231                        is_cancellable: Some(progress.is_cancellable),
10232                    },
10233                ),
10234            })
10235        }
10236    }
10237
10238    fn on_lsp_work_end(
10239        &mut self,
10240        language_server_id: LanguageServerId,
10241        token: ProgressToken,
10242        cx: &mut Context<Self>,
10243    ) {
10244        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10245            if let Some(work) = status.pending_work.remove(&token)
10246                && !work.is_disk_based_diagnostics_progress
10247            {
10248                cx.emit(LspStoreEvent::RefreshInlayHints {
10249                    server_id: language_server_id,
10250                    request_id: None,
10251                });
10252            }
10253            cx.notify();
10254        }
10255
10256        cx.emit(LspStoreEvent::LanguageServerUpdate {
10257            language_server_id,
10258            name: self
10259                .language_server_adapter_for_id(language_server_id)
10260                .map(|adapter| adapter.name()),
10261            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10262                token: Some(token.to_proto()),
10263            }),
10264        })
10265    }
10266
10267    pub async fn handle_resolve_completion_documentation(
10268        this: Entity<Self>,
10269        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10270        mut cx: AsyncApp,
10271    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10272        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10273
10274        let completion = this
10275            .read_with(&cx, |this, cx| {
10276                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10277                let server = this
10278                    .language_server_for_id(id)
10279                    .with_context(|| format!("No language server {id}"))?;
10280
10281                let request_timeout = ProjectSettings::get_global(cx)
10282                    .global_lsp_settings
10283                    .get_request_timeout();
10284
10285                anyhow::Ok(cx.background_spawn(async move {
10286                    let can_resolve = server
10287                        .capabilities()
10288                        .completion_provider
10289                        .as_ref()
10290                        .and_then(|options| options.resolve_provider)
10291                        .unwrap_or(false);
10292                    if can_resolve {
10293                        server
10294                            .request::<lsp::request::ResolveCompletionItem>(
10295                                lsp_completion,
10296                                request_timeout,
10297                            )
10298                            .await
10299                            .into_response()
10300                            .context("resolve completion item")
10301                    } else {
10302                        anyhow::Ok(lsp_completion)
10303                    }
10304                }))
10305            })?
10306            .await?;
10307
10308        let mut documentation_is_markdown = false;
10309        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10310        let documentation = match completion.documentation {
10311            Some(lsp::Documentation::String(text)) => text,
10312
10313            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10314                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10315                value
10316            }
10317
10318            _ => String::new(),
10319        };
10320
10321        // If we have a new buffer_id, that means we're talking to a new client
10322        // and want to check for new text_edits in the completion too.
10323        let mut old_replace_start = None;
10324        let mut old_replace_end = None;
10325        let mut old_insert_start = None;
10326        let mut old_insert_end = None;
10327        let mut new_text = String::default();
10328        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10329            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10330                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10331                anyhow::Ok(buffer.read(cx).snapshot())
10332            })?;
10333
10334            if let Some(text_edit) = completion.text_edit.as_ref() {
10335                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10336
10337                if let Some(mut edit) = edit {
10338                    LineEnding::normalize(&mut edit.new_text);
10339
10340                    new_text = edit.new_text;
10341                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10342                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10343                    if let Some(insert_range) = edit.insert_range {
10344                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10345                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10346                    }
10347                }
10348            }
10349        }
10350
10351        Ok(proto::ResolveCompletionDocumentationResponse {
10352            documentation,
10353            documentation_is_markdown,
10354            old_replace_start,
10355            old_replace_end,
10356            new_text,
10357            lsp_completion,
10358            old_insert_start,
10359            old_insert_end,
10360        })
10361    }
10362
10363    async fn handle_on_type_formatting(
10364        this: Entity<Self>,
10365        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10366        mut cx: AsyncApp,
10367    ) -> Result<proto::OnTypeFormattingResponse> {
10368        let on_type_formatting = this.update(&mut cx, |this, cx| {
10369            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10370            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10371            let position = envelope
10372                .payload
10373                .position
10374                .and_then(deserialize_anchor)
10375                .context("invalid position")?;
10376            anyhow::Ok(this.apply_on_type_formatting(
10377                buffer,
10378                position,
10379                envelope.payload.trigger.clone(),
10380                cx,
10381            ))
10382        })?;
10383
10384        let transaction = on_type_formatting
10385            .await?
10386            .as_ref()
10387            .map(language::proto::serialize_transaction);
10388        Ok(proto::OnTypeFormattingResponse { transaction })
10389    }
10390
10391    async fn handle_pull_workspace_diagnostics(
10392        lsp_store: Entity<Self>,
10393        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10394        mut cx: AsyncApp,
10395    ) -> Result<proto::Ack> {
10396        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10397        lsp_store.update(&mut cx, |lsp_store, _| {
10398            lsp_store.pull_workspace_diagnostics(server_id);
10399        });
10400        Ok(proto::Ack {})
10401    }
10402
10403    async fn handle_open_buffer_for_symbol(
10404        this: Entity<Self>,
10405        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10406        mut cx: AsyncApp,
10407    ) -> Result<proto::OpenBufferForSymbolResponse> {
10408        let peer_id = envelope.original_sender_id().unwrap_or_default();
10409        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10410        let symbol = Self::deserialize_symbol(symbol)?;
10411        this.read_with(&cx, |this, _| {
10412            if let SymbolLocation::OutsideProject {
10413                abs_path,
10414                signature,
10415            } = &symbol.path
10416            {
10417                let new_signature = this.symbol_signature(&abs_path);
10418                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10419            }
10420            Ok(())
10421        })?;
10422        let buffer = this
10423            .update(&mut cx, |this, cx| {
10424                this.open_buffer_for_symbol(
10425                    &Symbol {
10426                        language_server_name: symbol.language_server_name,
10427                        source_worktree_id: symbol.source_worktree_id,
10428                        source_language_server_id: symbol.source_language_server_id,
10429                        path: symbol.path,
10430                        name: symbol.name,
10431                        kind: symbol.kind,
10432                        range: symbol.range,
10433                        label: CodeLabel::default(),
10434                        container_name: symbol.container_name,
10435                    },
10436                    cx,
10437                )
10438            })
10439            .await?;
10440
10441        this.update(&mut cx, |this, cx| {
10442            let is_private = buffer
10443                .read(cx)
10444                .file()
10445                .map(|f| f.is_private())
10446                .unwrap_or_default();
10447            if is_private {
10448                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10449            } else {
10450                this.buffer_store
10451                    .update(cx, |buffer_store, cx| {
10452                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10453                    })
10454                    .detach_and_log_err(cx);
10455                let buffer_id = buffer.read(cx).remote_id().to_proto();
10456                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10457            }
10458        })
10459    }
10460
10461    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10462        let mut hasher = Sha256::new();
10463        hasher.update(abs_path.to_string_lossy().as_bytes());
10464        hasher.update(self.nonce.to_be_bytes());
10465        hasher.finalize().as_slice().try_into().unwrap()
10466    }
10467
10468    pub async fn handle_get_project_symbols(
10469        this: Entity<Self>,
10470        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10471        mut cx: AsyncApp,
10472    ) -> Result<proto::GetProjectSymbolsResponse> {
10473        let symbols = this
10474            .update(&mut cx, |this, cx| {
10475                this.symbols(&envelope.payload.query, cx)
10476            })
10477            .await?;
10478
10479        Ok(proto::GetProjectSymbolsResponse {
10480            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10481        })
10482    }
10483
10484    pub async fn handle_restart_language_servers(
10485        this: Entity<Self>,
10486        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10487        mut cx: AsyncApp,
10488    ) -> Result<proto::Ack> {
10489        this.update(&mut cx, |lsp_store, cx| {
10490            let buffers =
10491                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10492            lsp_store.restart_language_servers_for_buffers(
10493                buffers,
10494                envelope
10495                    .payload
10496                    .only_servers
10497                    .into_iter()
10498                    .filter_map(|selector| {
10499                        Some(match selector.selector? {
10500                            proto::language_server_selector::Selector::ServerId(server_id) => {
10501                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10502                            }
10503                            proto::language_server_selector::Selector::Name(name) => {
10504                                LanguageServerSelector::Name(LanguageServerName(
10505                                    SharedString::from(name),
10506                                ))
10507                            }
10508                        })
10509                    })
10510                    .collect(),
10511                cx,
10512            );
10513        });
10514
10515        Ok(proto::Ack {})
10516    }
10517
10518    pub async fn handle_stop_language_servers(
10519        lsp_store: Entity<Self>,
10520        envelope: TypedEnvelope<proto::StopLanguageServers>,
10521        mut cx: AsyncApp,
10522    ) -> Result<proto::Ack> {
10523        lsp_store.update(&mut cx, |lsp_store, cx| {
10524            if envelope.payload.all
10525                && envelope.payload.also_servers.is_empty()
10526                && envelope.payload.buffer_ids.is_empty()
10527            {
10528                lsp_store.stop_all_language_servers(cx);
10529            } else {
10530                let buffers =
10531                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10532                lsp_store
10533                    .stop_language_servers_for_buffers(
10534                        buffers,
10535                        envelope
10536                            .payload
10537                            .also_servers
10538                            .into_iter()
10539                            .filter_map(|selector| {
10540                                Some(match selector.selector? {
10541                                    proto::language_server_selector::Selector::ServerId(
10542                                        server_id,
10543                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10544                                        server_id,
10545                                    )),
10546                                    proto::language_server_selector::Selector::Name(name) => {
10547                                        LanguageServerSelector::Name(LanguageServerName(
10548                                            SharedString::from(name),
10549                                        ))
10550                                    }
10551                                })
10552                            })
10553                            .collect(),
10554                        cx,
10555                    )
10556                    .detach_and_log_err(cx);
10557            }
10558        });
10559
10560        Ok(proto::Ack {})
10561    }
10562
10563    pub async fn handle_cancel_language_server_work(
10564        lsp_store: Entity<Self>,
10565        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10566        mut cx: AsyncApp,
10567    ) -> Result<proto::Ack> {
10568        lsp_store.update(&mut cx, |lsp_store, cx| {
10569            if let Some(work) = envelope.payload.work {
10570                match work {
10571                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10572                        let buffers =
10573                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10574                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10575                    }
10576                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10577                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10578                        let token = work
10579                            .token
10580                            .map(|token| {
10581                                ProgressToken::from_proto(token)
10582                                    .context("invalid work progress token")
10583                            })
10584                            .transpose()?;
10585                        lsp_store.cancel_language_server_work(server_id, token, cx);
10586                    }
10587                }
10588            }
10589            anyhow::Ok(())
10590        })?;
10591
10592        Ok(proto::Ack {})
10593    }
10594
10595    fn buffer_ids_to_buffers(
10596        &mut self,
10597        buffer_ids: impl Iterator<Item = u64>,
10598        cx: &mut Context<Self>,
10599    ) -> Vec<Entity<Buffer>> {
10600        buffer_ids
10601            .into_iter()
10602            .flat_map(|buffer_id| {
10603                self.buffer_store
10604                    .read(cx)
10605                    .get(BufferId::new(buffer_id).log_err()?)
10606            })
10607            .collect::<Vec<_>>()
10608    }
10609
10610    async fn handle_apply_additional_edits_for_completion(
10611        this: Entity<Self>,
10612        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10613        mut cx: AsyncApp,
10614    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10615        let (buffer, completion, all_commit_ranges) = this.update(&mut cx, |this, cx| {
10616            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10617            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10618            let completion = Self::deserialize_completion(
10619                envelope.payload.completion.context("invalid completion")?,
10620            )?;
10621            let all_commit_ranges = envelope
10622                .payload
10623                .all_commit_ranges
10624                .into_iter()
10625                .map(language::proto::deserialize_anchor_range)
10626                .collect::<Result<Vec<_>, _>>()?;
10627            anyhow::Ok((buffer, completion, all_commit_ranges))
10628        })?;
10629
10630        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10631            this.apply_additional_edits_for_completion(
10632                buffer,
10633                Rc::new(RefCell::new(Box::new([Completion {
10634                    replace_range: completion.replace_range,
10635                    new_text: completion.new_text,
10636                    source: completion.source,
10637                    documentation: None,
10638                    label: CodeLabel::default(),
10639                    match_start: None,
10640                    snippet_deduplication_key: None,
10641                    insert_text_mode: None,
10642                    icon_path: None,
10643                    confirm: None,
10644                }]))),
10645                0,
10646                false,
10647                all_commit_ranges,
10648                cx,
10649            )
10650        });
10651
10652        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10653            transaction: apply_additional_edits
10654                .await?
10655                .as_ref()
10656                .map(language::proto::serialize_transaction),
10657        })
10658    }
10659
10660    pub fn last_formatting_failure(&self) -> Option<&str> {
10661        self.last_formatting_failure.as_deref()
10662    }
10663
10664    pub fn reset_last_formatting_failure(&mut self) {
10665        self.last_formatting_failure = None;
10666    }
10667
10668    pub fn environment_for_buffer(
10669        &self,
10670        buffer: &Entity<Buffer>,
10671        cx: &mut Context<Self>,
10672    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10673        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10674            environment.update(cx, |env, cx| {
10675                env.buffer_environment(buffer, &self.worktree_store, cx)
10676            })
10677        } else {
10678            Task::ready(None).shared()
10679        }
10680    }
10681
10682    pub fn format(
10683        &mut self,
10684        buffers: HashSet<Entity<Buffer>>,
10685        target: LspFormatTarget,
10686        push_to_history: bool,
10687        trigger: FormatTrigger,
10688        cx: &mut Context<Self>,
10689    ) -> Task<anyhow::Result<ProjectTransaction>> {
10690        let logger = zlog::scoped!("format");
10691        if self.as_local().is_some() {
10692            zlog::trace!(logger => "Formatting locally");
10693            let logger = zlog::scoped!(logger => "local");
10694            let buffers = buffers
10695                .into_iter()
10696                .map(|buffer_handle| {
10697                    let buffer = buffer_handle.read(cx);
10698                    let buffer_abs_path = File::from_dyn(buffer.file())
10699                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10700
10701                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10702                })
10703                .collect::<Vec<_>>();
10704
10705            cx.spawn(async move |lsp_store, cx| {
10706                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10707
10708                for (handle, abs_path, id) in buffers {
10709                    let env = lsp_store
10710                        .update(cx, |lsp_store, cx| {
10711                            lsp_store.environment_for_buffer(&handle, cx)
10712                        })?
10713                        .await;
10714
10715                    let ranges = match &target {
10716                        LspFormatTarget::Buffers => None,
10717                        LspFormatTarget::Ranges(ranges) => {
10718                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10719                        }
10720                    };
10721
10722                    formattable_buffers.push(FormattableBuffer {
10723                        handle,
10724                        abs_path,
10725                        env,
10726                        ranges,
10727                    });
10728                }
10729                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10730
10731                let format_timer = zlog::time!(logger => "Formatting buffers");
10732                let result = LocalLspStore::format_locally(
10733                    lsp_store.clone(),
10734                    formattable_buffers,
10735                    push_to_history,
10736                    trigger,
10737                    logger,
10738                    cx,
10739                )
10740                .await;
10741                format_timer.end();
10742
10743                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10744
10745                lsp_store.update(cx, |lsp_store, _| {
10746                    lsp_store.update_last_formatting_failure(&result);
10747                })?;
10748
10749                result
10750            })
10751        } else if let Some((client, project_id)) = self.upstream_client() {
10752            zlog::trace!(logger => "Formatting remotely");
10753            let logger = zlog::scoped!(logger => "remote");
10754
10755            let buffer_ranges = match &target {
10756                LspFormatTarget::Buffers => Vec::new(),
10757                LspFormatTarget::Ranges(ranges) => ranges
10758                    .iter()
10759                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10760                        buffer_id: buffer_id.to_proto(),
10761                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10762                    })
10763                    .collect(),
10764            };
10765
10766            let buffer_store = self.buffer_store();
10767            cx.spawn(async move |lsp_store, cx| {
10768                zlog::trace!(logger => "Sending remote format request");
10769                let request_timer = zlog::time!(logger => "remote format request");
10770                let result = client
10771                    .request(proto::FormatBuffers {
10772                        project_id,
10773                        trigger: trigger as i32,
10774                        buffer_ids: buffers
10775                            .iter()
10776                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10777                            .collect(),
10778                        buffer_ranges,
10779                    })
10780                    .await
10781                    .and_then(|result| result.transaction.context("missing transaction"));
10782                request_timer.end();
10783
10784                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10785
10786                lsp_store.update(cx, |lsp_store, _| {
10787                    lsp_store.update_last_formatting_failure(&result);
10788                })?;
10789
10790                let transaction_response = result?;
10791                let _timer = zlog::time!(logger => "deserializing project transaction");
10792                buffer_store
10793                    .update(cx, |buffer_store, cx| {
10794                        buffer_store.deserialize_project_transaction(
10795                            transaction_response,
10796                            push_to_history,
10797                            cx,
10798                        )
10799                    })
10800                    .await
10801            })
10802        } else {
10803            zlog::trace!(logger => "Not formatting");
10804            Task::ready(Ok(ProjectTransaction::default()))
10805        }
10806    }
10807
10808    async fn handle_format_buffers(
10809        this: Entity<Self>,
10810        envelope: TypedEnvelope<proto::FormatBuffers>,
10811        mut cx: AsyncApp,
10812    ) -> Result<proto::FormatBuffersResponse> {
10813        let sender_id = envelope.original_sender_id().unwrap_or_default();
10814        let format = this.update(&mut cx, |this, cx| {
10815            let mut buffers = HashSet::default();
10816            for buffer_id in &envelope.payload.buffer_ids {
10817                let buffer_id = BufferId::new(*buffer_id)?;
10818                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10819            }
10820
10821            let target = if envelope.payload.buffer_ranges.is_empty() {
10822                LspFormatTarget::Buffers
10823            } else {
10824                let mut ranges_map = BTreeMap::new();
10825                for buffer_range in &envelope.payload.buffer_ranges {
10826                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10827                    let ranges: Result<Vec<_>> = buffer_range
10828                        .ranges
10829                        .iter()
10830                        .map(|range| {
10831                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10832                        })
10833                        .collect();
10834                    ranges_map.insert(buffer_id, ranges?);
10835                }
10836                LspFormatTarget::Ranges(ranges_map)
10837            };
10838
10839            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10840            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10841        })?;
10842
10843        let project_transaction = format.await?;
10844        let project_transaction = this.update(&mut cx, |this, cx| {
10845            this.buffer_store.update(cx, |buffer_store, cx| {
10846                buffer_store.serialize_project_transaction_for_peer(
10847                    project_transaction,
10848                    sender_id,
10849                    cx,
10850                )
10851            })
10852        });
10853        Ok(proto::FormatBuffersResponse {
10854            transaction: Some(project_transaction),
10855        })
10856    }
10857
10858    async fn handle_apply_code_action_kind(
10859        this: Entity<Self>,
10860        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10861        mut cx: AsyncApp,
10862    ) -> Result<proto::ApplyCodeActionKindResponse> {
10863        let sender_id = envelope.original_sender_id().unwrap_or_default();
10864        let format = this.update(&mut cx, |this, cx| {
10865            let mut buffers = HashSet::default();
10866            for buffer_id in &envelope.payload.buffer_ids {
10867                let buffer_id = BufferId::new(*buffer_id)?;
10868                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10869            }
10870            let kind = match envelope.payload.kind.as_str() {
10871                "" => CodeActionKind::EMPTY,
10872                "quickfix" => CodeActionKind::QUICKFIX,
10873                "refactor" => CodeActionKind::REFACTOR,
10874                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10875                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10876                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10877                "source" => CodeActionKind::SOURCE,
10878                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10879                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10880                _ => anyhow::bail!(
10881                    "Invalid code action kind {}",
10882                    envelope.payload.kind.as_str()
10883                ),
10884            };
10885            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10886        })?;
10887
10888        let project_transaction = format.await?;
10889        let project_transaction = this.update(&mut cx, |this, cx| {
10890            this.buffer_store.update(cx, |buffer_store, cx| {
10891                buffer_store.serialize_project_transaction_for_peer(
10892                    project_transaction,
10893                    sender_id,
10894                    cx,
10895                )
10896            })
10897        });
10898        Ok(proto::ApplyCodeActionKindResponse {
10899            transaction: Some(project_transaction),
10900        })
10901    }
10902
10903    async fn shutdown_language_server(
10904        server_state: Option<LanguageServerState>,
10905        name: LanguageServerName,
10906        cx: &mut AsyncApp,
10907    ) {
10908        let server = match server_state {
10909            Some(LanguageServerState::Starting { startup, .. }) => {
10910                let mut timer = cx
10911                    .background_executor()
10912                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10913                    .fuse();
10914
10915                select! {
10916                    server = startup.fuse() => server,
10917                    () = timer => {
10918                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10919                        None
10920                    },
10921                }
10922            }
10923
10924            Some(LanguageServerState::Running { server, .. }) => Some(server),
10925
10926            None => None,
10927        };
10928
10929        let Some(server) = server else { return };
10930        if let Some(shutdown) = server.shutdown() {
10931            shutdown.await;
10932        }
10933    }
10934
10935    // Returns a list of all of the worktrees which no longer have a language server and the root path
10936    // for the stopped server
10937    fn stop_local_language_server(
10938        &mut self,
10939        server_id: LanguageServerId,
10940        cx: &mut Context<Self>,
10941    ) -> Task<()> {
10942        let local = match &mut self.mode {
10943            LspStoreMode::Local(local) => local,
10944            _ => {
10945                return Task::ready(());
10946            }
10947        };
10948
10949        // Remove this server ID from all entries in the given worktree.
10950        local
10951            .language_server_ids
10952            .retain(|_, state| state.id != server_id);
10953        self.buffer_store.update(cx, |buffer_store, cx| {
10954            for buffer in buffer_store.buffers() {
10955                buffer.update(cx, |buffer, cx| {
10956                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10957                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10958                });
10959            }
10960        });
10961
10962        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
10963        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10964            summaries.retain(|path, summaries_by_server_id| {
10965                if summaries_by_server_id.remove(&server_id).is_some() {
10966                    if let Some((client, project_id)) = self.downstream_client.clone() {
10967                        client
10968                            .send(proto::UpdateDiagnosticSummary {
10969                                project_id,
10970                                worktree_id: worktree_id.to_proto(),
10971                                summary: Some(proto::DiagnosticSummary {
10972                                    path: path.as_ref().to_proto(),
10973                                    language_server_id: server_id.0 as u64,
10974                                    error_count: 0,
10975                                    warning_count: 0,
10976                                }),
10977                                more_summaries: Vec::new(),
10978                            })
10979                            .log_err();
10980                    }
10981                    cleared_paths.push(ProjectPath {
10982                        worktree_id: *worktree_id,
10983                        path: path.clone(),
10984                    });
10985                    !summaries_by_server_id.is_empty()
10986                } else {
10987                    true
10988                }
10989            });
10990        }
10991        if !cleared_paths.is_empty() {
10992            cx.emit(LspStoreEvent::DiagnosticsUpdated {
10993                server_id,
10994                paths: cleared_paths,
10995            });
10996        }
10997
10998        let local = self.as_local_mut().unwrap();
10999        for diagnostics in local.diagnostics.values_mut() {
11000            diagnostics.retain(|_, diagnostics_by_server_id| {
11001                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
11002                    diagnostics_by_server_id.remove(ix);
11003                    !diagnostics_by_server_id.is_empty()
11004                } else {
11005                    true
11006                }
11007            });
11008        }
11009        local.language_server_watched_paths.remove(&server_id);
11010
11011        let server_state = local.language_servers.remove(&server_id);
11012        self.cleanup_lsp_data(server_id);
11013        let name = self
11014            .language_server_statuses
11015            .remove(&server_id)
11016            .map(|status| status.name)
11017            .or_else(|| {
11018                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
11019                    Some(adapter.name())
11020                } else {
11021                    None
11022                }
11023            });
11024
11025        if let Some(name) = name {
11026            log::info!("stopping language server {name}");
11027            self.languages
11028                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
11029            cx.notify();
11030
11031            return cx.spawn(async move |lsp_store, cx| {
11032                Self::shutdown_language_server(server_state, name.clone(), cx).await;
11033                lsp_store
11034                    .update(cx, |lsp_store, cx| {
11035                        lsp_store
11036                            .languages
11037                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
11038                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11039                        cx.notify();
11040                    })
11041                    .ok();
11042            });
11043        }
11044
11045        if server_state.is_some() {
11046            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11047        }
11048        Task::ready(())
11049    }
11050
11051    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
11052        self.shutdown_all_language_servers(cx).detach();
11053    }
11054
11055    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
11056        if let Some((client, project_id)) = self.upstream_client() {
11057            let request = client.request(proto::StopLanguageServers {
11058                project_id,
11059                buffer_ids: Vec::new(),
11060                also_servers: Vec::new(),
11061                all: true,
11062            });
11063            cx.background_spawn(async move {
11064                request.await.ok();
11065            })
11066        } else {
11067            let Some(local) = self.as_local_mut() else {
11068                return Task::ready(());
11069            };
11070            let language_servers_to_stop = local
11071                .language_server_ids
11072                .values()
11073                .map(|state| state.id)
11074                .collect();
11075            local.lsp_tree.remove_nodes(&language_servers_to_stop);
11076            let tasks = language_servers_to_stop
11077                .into_iter()
11078                .map(|server| self.stop_local_language_server(server, cx))
11079                .collect::<Vec<_>>();
11080            cx.background_spawn(async move {
11081                futures::future::join_all(tasks).await;
11082            })
11083        }
11084    }
11085
11086    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
11087        let buffers = self.buffer_store.read(cx).buffers().collect();
11088        self.restart_language_servers_for_buffers(buffers, HashSet::default(), cx);
11089    }
11090
11091    pub fn restart_language_servers_for_buffers(
11092        &mut self,
11093        buffers: Vec<Entity<Buffer>>,
11094        only_restart_servers: HashSet<LanguageServerSelector>,
11095        cx: &mut Context<Self>,
11096    ) {
11097        if let Some((client, project_id)) = self.upstream_client() {
11098            let request = client.request(proto::RestartLanguageServers {
11099                project_id,
11100                buffer_ids: buffers
11101                    .into_iter()
11102                    .map(|b| b.read(cx).remote_id().to_proto())
11103                    .collect(),
11104                only_servers: only_restart_servers
11105                    .into_iter()
11106                    .map(|selector| {
11107                        let selector = match selector {
11108                            LanguageServerSelector::Id(language_server_id) => {
11109                                proto::language_server_selector::Selector::ServerId(
11110                                    language_server_id.to_proto(),
11111                                )
11112                            }
11113                            LanguageServerSelector::Name(language_server_name) => {
11114                                proto::language_server_selector::Selector::Name(
11115                                    language_server_name.to_string(),
11116                                )
11117                            }
11118                        };
11119                        proto::LanguageServerSelector {
11120                            selector: Some(selector),
11121                        }
11122                    })
11123                    .collect(),
11124                all: false,
11125            });
11126            cx.background_spawn(request).detach_and_log_err(cx);
11127        } else {
11128            let stop_task = if only_restart_servers.is_empty() {
11129                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11130            } else {
11131                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11132            };
11133            cx.spawn(async move |lsp_store, cx| {
11134                stop_task.await;
11135                lsp_store.update(cx, |lsp_store, cx| {
11136                    for buffer in buffers {
11137                        lsp_store.register_buffer_with_language_servers(
11138                            &buffer,
11139                            only_restart_servers.clone(),
11140                            true,
11141                            cx,
11142                        );
11143                    }
11144                })
11145            })
11146            .detach();
11147        }
11148    }
11149
11150    pub fn stop_language_servers_for_buffers(
11151        &mut self,
11152        buffers: Vec<Entity<Buffer>>,
11153        also_stop_servers: HashSet<LanguageServerSelector>,
11154        cx: &mut Context<Self>,
11155    ) -> Task<Result<()>> {
11156        if let Some((client, project_id)) = self.upstream_client() {
11157            let request = client.request(proto::StopLanguageServers {
11158                project_id,
11159                buffer_ids: buffers
11160                    .into_iter()
11161                    .map(|b| b.read(cx).remote_id().to_proto())
11162                    .collect(),
11163                also_servers: also_stop_servers
11164                    .into_iter()
11165                    .map(|selector| {
11166                        let selector = match selector {
11167                            LanguageServerSelector::Id(language_server_id) => {
11168                                proto::language_server_selector::Selector::ServerId(
11169                                    language_server_id.to_proto(),
11170                                )
11171                            }
11172                            LanguageServerSelector::Name(language_server_name) => {
11173                                proto::language_server_selector::Selector::Name(
11174                                    language_server_name.to_string(),
11175                                )
11176                            }
11177                        };
11178                        proto::LanguageServerSelector {
11179                            selector: Some(selector),
11180                        }
11181                    })
11182                    .collect(),
11183                all: false,
11184            });
11185            cx.background_spawn(async move {
11186                let _ = request.await?;
11187                Ok(())
11188            })
11189        } else {
11190            let task =
11191                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11192            cx.background_spawn(async move {
11193                task.await;
11194                Ok(())
11195            })
11196        }
11197    }
11198
11199    fn stop_local_language_servers_for_buffers(
11200        &mut self,
11201        buffers: &[Entity<Buffer>],
11202        also_stop_servers: HashSet<LanguageServerSelector>,
11203        cx: &mut Context<Self>,
11204    ) -> Task<()> {
11205        let Some(local) = self.as_local_mut() else {
11206            return Task::ready(());
11207        };
11208        let mut language_server_names_to_stop = BTreeSet::default();
11209        let mut language_servers_to_stop = also_stop_servers
11210            .into_iter()
11211            .flat_map(|selector| match selector {
11212                LanguageServerSelector::Id(id) => Some(id),
11213                LanguageServerSelector::Name(name) => {
11214                    language_server_names_to_stop.insert(name);
11215                    None
11216                }
11217            })
11218            .collect::<BTreeSet<_>>();
11219
11220        let mut covered_worktrees = HashSet::default();
11221        for buffer in buffers {
11222            buffer.update(cx, |buffer, cx| {
11223                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11224                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11225                    && covered_worktrees.insert(worktree_id)
11226                {
11227                    language_server_names_to_stop.retain(|name| {
11228                        let old_ids_count = language_servers_to_stop.len();
11229                        let all_language_servers_with_this_name = local
11230                            .language_server_ids
11231                            .iter()
11232                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11233                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11234                        old_ids_count == language_servers_to_stop.len()
11235                    });
11236                }
11237            });
11238        }
11239        for name in language_server_names_to_stop {
11240            language_servers_to_stop.extend(
11241                local
11242                    .language_server_ids
11243                    .iter()
11244                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11245            );
11246        }
11247
11248        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11249        let tasks = language_servers_to_stop
11250            .into_iter()
11251            .map(|server| self.stop_local_language_server(server, cx))
11252            .collect::<Vec<_>>();
11253
11254        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11255    }
11256
11257    #[cfg(any(test, feature = "test-support"))]
11258    pub fn update_diagnostics(
11259        &mut self,
11260        server_id: LanguageServerId,
11261        diagnostics: lsp::PublishDiagnosticsParams,
11262        result_id: Option<SharedString>,
11263        source_kind: DiagnosticSourceKind,
11264        disk_based_sources: &[String],
11265        cx: &mut Context<Self>,
11266    ) -> Result<()> {
11267        self.merge_lsp_diagnostics(
11268            source_kind,
11269            vec![DocumentDiagnosticsUpdate {
11270                diagnostics,
11271                result_id,
11272                server_id,
11273                disk_based_sources: Cow::Borrowed(disk_based_sources),
11274                registration_id: None,
11275            }],
11276            |_, _, _| false,
11277            cx,
11278        )
11279    }
11280
11281    pub fn merge_lsp_diagnostics(
11282        &mut self,
11283        source_kind: DiagnosticSourceKind,
11284        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11285        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11286        cx: &mut Context<Self>,
11287    ) -> Result<()> {
11288        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11289        let updates = lsp_diagnostics
11290            .into_iter()
11291            .filter_map(|update| {
11292                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11293                Some(DocumentDiagnosticsUpdate {
11294                    diagnostics: self.lsp_to_document_diagnostics(
11295                        abs_path,
11296                        source_kind,
11297                        update.server_id,
11298                        update.diagnostics,
11299                        &update.disk_based_sources,
11300                        update.registration_id.clone(),
11301                    ),
11302                    result_id: update.result_id,
11303                    server_id: update.server_id,
11304                    disk_based_sources: update.disk_based_sources,
11305                    registration_id: update.registration_id,
11306                })
11307            })
11308            .collect();
11309        self.merge_diagnostic_entries(updates, merge, cx)?;
11310        Ok(())
11311    }
11312
11313    fn lsp_to_document_diagnostics(
11314        &mut self,
11315        document_abs_path: PathBuf,
11316        source_kind: DiagnosticSourceKind,
11317        server_id: LanguageServerId,
11318        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11319        disk_based_sources: &[String],
11320        registration_id: Option<SharedString>,
11321    ) -> DocumentDiagnostics {
11322        let mut diagnostics = Vec::default();
11323        let mut primary_diagnostic_group_ids = HashMap::default();
11324        let mut sources_by_group_id = HashMap::default();
11325        let mut supporting_diagnostics = HashMap::default();
11326
11327        let adapter = self.language_server_adapter_for_id(server_id);
11328
11329        // Ensure that primary diagnostics are always the most severe
11330        lsp_diagnostics
11331            .diagnostics
11332            .sort_by_key(|item| item.severity);
11333
11334        for diagnostic in &lsp_diagnostics.diagnostics {
11335            let source = diagnostic.source.as_ref();
11336            let range = range_from_lsp(diagnostic.range);
11337            let is_supporting = diagnostic
11338                .related_information
11339                .as_ref()
11340                .is_some_and(|infos| {
11341                    infos.iter().any(|info| {
11342                        primary_diagnostic_group_ids.contains_key(&(
11343                            source,
11344                            diagnostic.code.clone(),
11345                            range_from_lsp(info.location.range),
11346                        ))
11347                    })
11348                });
11349
11350            let is_unnecessary = diagnostic
11351                .tags
11352                .as_ref()
11353                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11354
11355            let underline = self
11356                .language_server_adapter_for_id(server_id)
11357                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11358
11359            if is_supporting {
11360                supporting_diagnostics.insert(
11361                    (source, diagnostic.code.clone(), range),
11362                    (diagnostic.severity, is_unnecessary),
11363                );
11364            } else {
11365                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11366                let is_disk_based =
11367                    source.is_some_and(|source| disk_based_sources.contains(source));
11368
11369                sources_by_group_id.insert(group_id, source);
11370                primary_diagnostic_group_ids
11371                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11372
11373                diagnostics.push(DiagnosticEntry {
11374                    range,
11375                    diagnostic: Diagnostic {
11376                        source: diagnostic.source.clone(),
11377                        source_kind,
11378                        code: diagnostic.code.clone(),
11379                        code_description: diagnostic
11380                            .code_description
11381                            .as_ref()
11382                            .and_then(|d| d.href.clone()),
11383                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11384                        markdown: adapter.as_ref().and_then(|adapter| {
11385                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11386                        }),
11387                        message: diagnostic.message.trim().to_string(),
11388                        group_id,
11389                        is_primary: true,
11390                        is_disk_based,
11391                        is_unnecessary,
11392                        underline,
11393                        data: diagnostic.data.clone(),
11394                        registration_id: registration_id.clone(),
11395                    },
11396                });
11397                if let Some(infos) = &diagnostic.related_information {
11398                    for info in infos {
11399                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11400                            let range = range_from_lsp(info.location.range);
11401                            diagnostics.push(DiagnosticEntry {
11402                                range,
11403                                diagnostic: Diagnostic {
11404                                    source: diagnostic.source.clone(),
11405                                    source_kind,
11406                                    code: diagnostic.code.clone(),
11407                                    code_description: diagnostic
11408                                        .code_description
11409                                        .as_ref()
11410                                        .and_then(|d| d.href.clone()),
11411                                    severity: DiagnosticSeverity::INFORMATION,
11412                                    markdown: adapter.as_ref().and_then(|adapter| {
11413                                        adapter.diagnostic_message_to_markdown(&info.message)
11414                                    }),
11415                                    message: info.message.trim().to_string(),
11416                                    group_id,
11417                                    is_primary: false,
11418                                    is_disk_based,
11419                                    is_unnecessary: false,
11420                                    underline,
11421                                    data: diagnostic.data.clone(),
11422                                    registration_id: registration_id.clone(),
11423                                },
11424                            });
11425                        }
11426                    }
11427                }
11428            }
11429        }
11430
11431        for entry in &mut diagnostics {
11432            let diagnostic = &mut entry.diagnostic;
11433            if !diagnostic.is_primary {
11434                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11435                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11436                    source,
11437                    diagnostic.code.clone(),
11438                    entry.range.clone(),
11439                )) {
11440                    if let Some(severity) = severity {
11441                        diagnostic.severity = severity;
11442                    }
11443                    diagnostic.is_unnecessary = is_unnecessary;
11444                }
11445            }
11446        }
11447
11448        DocumentDiagnostics {
11449            diagnostics,
11450            document_abs_path,
11451            version: lsp_diagnostics.version,
11452        }
11453    }
11454
11455    fn insert_newly_running_language_server(
11456        &mut self,
11457        adapter: Arc<CachedLspAdapter>,
11458        language_server: Arc<LanguageServer>,
11459        server_id: LanguageServerId,
11460        key: LanguageServerSeed,
11461        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11462        cx: &mut Context<Self>,
11463    ) {
11464        let Some(local) = self.as_local_mut() else {
11465            return;
11466        };
11467        // If the language server for this key doesn't match the server id, don't store the
11468        // server. Which will cause it to be dropped, killing the process
11469        if local
11470            .language_server_ids
11471            .get(&key)
11472            .map(|state| state.id != server_id)
11473            .unwrap_or(false)
11474        {
11475            return;
11476        }
11477
11478        // Update language_servers collection with Running variant of LanguageServerState
11479        // indicating that the server is up and running and ready
11480        let workspace_folders = workspace_folders.lock().clone();
11481        language_server.set_workspace_folders(workspace_folders);
11482
11483        let workspace_diagnostics_refresh_tasks = language_server
11484            .capabilities()
11485            .diagnostic_provider
11486            .and_then(|provider| {
11487                local
11488                    .language_server_dynamic_registrations
11489                    .entry(server_id)
11490                    .or_default()
11491                    .diagnostics
11492                    .entry(None)
11493                    .or_insert(provider.clone());
11494                let workspace_refresher =
11495                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11496
11497                Some((None, workspace_refresher))
11498            })
11499            .into_iter()
11500            .collect();
11501        local.language_servers.insert(
11502            server_id,
11503            LanguageServerState::Running {
11504                workspace_diagnostics_refresh_tasks,
11505                adapter: adapter.clone(),
11506                server: language_server.clone(),
11507                simulate_disk_based_diagnostics_completion: None,
11508            },
11509        );
11510        local
11511            .languages
11512            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11513        if let Some(file_ops_caps) = language_server
11514            .capabilities()
11515            .workspace
11516            .as_ref()
11517            .and_then(|ws| ws.file_operations.as_ref())
11518        {
11519            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11520            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11521            if did_rename_caps.or(will_rename_caps).is_some() {
11522                let watcher = RenamePathsWatchedForServer::default()
11523                    .with_did_rename_patterns(did_rename_caps)
11524                    .with_will_rename_patterns(will_rename_caps);
11525                local
11526                    .language_server_paths_watched_for_rename
11527                    .insert(server_id, watcher);
11528            }
11529        }
11530
11531        self.language_server_statuses.insert(
11532            server_id,
11533            LanguageServerStatus {
11534                name: language_server.name(),
11535                server_version: language_server.version(),
11536                server_readable_version: language_server.readable_version(),
11537                pending_work: Default::default(),
11538                has_pending_diagnostic_updates: false,
11539                progress_tokens: Default::default(),
11540                worktree: Some(key.worktree_id),
11541                binary: Some(language_server.binary().clone()),
11542                configuration: Some(language_server.configuration().clone()),
11543                workspace_folders: language_server.workspace_folders(),
11544                process_id: language_server.process_id(),
11545            },
11546        );
11547
11548        cx.emit(LspStoreEvent::LanguageServerAdded(
11549            server_id,
11550            language_server.name(),
11551            Some(key.worktree_id),
11552        ));
11553
11554        let server_capabilities = language_server.capabilities();
11555        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11556            downstream_client
11557                .send(proto::StartLanguageServer {
11558                    project_id: *project_id,
11559                    server: Some(proto::LanguageServer {
11560                        id: server_id.to_proto(),
11561                        name: language_server.name().to_string(),
11562                        worktree_id: Some(key.worktree_id.to_proto()),
11563                    }),
11564                    capabilities: serde_json::to_string(&server_capabilities)
11565                        .expect("serializing server LSP capabilities"),
11566                })
11567                .log_err();
11568        }
11569        self.lsp_server_capabilities
11570            .insert(server_id, server_capabilities);
11571
11572        // Tell the language server about every open buffer in the worktree that matches the language.
11573        // Also check for buffers in worktrees that reused this server
11574        let mut worktrees_using_server = vec![key.worktree_id];
11575        if let Some(local) = self.as_local() {
11576            // Find all worktrees that have this server in their language server tree
11577            for (worktree_id, servers) in &local.lsp_tree.instances {
11578                if *worktree_id != key.worktree_id {
11579                    for server_map in servers.roots.values() {
11580                        if server_map
11581                            .values()
11582                            .any(|(node, _)| node.id() == Some(server_id))
11583                        {
11584                            worktrees_using_server.push(*worktree_id);
11585                        }
11586                    }
11587                }
11588            }
11589        }
11590
11591        let mut buffer_paths_registered = Vec::new();
11592        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11593            let mut lsp_adapters = HashMap::default();
11594            for buffer_handle in buffer_store.buffers() {
11595                let buffer = buffer_handle.read(cx);
11596                let file = match File::from_dyn(buffer.file()) {
11597                    Some(file) => file,
11598                    None => continue,
11599                };
11600                let language = match buffer.language() {
11601                    Some(language) => language,
11602                    None => continue,
11603                };
11604
11605                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11606                    || !lsp_adapters
11607                        .entry(language.name())
11608                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11609                        .iter()
11610                        .any(|a| a.name == key.name)
11611                {
11612                    continue;
11613                }
11614                // didOpen
11615                let file = match file.as_local() {
11616                    Some(file) => file,
11617                    None => continue,
11618                };
11619
11620                let local = self.as_local_mut().unwrap();
11621
11622                let buffer_id = buffer.remote_id();
11623                if local.registered_buffers.contains_key(&buffer_id) {
11624                    let abs_path = file.abs_path(cx);
11625                    let uri = match lsp::Uri::from_file_path(&abs_path) {
11626                        Ok(uri) => uri,
11627                        Err(()) => {
11628                            log::error!("failed to convert path to URI: {:?}", abs_path);
11629                            continue;
11630                        }
11631                    };
11632
11633                    let versions = local
11634                        .buffer_snapshots
11635                        .entry(buffer_id)
11636                        .or_default()
11637                        .entry(server_id)
11638                        .and_modify(|_| {
11639                            assert!(
11640                            false,
11641                            "There should not be an existing snapshot for a newly inserted buffer"
11642                        )
11643                        })
11644                        .or_insert_with(|| {
11645                            vec![LspBufferSnapshot {
11646                                version: 0,
11647                                snapshot: buffer.text_snapshot(),
11648                            }]
11649                        });
11650
11651                    let snapshot = versions.last().unwrap();
11652                    let version = snapshot.version;
11653                    let initial_snapshot = &snapshot.snapshot;
11654                    language_server.register_buffer(
11655                        uri,
11656                        adapter.language_id(&language.name()),
11657                        version,
11658                        initial_snapshot.text(),
11659                    );
11660                    buffer_paths_registered.push((buffer_id, abs_path));
11661                    local
11662                        .buffers_opened_in_servers
11663                        .entry(buffer_id)
11664                        .or_default()
11665                        .insert(server_id);
11666                }
11667                buffer_handle.update(cx, |buffer, cx| {
11668                    buffer.set_completion_triggers(
11669                        server_id,
11670                        language_server
11671                            .capabilities()
11672                            .completion_provider
11673                            .as_ref()
11674                            .and_then(|provider| {
11675                                provider
11676                                    .trigger_characters
11677                                    .as_ref()
11678                                    .map(|characters| characters.iter().cloned().collect())
11679                            })
11680                            .unwrap_or_default(),
11681                        cx,
11682                    )
11683                });
11684            }
11685        });
11686
11687        for (buffer_id, abs_path) in buffer_paths_registered {
11688            cx.emit(LspStoreEvent::LanguageServerUpdate {
11689                language_server_id: server_id,
11690                name: Some(adapter.name()),
11691                message: proto::update_language_server::Variant::RegisteredForBuffer(
11692                    proto::RegisteredForBuffer {
11693                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11694                        buffer_id: buffer_id.to_proto(),
11695                    },
11696                ),
11697            });
11698        }
11699
11700        cx.notify();
11701    }
11702
11703    pub fn language_servers_running_disk_based_diagnostics(
11704        &self,
11705    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11706        self.language_server_statuses
11707            .iter()
11708            .filter_map(|(id, status)| {
11709                if status.has_pending_diagnostic_updates {
11710                    Some(*id)
11711                } else {
11712                    None
11713                }
11714            })
11715    }
11716
11717    pub(crate) fn cancel_language_server_work_for_buffers(
11718        &mut self,
11719        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11720        cx: &mut Context<Self>,
11721    ) {
11722        if let Some((client, project_id)) = self.upstream_client() {
11723            let request = client.request(proto::CancelLanguageServerWork {
11724                project_id,
11725                work: Some(proto::cancel_language_server_work::Work::Buffers(
11726                    proto::cancel_language_server_work::Buffers {
11727                        buffer_ids: buffers
11728                            .into_iter()
11729                            .map(|b| b.read(cx).remote_id().to_proto())
11730                            .collect(),
11731                    },
11732                )),
11733            });
11734            cx.background_spawn(request).detach_and_log_err(cx);
11735        } else if let Some(local) = self.as_local() {
11736            let servers = buffers
11737                .into_iter()
11738                .flat_map(|buffer| {
11739                    buffer.update(cx, |buffer, cx| {
11740                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11741                    })
11742                })
11743                .collect::<HashSet<_>>();
11744            for server_id in servers {
11745                self.cancel_language_server_work(server_id, None, cx);
11746            }
11747        }
11748    }
11749
11750    pub(crate) fn cancel_language_server_work(
11751        &mut self,
11752        server_id: LanguageServerId,
11753        token_to_cancel: Option<ProgressToken>,
11754        cx: &mut Context<Self>,
11755    ) {
11756        if let Some(local) = self.as_local() {
11757            let status = self.language_server_statuses.get(&server_id);
11758            let server = local.language_servers.get(&server_id);
11759            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11760            {
11761                for (token, progress) in &status.pending_work {
11762                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11763                        && token != token_to_cancel
11764                    {
11765                        continue;
11766                    }
11767                    if progress.is_cancellable {
11768                        server
11769                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11770                                WorkDoneProgressCancelParams {
11771                                    token: token.to_lsp(),
11772                                },
11773                            )
11774                            .ok();
11775                    }
11776                }
11777            }
11778        } else if let Some((client, project_id)) = self.upstream_client() {
11779            let request = client.request(proto::CancelLanguageServerWork {
11780                project_id,
11781                work: Some(
11782                    proto::cancel_language_server_work::Work::LanguageServerWork(
11783                        proto::cancel_language_server_work::LanguageServerWork {
11784                            language_server_id: server_id.to_proto(),
11785                            token: token_to_cancel.map(|token| token.to_proto()),
11786                        },
11787                    ),
11788                ),
11789            });
11790            cx.background_spawn(request).detach_and_log_err(cx);
11791        }
11792    }
11793
11794    fn register_supplementary_language_server(
11795        &mut self,
11796        id: LanguageServerId,
11797        name: LanguageServerName,
11798        server: Arc<LanguageServer>,
11799        cx: &mut Context<Self>,
11800    ) {
11801        if let Some(local) = self.as_local_mut() {
11802            local
11803                .supplementary_language_servers
11804                .insert(id, (name.clone(), server));
11805            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11806        }
11807    }
11808
11809    fn unregister_supplementary_language_server(
11810        &mut self,
11811        id: LanguageServerId,
11812        cx: &mut Context<Self>,
11813    ) {
11814        if let Some(local) = self.as_local_mut() {
11815            local.supplementary_language_servers.remove(&id);
11816            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11817        }
11818    }
11819
11820    pub(crate) fn supplementary_language_servers(
11821        &self,
11822    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11823        self.as_local().into_iter().flat_map(|local| {
11824            local
11825                .supplementary_language_servers
11826                .iter()
11827                .map(|(id, (name, _))| (*id, name.clone()))
11828        })
11829    }
11830
11831    pub fn language_server_adapter_for_id(
11832        &self,
11833        id: LanguageServerId,
11834    ) -> Option<Arc<CachedLspAdapter>> {
11835        self.as_local()
11836            .and_then(|local| local.language_servers.get(&id))
11837            .and_then(|language_server_state| match language_server_state {
11838                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11839                _ => None,
11840            })
11841    }
11842
11843    pub(super) fn update_local_worktree_language_servers(
11844        &mut self,
11845        worktree_handle: &Entity<Worktree>,
11846        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11847        cx: &mut Context<Self>,
11848    ) {
11849        if changes.is_empty() {
11850            return;
11851        }
11852
11853        let Some(local) = self.as_local() else { return };
11854
11855        local.prettier_store.update(cx, |prettier_store, cx| {
11856            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11857        });
11858
11859        let worktree_id = worktree_handle.read(cx).id();
11860        let mut language_server_ids = local
11861            .language_server_ids
11862            .iter()
11863            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11864            .collect::<Vec<_>>();
11865        language_server_ids.sort();
11866        language_server_ids.dedup();
11867
11868        // let abs_path = worktree_handle.read(cx).abs_path();
11869        for server_id in &language_server_ids {
11870            if let Some(LanguageServerState::Running { server, .. }) =
11871                local.language_servers.get(server_id)
11872                && let Some(watched_paths) = local
11873                    .language_server_watched_paths
11874                    .get(server_id)
11875                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11876            {
11877                let params = lsp::DidChangeWatchedFilesParams {
11878                    changes: changes
11879                        .iter()
11880                        .filter_map(|(path, _, change)| {
11881                            if !watched_paths.is_match(path.as_std_path()) {
11882                                return None;
11883                            }
11884                            let typ = match change {
11885                                PathChange::Loaded => return None,
11886                                PathChange::Added => lsp::FileChangeType::CREATED,
11887                                PathChange::Removed => lsp::FileChangeType::DELETED,
11888                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11889                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11890                            };
11891                            let uri = lsp::Uri::from_file_path(
11892                                worktree_handle.read(cx).absolutize(&path),
11893                            )
11894                            .ok()?;
11895                            Some(lsp::FileEvent { uri, typ })
11896                        })
11897                        .collect(),
11898                };
11899                if !params.changes.is_empty() {
11900                    server
11901                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11902                        .ok();
11903                }
11904            }
11905        }
11906        for (path, _, _) in changes {
11907            if let Some(file_name) = path.file_name()
11908                && local.watched_manifest_filenames.contains(file_name)
11909            {
11910                self.request_workspace_config_refresh();
11911                break;
11912            }
11913        }
11914    }
11915
11916    pub fn wait_for_remote_buffer(
11917        &mut self,
11918        id: BufferId,
11919        cx: &mut Context<Self>,
11920    ) -> Task<Result<Entity<Buffer>>> {
11921        self.buffer_store.update(cx, |buffer_store, cx| {
11922            buffer_store.wait_for_remote_buffer(id, cx)
11923        })
11924    }
11925
11926    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11927        let mut result = proto::Symbol {
11928            language_server_name: symbol.language_server_name.0.to_string(),
11929            source_worktree_id: symbol.source_worktree_id.to_proto(),
11930            language_server_id: symbol.source_language_server_id.to_proto(),
11931            name: symbol.name.clone(),
11932            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11933            start: Some(proto::PointUtf16 {
11934                row: symbol.range.start.0.row,
11935                column: symbol.range.start.0.column,
11936            }),
11937            end: Some(proto::PointUtf16 {
11938                row: symbol.range.end.0.row,
11939                column: symbol.range.end.0.column,
11940            }),
11941            worktree_id: Default::default(),
11942            path: Default::default(),
11943            signature: Default::default(),
11944            container_name: symbol.container_name.clone(),
11945        };
11946        match &symbol.path {
11947            SymbolLocation::InProject(path) => {
11948                result.worktree_id = path.worktree_id.to_proto();
11949                result.path = path.path.to_proto();
11950            }
11951            SymbolLocation::OutsideProject {
11952                abs_path,
11953                signature,
11954            } => {
11955                result.path = abs_path.to_string_lossy().into_owned();
11956                result.signature = signature.to_vec();
11957            }
11958        }
11959        result
11960    }
11961
11962    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11963        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11964        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11965        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11966
11967        let path = if serialized_symbol.signature.is_empty() {
11968            SymbolLocation::InProject(ProjectPath {
11969                worktree_id,
11970                path: RelPath::from_proto(&serialized_symbol.path)
11971                    .context("invalid symbol path")?,
11972            })
11973        } else {
11974            SymbolLocation::OutsideProject {
11975                abs_path: Path::new(&serialized_symbol.path).into(),
11976                signature: serialized_symbol
11977                    .signature
11978                    .try_into()
11979                    .map_err(|_| anyhow!("invalid signature"))?,
11980            }
11981        };
11982
11983        let start = serialized_symbol.start.context("invalid start")?;
11984        let end = serialized_symbol.end.context("invalid end")?;
11985        Ok(CoreSymbol {
11986            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11987            source_worktree_id,
11988            source_language_server_id: LanguageServerId::from_proto(
11989                serialized_symbol.language_server_id,
11990            ),
11991            path,
11992            name: serialized_symbol.name,
11993            range: Unclipped(PointUtf16::new(start.row, start.column))
11994                ..Unclipped(PointUtf16::new(end.row, end.column)),
11995            kind,
11996            container_name: serialized_symbol.container_name,
11997        })
11998    }
11999
12000    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
12001        let mut serialized_completion = proto::Completion {
12002            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
12003            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
12004            new_text: completion.new_text.clone(),
12005            ..proto::Completion::default()
12006        };
12007        match &completion.source {
12008            CompletionSource::Lsp {
12009                insert_range,
12010                server_id,
12011                lsp_completion,
12012                lsp_defaults,
12013                resolved,
12014            } => {
12015                let (old_insert_start, old_insert_end) = insert_range
12016                    .as_ref()
12017                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
12018                    .unzip();
12019
12020                serialized_completion.old_insert_start = old_insert_start;
12021                serialized_completion.old_insert_end = old_insert_end;
12022                serialized_completion.source = proto::completion::Source::Lsp as i32;
12023                serialized_completion.server_id = server_id.0 as u64;
12024                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
12025                serialized_completion.lsp_defaults = lsp_defaults
12026                    .as_deref()
12027                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
12028                serialized_completion.resolved = *resolved;
12029            }
12030            CompletionSource::BufferWord {
12031                word_range,
12032                resolved,
12033            } => {
12034                serialized_completion.source = proto::completion::Source::BufferWord as i32;
12035                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
12036                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
12037                serialized_completion.resolved = *resolved;
12038            }
12039            CompletionSource::Custom => {
12040                serialized_completion.source = proto::completion::Source::Custom as i32;
12041                serialized_completion.resolved = true;
12042            }
12043            CompletionSource::Dap { sort_text } => {
12044                serialized_completion.source = proto::completion::Source::Dap as i32;
12045                serialized_completion.sort_text = Some(sort_text.clone());
12046            }
12047        }
12048
12049        serialized_completion
12050    }
12051
12052    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
12053        let old_replace_start = completion
12054            .old_replace_start
12055            .and_then(deserialize_anchor)
12056            .context("invalid old start")?;
12057        let old_replace_end = completion
12058            .old_replace_end
12059            .and_then(deserialize_anchor)
12060            .context("invalid old end")?;
12061        let insert_range = {
12062            match completion.old_insert_start.zip(completion.old_insert_end) {
12063                Some((start, end)) => {
12064                    let start = deserialize_anchor(start).context("invalid insert old start")?;
12065                    let end = deserialize_anchor(end).context("invalid insert old end")?;
12066                    Some(start..end)
12067                }
12068                None => None,
12069            }
12070        };
12071        Ok(CoreCompletion {
12072            replace_range: old_replace_start..old_replace_end,
12073            new_text: completion.new_text,
12074            source: match proto::completion::Source::from_i32(completion.source) {
12075                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
12076                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
12077                    insert_range,
12078                    server_id: LanguageServerId::from_proto(completion.server_id),
12079                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
12080                    lsp_defaults: completion
12081                        .lsp_defaults
12082                        .as_deref()
12083                        .map(serde_json::from_slice)
12084                        .transpose()?,
12085                    resolved: completion.resolved,
12086                },
12087                Some(proto::completion::Source::BufferWord) => {
12088                    let word_range = completion
12089                        .buffer_word_start
12090                        .and_then(deserialize_anchor)
12091                        .context("invalid buffer word start")?
12092                        ..completion
12093                            .buffer_word_end
12094                            .and_then(deserialize_anchor)
12095                            .context("invalid buffer word end")?;
12096                    CompletionSource::BufferWord {
12097                        word_range,
12098                        resolved: completion.resolved,
12099                    }
12100                }
12101                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12102                    sort_text: completion
12103                        .sort_text
12104                        .context("expected sort text to exist")?,
12105                },
12106                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12107            },
12108        })
12109    }
12110
12111    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12112        let (kind, lsp_action) = match &action.lsp_action {
12113            LspAction::Action(code_action) => (
12114                proto::code_action::Kind::Action as i32,
12115                serde_json::to_vec(code_action).unwrap(),
12116            ),
12117            LspAction::Command(command) => (
12118                proto::code_action::Kind::Command as i32,
12119                serde_json::to_vec(command).unwrap(),
12120            ),
12121            LspAction::CodeLens(code_lens) => (
12122                proto::code_action::Kind::CodeLens as i32,
12123                serde_json::to_vec(code_lens).unwrap(),
12124            ),
12125        };
12126
12127        proto::CodeAction {
12128            server_id: action.server_id.0 as u64,
12129            start: Some(serialize_anchor(&action.range.start)),
12130            end: Some(serialize_anchor(&action.range.end)),
12131            lsp_action,
12132            kind,
12133            resolved: action.resolved,
12134        }
12135    }
12136
12137    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12138        let start = action
12139            .start
12140            .and_then(deserialize_anchor)
12141            .context("invalid start")?;
12142        let end = action
12143            .end
12144            .and_then(deserialize_anchor)
12145            .context("invalid end")?;
12146        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12147            Some(proto::code_action::Kind::Action) => {
12148                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12149            }
12150            Some(proto::code_action::Kind::Command) => {
12151                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12152            }
12153            Some(proto::code_action::Kind::CodeLens) => {
12154                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12155            }
12156            None => anyhow::bail!("Unknown action kind {}", action.kind),
12157        };
12158        Ok(CodeAction {
12159            server_id: LanguageServerId(action.server_id as usize),
12160            range: start..end,
12161            resolved: action.resolved,
12162            lsp_action,
12163        })
12164    }
12165
12166    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12167        match &formatting_result {
12168            Ok(_) => self.last_formatting_failure = None,
12169            Err(error) => {
12170                let error_string = format!("{error:#}");
12171                log::error!("Formatting failed: {error_string}");
12172                self.last_formatting_failure
12173                    .replace(error_string.lines().join(" "));
12174            }
12175        }
12176    }
12177
12178    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12179        self.lsp_server_capabilities.remove(&for_server);
12180        self.semantic_token_config.remove_server_data(for_server);
12181        for lsp_data in self.lsp_data.values_mut() {
12182            lsp_data.remove_server_data(for_server);
12183        }
12184        if let Some(local) = self.as_local_mut() {
12185            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12186            local
12187                .workspace_pull_diagnostics_result_ids
12188                .remove(&for_server);
12189            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12190                buffer_servers.remove(&for_server);
12191            }
12192        }
12193    }
12194
12195    pub fn result_id_for_buffer_pull(
12196        &self,
12197        server_id: LanguageServerId,
12198        buffer_id: BufferId,
12199        registration_id: &Option<SharedString>,
12200        cx: &App,
12201    ) -> Option<SharedString> {
12202        let abs_path = self
12203            .buffer_store
12204            .read(cx)
12205            .get(buffer_id)
12206            .and_then(|b| File::from_dyn(b.read(cx).file()))
12207            .map(|f| f.abs_path(cx))?;
12208        self.as_local()?
12209            .buffer_pull_diagnostics_result_ids
12210            .get(&server_id)?
12211            .get(registration_id)?
12212            .get(&abs_path)?
12213            .clone()
12214    }
12215
12216    /// Gets all result_ids for a workspace diagnostics pull request.
12217    /// 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.
12218    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12219    pub fn result_ids_for_workspace_refresh(
12220        &self,
12221        server_id: LanguageServerId,
12222        registration_id: &Option<SharedString>,
12223    ) -> HashMap<PathBuf, SharedString> {
12224        let Some(local) = self.as_local() else {
12225            return HashMap::default();
12226        };
12227        local
12228            .workspace_pull_diagnostics_result_ids
12229            .get(&server_id)
12230            .into_iter()
12231            .filter_map(|diagnostics| diagnostics.get(registration_id))
12232            .flatten()
12233            .filter_map(|(abs_path, result_id)| {
12234                let result_id = local
12235                    .buffer_pull_diagnostics_result_ids
12236                    .get(&server_id)
12237                    .and_then(|buffer_ids_result_ids| {
12238                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12239                    })
12240                    .cloned()
12241                    .flatten()
12242                    .or_else(|| result_id.clone())?;
12243                Some((abs_path.clone(), result_id))
12244            })
12245            .collect()
12246    }
12247
12248    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12249        if let Some(LanguageServerState::Running {
12250            workspace_diagnostics_refresh_tasks,
12251            ..
12252        }) = self
12253            .as_local_mut()
12254            .and_then(|local| local.language_servers.get_mut(&server_id))
12255        {
12256            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12257                diagnostics.refresh_tx.try_send(()).ok();
12258            }
12259        }
12260    }
12261
12262    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12263    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12264    /// which requires refreshing both workspace and document diagnostics.
12265    pub fn pull_document_diagnostics_for_server(
12266        &mut self,
12267        server_id: LanguageServerId,
12268        source_buffer_id: Option<BufferId>,
12269        cx: &mut Context<Self>,
12270    ) -> Shared<Task<()>> {
12271        let Some(local) = self.as_local_mut() else {
12272            return Task::ready(()).shared();
12273        };
12274        let mut buffers_to_refresh = HashSet::default();
12275        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12276            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12277                buffers_to_refresh.insert(*buffer_id);
12278            }
12279        }
12280
12281        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12282    }
12283
12284    pub fn pull_document_diagnostics_for_buffer_edit(
12285        &mut self,
12286        buffer_id: BufferId,
12287        cx: &mut Context<Self>,
12288    ) {
12289        let Some(local) = self.as_local_mut() else {
12290            return;
12291        };
12292        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12293        else {
12294            return;
12295        };
12296        for server_id in languages_servers {
12297            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12298        }
12299    }
12300
12301    fn apply_workspace_diagnostic_report(
12302        &mut self,
12303        server_id: LanguageServerId,
12304        report: lsp::WorkspaceDiagnosticReportResult,
12305        registration_id: Option<SharedString>,
12306        cx: &mut Context<Self>,
12307    ) {
12308        let mut workspace_diagnostics =
12309            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12310                report,
12311                server_id,
12312                registration_id,
12313            );
12314        workspace_diagnostics.retain(|d| match &d.diagnostics {
12315            LspPullDiagnostics::Response {
12316                server_id,
12317                registration_id,
12318                ..
12319            } => self.diagnostic_registration_exists(*server_id, registration_id),
12320            LspPullDiagnostics::Default => false,
12321        });
12322        let mut unchanged_buffers = HashMap::default();
12323        let workspace_diagnostics_updates = workspace_diagnostics
12324            .into_iter()
12325            .filter_map(
12326                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12327                    LspPullDiagnostics::Response {
12328                        server_id,
12329                        uri,
12330                        diagnostics,
12331                        registration_id,
12332                    } => Some((
12333                        server_id,
12334                        uri,
12335                        diagnostics,
12336                        workspace_diagnostics.version,
12337                        registration_id,
12338                    )),
12339                    LspPullDiagnostics::Default => None,
12340                },
12341            )
12342            .fold(
12343                HashMap::default(),
12344                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12345                    let (result_id, diagnostics) = match diagnostics {
12346                        PulledDiagnostics::Unchanged { result_id } => {
12347                            unchanged_buffers
12348                                .entry(new_registration_id.clone())
12349                                .or_insert_with(HashSet::default)
12350                                .insert(uri.clone());
12351                            (Some(result_id), Vec::new())
12352                        }
12353                        PulledDiagnostics::Changed {
12354                            result_id,
12355                            diagnostics,
12356                        } => (result_id, diagnostics),
12357                    };
12358                    let disk_based_sources = Cow::Owned(
12359                        self.language_server_adapter_for_id(server_id)
12360                            .as_ref()
12361                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12362                            .unwrap_or(&[])
12363                            .to_vec(),
12364                    );
12365
12366                    let Some(abs_path) = uri.to_file_path().ok() else {
12367                        return acc;
12368                    };
12369                    let Some((worktree, relative_path)) =
12370                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12371                    else {
12372                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12373                        return acc;
12374                    };
12375                    let worktree_id = worktree.read(cx).id();
12376                    let project_path = ProjectPath {
12377                        worktree_id,
12378                        path: relative_path,
12379                    };
12380                    if let Some(local_lsp_store) = self.as_local_mut() {
12381                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12382                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12383                    }
12384                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12385                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12386                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12387                        acc.entry(server_id)
12388                            .or_insert_with(HashMap::default)
12389                            .entry(new_registration_id.clone())
12390                            .or_insert_with(Vec::new)
12391                            .push(DocumentDiagnosticsUpdate {
12392                                server_id,
12393                                diagnostics: lsp::PublishDiagnosticsParams {
12394                                    uri,
12395                                    diagnostics,
12396                                    version,
12397                                },
12398                                result_id: result_id.map(SharedString::new),
12399                                disk_based_sources,
12400                                registration_id: new_registration_id,
12401                            });
12402                    }
12403                    acc
12404                },
12405            );
12406
12407        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12408            for (registration_id, diagnostic_updates) in diagnostic_updates {
12409                self.merge_lsp_diagnostics(
12410                    DiagnosticSourceKind::Pulled,
12411                    diagnostic_updates,
12412                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12413                        DiagnosticSourceKind::Pulled => {
12414                            old_diagnostic.registration_id != registration_id
12415                                || unchanged_buffers
12416                                    .get(&old_diagnostic.registration_id)
12417                                    .is_some_and(|unchanged_buffers| {
12418                                        unchanged_buffers.contains(&document_uri)
12419                                    })
12420                        }
12421                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12422                    },
12423                    cx,
12424                )
12425                .log_err();
12426            }
12427        }
12428    }
12429
12430    fn register_server_capabilities(
12431        &mut self,
12432        server_id: LanguageServerId,
12433        params: lsp::RegistrationParams,
12434        cx: &mut Context<Self>,
12435    ) -> anyhow::Result<()> {
12436        let server = self
12437            .language_server_for_id(server_id)
12438            .with_context(|| format!("no server {server_id} found"))?;
12439        for reg in params.registrations {
12440            match reg.method.as_str() {
12441                "workspace/didChangeWatchedFiles" => {
12442                    if let Some(options) = reg.register_options {
12443                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12444                            let caps = serde_json::from_value(options)?;
12445                            local_lsp_store
12446                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12447                            true
12448                        } else {
12449                            false
12450                        };
12451                        if notify {
12452                            notify_server_capabilities_updated(&server, cx);
12453                        }
12454                    }
12455                }
12456                "workspace/didChangeConfiguration" => {
12457                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12458                }
12459                "workspace/didChangeWorkspaceFolders" => {
12460                    // In this case register options is an empty object, we can ignore it
12461                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12462                        supported: Some(true),
12463                        change_notifications: Some(OneOf::Right(reg.id)),
12464                    };
12465                    server.update_capabilities(|capabilities| {
12466                        capabilities
12467                            .workspace
12468                            .get_or_insert_default()
12469                            .workspace_folders = Some(caps);
12470                    });
12471                    notify_server_capabilities_updated(&server, cx);
12472                }
12473                "workspace/symbol" => {
12474                    let options = parse_register_capabilities(reg)?;
12475                    server.update_capabilities(|capabilities| {
12476                        capabilities.workspace_symbol_provider = Some(options);
12477                    });
12478                    notify_server_capabilities_updated(&server, cx);
12479                }
12480                "workspace/fileOperations" => {
12481                    if let Some(options) = reg.register_options {
12482                        let caps = serde_json::from_value(options)?;
12483                        server.update_capabilities(|capabilities| {
12484                            capabilities
12485                                .workspace
12486                                .get_or_insert_default()
12487                                .file_operations = Some(caps);
12488                        });
12489                        notify_server_capabilities_updated(&server, cx);
12490                    }
12491                }
12492                "workspace/executeCommand" => {
12493                    if let Some(options) = reg.register_options {
12494                        let options = serde_json::from_value(options)?;
12495                        server.update_capabilities(|capabilities| {
12496                            capabilities.execute_command_provider = Some(options);
12497                        });
12498                        notify_server_capabilities_updated(&server, cx);
12499                    }
12500                }
12501                "textDocument/rangeFormatting" => {
12502                    let options = parse_register_capabilities(reg)?;
12503                    server.update_capabilities(|capabilities| {
12504                        capabilities.document_range_formatting_provider = Some(options);
12505                    });
12506                    notify_server_capabilities_updated(&server, cx);
12507                }
12508                "textDocument/onTypeFormatting" => {
12509                    if let Some(options) = reg
12510                        .register_options
12511                        .map(serde_json::from_value)
12512                        .transpose()?
12513                    {
12514                        server.update_capabilities(|capabilities| {
12515                            capabilities.document_on_type_formatting_provider = Some(options);
12516                        });
12517                        notify_server_capabilities_updated(&server, cx);
12518                    }
12519                }
12520                "textDocument/formatting" => {
12521                    let options = parse_register_capabilities(reg)?;
12522                    server.update_capabilities(|capabilities| {
12523                        capabilities.document_formatting_provider = Some(options);
12524                    });
12525                    notify_server_capabilities_updated(&server, cx);
12526                }
12527                "textDocument/rename" => {
12528                    let options = parse_register_capabilities(reg)?;
12529                    server.update_capabilities(|capabilities| {
12530                        capabilities.rename_provider = Some(options);
12531                    });
12532                    notify_server_capabilities_updated(&server, cx);
12533                }
12534                "textDocument/inlayHint" => {
12535                    let options = parse_register_capabilities(reg)?;
12536                    server.update_capabilities(|capabilities| {
12537                        capabilities.inlay_hint_provider = Some(options);
12538                    });
12539                    notify_server_capabilities_updated(&server, cx);
12540                }
12541                "textDocument/documentSymbol" => {
12542                    let options = parse_register_capabilities(reg)?;
12543                    server.update_capabilities(|capabilities| {
12544                        capabilities.document_symbol_provider = Some(options);
12545                    });
12546                    notify_server_capabilities_updated(&server, cx);
12547                }
12548                "textDocument/codeAction" => {
12549                    let options = parse_register_capabilities(reg)?;
12550                    let provider = match options {
12551                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12552                        OneOf::Right(caps) => caps,
12553                    };
12554                    server.update_capabilities(|capabilities| {
12555                        capabilities.code_action_provider = Some(provider);
12556                    });
12557                    notify_server_capabilities_updated(&server, cx);
12558                }
12559                "textDocument/definition" => {
12560                    let options = parse_register_capabilities(reg)?;
12561                    server.update_capabilities(|capabilities| {
12562                        capabilities.definition_provider = Some(options);
12563                    });
12564                    notify_server_capabilities_updated(&server, cx);
12565                }
12566                "textDocument/completion" => {
12567                    if let Some(caps) = reg
12568                        .register_options
12569                        .map(serde_json::from_value::<CompletionOptions>)
12570                        .transpose()?
12571                    {
12572                        server.update_capabilities(|capabilities| {
12573                            capabilities.completion_provider = Some(caps.clone());
12574                        });
12575
12576                        if let Some(local) = self.as_local() {
12577                            let mut buffers_with_language_server = Vec::new();
12578                            for handle in self.buffer_store.read(cx).buffers() {
12579                                let buffer_id = handle.read(cx).remote_id();
12580                                if local
12581                                    .buffers_opened_in_servers
12582                                    .get(&buffer_id)
12583                                    .filter(|s| s.contains(&server_id))
12584                                    .is_some()
12585                                {
12586                                    buffers_with_language_server.push(handle);
12587                                }
12588                            }
12589                            let triggers = caps
12590                                .trigger_characters
12591                                .unwrap_or_default()
12592                                .into_iter()
12593                                .collect::<BTreeSet<_>>();
12594                            for handle in buffers_with_language_server {
12595                                let triggers = triggers.clone();
12596                                let _ = handle.update(cx, move |buffer, cx| {
12597                                    buffer.set_completion_triggers(server_id, triggers, cx);
12598                                });
12599                            }
12600                        }
12601                        notify_server_capabilities_updated(&server, cx);
12602                    }
12603                }
12604                "textDocument/hover" => {
12605                    let options = parse_register_capabilities(reg)?;
12606                    let provider = match options {
12607                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12608                        OneOf::Right(caps) => caps,
12609                    };
12610                    server.update_capabilities(|capabilities| {
12611                        capabilities.hover_provider = Some(provider);
12612                    });
12613                    notify_server_capabilities_updated(&server, cx);
12614                }
12615                "textDocument/signatureHelp" => {
12616                    if let Some(caps) = reg
12617                        .register_options
12618                        .map(serde_json::from_value)
12619                        .transpose()?
12620                    {
12621                        server.update_capabilities(|capabilities| {
12622                            capabilities.signature_help_provider = Some(caps);
12623                        });
12624                        notify_server_capabilities_updated(&server, cx);
12625                    }
12626                }
12627                "textDocument/didChange" => {
12628                    if let Some(sync_kind) = reg
12629                        .register_options
12630                        .and_then(|opts| opts.get("syncKind").cloned())
12631                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12632                        .transpose()?
12633                    {
12634                        server.update_capabilities(|capabilities| {
12635                            let mut sync_options =
12636                                Self::take_text_document_sync_options(capabilities);
12637                            sync_options.change = Some(sync_kind);
12638                            capabilities.text_document_sync =
12639                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12640                        });
12641                        notify_server_capabilities_updated(&server, cx);
12642                    }
12643                }
12644                "textDocument/didSave" => {
12645                    if let Some(include_text) = reg
12646                        .register_options
12647                        .map(|opts| {
12648                            let transpose = opts
12649                                .get("includeText")
12650                                .cloned()
12651                                .map(serde_json::from_value::<Option<bool>>)
12652                                .transpose();
12653                            match transpose {
12654                                Ok(value) => Ok(value.flatten()),
12655                                Err(e) => Err(e),
12656                            }
12657                        })
12658                        .transpose()?
12659                    {
12660                        server.update_capabilities(|capabilities| {
12661                            let mut sync_options =
12662                                Self::take_text_document_sync_options(capabilities);
12663                            sync_options.save =
12664                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12665                                    include_text,
12666                                }));
12667                            capabilities.text_document_sync =
12668                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12669                        });
12670                        notify_server_capabilities_updated(&server, cx);
12671                    }
12672                }
12673                "textDocument/codeLens" => {
12674                    if let Some(caps) = reg
12675                        .register_options
12676                        .map(serde_json::from_value)
12677                        .transpose()?
12678                    {
12679                        server.update_capabilities(|capabilities| {
12680                            capabilities.code_lens_provider = Some(caps);
12681                        });
12682                        notify_server_capabilities_updated(&server, cx);
12683                    }
12684                }
12685                "textDocument/diagnostic" => {
12686                    if let Some(caps) = reg
12687                        .register_options
12688                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12689                        .transpose()?
12690                    {
12691                        let local = self
12692                            .as_local_mut()
12693                            .context("Expected LSP Store to be local")?;
12694                        let state = local
12695                            .language_servers
12696                            .get_mut(&server_id)
12697                            .context("Could not obtain Language Servers state")?;
12698                        local
12699                            .language_server_dynamic_registrations
12700                            .entry(server_id)
12701                            .or_default()
12702                            .diagnostics
12703                            .insert(Some(reg.id.clone()), caps.clone());
12704
12705                        let supports_workspace_diagnostics =
12706                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12707                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12708                                    diagnostic_options.workspace_diagnostics
12709                                }
12710                                DiagnosticServerCapabilities::RegistrationOptions(
12711                                    diagnostic_registration_options,
12712                                ) => {
12713                                    diagnostic_registration_options
12714                                        .diagnostic_options
12715                                        .workspace_diagnostics
12716                                }
12717                            };
12718
12719                        if supports_workspace_diagnostics(&caps) {
12720                            if let LanguageServerState::Running {
12721                                workspace_diagnostics_refresh_tasks,
12722                                ..
12723                            } = state
12724                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12725                                    Some(reg.id.clone()),
12726                                    caps.clone(),
12727                                    server.clone(),
12728                                    cx,
12729                                )
12730                            {
12731                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12732                            }
12733                        }
12734
12735                        server.update_capabilities(|capabilities| {
12736                            capabilities.diagnostic_provider = Some(caps);
12737                        });
12738
12739                        notify_server_capabilities_updated(&server, cx);
12740
12741                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12742                    }
12743                }
12744                "textDocument/documentColor" => {
12745                    let options = parse_register_capabilities(reg)?;
12746                    let provider = match options {
12747                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12748                        OneOf::Right(caps) => caps,
12749                    };
12750                    server.update_capabilities(|capabilities| {
12751                        capabilities.color_provider = Some(provider);
12752                    });
12753                    notify_server_capabilities_updated(&server, cx);
12754                }
12755                "textDocument/foldingRange" => {
12756                    let options = parse_register_capabilities(reg)?;
12757                    let provider = match options {
12758                        OneOf::Left(value) => lsp::FoldingRangeProviderCapability::Simple(value),
12759                        OneOf::Right(caps) => caps,
12760                    };
12761                    server.update_capabilities(|capabilities| {
12762                        capabilities.folding_range_provider = Some(provider);
12763                    });
12764                    notify_server_capabilities_updated(&server, cx);
12765                }
12766                _ => log::warn!("unhandled capability registration: {reg:?}"),
12767            }
12768        }
12769
12770        Ok(())
12771    }
12772
12773    fn unregister_server_capabilities(
12774        &mut self,
12775        server_id: LanguageServerId,
12776        params: lsp::UnregistrationParams,
12777        cx: &mut Context<Self>,
12778    ) -> anyhow::Result<()> {
12779        let server = self
12780            .language_server_for_id(server_id)
12781            .with_context(|| format!("no server {server_id} found"))?;
12782        for unreg in params.unregisterations.iter() {
12783            match unreg.method.as_str() {
12784                "workspace/didChangeWatchedFiles" => {
12785                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12786                        local_lsp_store
12787                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12788                        true
12789                    } else {
12790                        false
12791                    };
12792                    if notify {
12793                        notify_server_capabilities_updated(&server, cx);
12794                    }
12795                }
12796                "workspace/didChangeConfiguration" => {
12797                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12798                }
12799                "workspace/didChangeWorkspaceFolders" => {
12800                    server.update_capabilities(|capabilities| {
12801                        capabilities
12802                            .workspace
12803                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12804                                workspace_folders: None,
12805                                file_operations: None,
12806                            })
12807                            .workspace_folders = None;
12808                    });
12809                    notify_server_capabilities_updated(&server, cx);
12810                }
12811                "workspace/symbol" => {
12812                    server.update_capabilities(|capabilities| {
12813                        capabilities.workspace_symbol_provider = None
12814                    });
12815                    notify_server_capabilities_updated(&server, cx);
12816                }
12817                "workspace/fileOperations" => {
12818                    server.update_capabilities(|capabilities| {
12819                        capabilities
12820                            .workspace
12821                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12822                                workspace_folders: None,
12823                                file_operations: None,
12824                            })
12825                            .file_operations = None;
12826                    });
12827                    notify_server_capabilities_updated(&server, cx);
12828                }
12829                "workspace/executeCommand" => {
12830                    server.update_capabilities(|capabilities| {
12831                        capabilities.execute_command_provider = None;
12832                    });
12833                    notify_server_capabilities_updated(&server, cx);
12834                }
12835                "textDocument/rangeFormatting" => {
12836                    server.update_capabilities(|capabilities| {
12837                        capabilities.document_range_formatting_provider = None
12838                    });
12839                    notify_server_capabilities_updated(&server, cx);
12840                }
12841                "textDocument/onTypeFormatting" => {
12842                    server.update_capabilities(|capabilities| {
12843                        capabilities.document_on_type_formatting_provider = None;
12844                    });
12845                    notify_server_capabilities_updated(&server, cx);
12846                }
12847                "textDocument/formatting" => {
12848                    server.update_capabilities(|capabilities| {
12849                        capabilities.document_formatting_provider = None;
12850                    });
12851                    notify_server_capabilities_updated(&server, cx);
12852                }
12853                "textDocument/rename" => {
12854                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12855                    notify_server_capabilities_updated(&server, cx);
12856                }
12857                "textDocument/codeAction" => {
12858                    server.update_capabilities(|capabilities| {
12859                        capabilities.code_action_provider = None;
12860                    });
12861                    notify_server_capabilities_updated(&server, cx);
12862                }
12863                "textDocument/definition" => {
12864                    server.update_capabilities(|capabilities| {
12865                        capabilities.definition_provider = None;
12866                    });
12867                    notify_server_capabilities_updated(&server, cx);
12868                }
12869                "textDocument/completion" => {
12870                    server.update_capabilities(|capabilities| {
12871                        capabilities.completion_provider = None;
12872                    });
12873                    notify_server_capabilities_updated(&server, cx);
12874                }
12875                "textDocument/hover" => {
12876                    server.update_capabilities(|capabilities| {
12877                        capabilities.hover_provider = None;
12878                    });
12879                    notify_server_capabilities_updated(&server, cx);
12880                }
12881                "textDocument/signatureHelp" => {
12882                    server.update_capabilities(|capabilities| {
12883                        capabilities.signature_help_provider = None;
12884                    });
12885                    notify_server_capabilities_updated(&server, cx);
12886                }
12887                "textDocument/didChange" => {
12888                    server.update_capabilities(|capabilities| {
12889                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12890                        sync_options.change = None;
12891                        capabilities.text_document_sync =
12892                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12893                    });
12894                    notify_server_capabilities_updated(&server, cx);
12895                }
12896                "textDocument/didSave" => {
12897                    server.update_capabilities(|capabilities| {
12898                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12899                        sync_options.save = None;
12900                        capabilities.text_document_sync =
12901                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12902                    });
12903                    notify_server_capabilities_updated(&server, cx);
12904                }
12905                "textDocument/codeLens" => {
12906                    server.update_capabilities(|capabilities| {
12907                        capabilities.code_lens_provider = None;
12908                    });
12909                    notify_server_capabilities_updated(&server, cx);
12910                }
12911                "textDocument/diagnostic" => {
12912                    let local = self
12913                        .as_local_mut()
12914                        .context("Expected LSP Store to be local")?;
12915
12916                    let state = local
12917                        .language_servers
12918                        .get_mut(&server_id)
12919                        .context("Could not obtain Language Servers state")?;
12920                    let registrations = local
12921                        .language_server_dynamic_registrations
12922                        .get_mut(&server_id)
12923                        .with_context(|| {
12924                            format!("Expected dynamic registration to exist for server {server_id}")
12925                        })?;
12926                    registrations.diagnostics
12927                        .remove(&Some(unreg.id.clone()))
12928                        .with_context(|| format!(
12929                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12930                            unreg.id)
12931                        )?;
12932                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12933
12934                    if let LanguageServerState::Running {
12935                        workspace_diagnostics_refresh_tasks,
12936                        ..
12937                    } = state
12938                    {
12939                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12940                    }
12941
12942                    self.clear_unregistered_diagnostics(
12943                        server_id,
12944                        SharedString::from(unreg.id.clone()),
12945                        cx,
12946                    )?;
12947
12948                    if removed_last_diagnostic_provider {
12949                        server.update_capabilities(|capabilities| {
12950                            debug_assert!(capabilities.diagnostic_provider.is_some());
12951                            capabilities.diagnostic_provider = None;
12952                        });
12953                    }
12954
12955                    notify_server_capabilities_updated(&server, cx);
12956                }
12957                "textDocument/documentColor" => {
12958                    server.update_capabilities(|capabilities| {
12959                        capabilities.color_provider = None;
12960                    });
12961                    notify_server_capabilities_updated(&server, cx);
12962                }
12963                "textDocument/foldingRange" => {
12964                    server.update_capabilities(|capabilities| {
12965                        capabilities.folding_range_provider = None;
12966                    });
12967                    notify_server_capabilities_updated(&server, cx);
12968                }
12969                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12970            }
12971        }
12972
12973        Ok(())
12974    }
12975
12976    fn clear_unregistered_diagnostics(
12977        &mut self,
12978        server_id: LanguageServerId,
12979        cleared_registration_id: SharedString,
12980        cx: &mut Context<Self>,
12981    ) -> anyhow::Result<()> {
12982        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12983
12984        self.buffer_store.update(cx, |buffer_store, cx| {
12985            for buffer_handle in buffer_store.buffers() {
12986                let buffer = buffer_handle.read(cx);
12987                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12988                let Some(abs_path) = abs_path else {
12989                    continue;
12990                };
12991                affected_abs_paths.insert(abs_path);
12992            }
12993        });
12994
12995        let local = self.as_local().context("Expected LSP Store to be local")?;
12996        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12997            let Some(worktree) = self
12998                .worktree_store
12999                .read(cx)
13000                .worktree_for_id(*worktree_id, cx)
13001            else {
13002                continue;
13003            };
13004
13005            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
13006                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
13007                    let has_matching_registration =
13008                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
13009                            entry.diagnostic.registration_id.as_ref()
13010                                == Some(&cleared_registration_id)
13011                        });
13012                    if has_matching_registration {
13013                        let abs_path = worktree.read(cx).absolutize(rel_path);
13014                        affected_abs_paths.insert(abs_path);
13015                    }
13016                }
13017            }
13018        }
13019
13020        if affected_abs_paths.is_empty() {
13021            return Ok(());
13022        }
13023
13024        // Send a fake diagnostic update which clears the state for the registration ID
13025        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
13026            affected_abs_paths
13027                .into_iter()
13028                .map(|abs_path| DocumentDiagnosticsUpdate {
13029                    diagnostics: DocumentDiagnostics {
13030                        diagnostics: Vec::new(),
13031                        document_abs_path: abs_path,
13032                        version: None,
13033                    },
13034                    result_id: None,
13035                    registration_id: Some(cleared_registration_id.clone()),
13036                    server_id,
13037                    disk_based_sources: Cow::Borrowed(&[]),
13038                })
13039                .collect();
13040
13041        let merge_registration_id = cleared_registration_id.clone();
13042        self.merge_diagnostic_entries(
13043            clears,
13044            move |_, diagnostic, _| {
13045                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
13046                    diagnostic.registration_id != Some(merge_registration_id.clone())
13047                } else {
13048                    true
13049                }
13050            },
13051            cx,
13052        )?;
13053
13054        Ok(())
13055    }
13056
13057    async fn deduplicate_range_based_lsp_requests<T>(
13058        lsp_store: &Entity<Self>,
13059        server_id: Option<LanguageServerId>,
13060        lsp_request_id: LspRequestId,
13061        proto_request: &T::ProtoRequest,
13062        range: Range<Anchor>,
13063        cx: &mut AsyncApp,
13064    ) -> Result<()>
13065    where
13066        T: LspCommand,
13067        T::ProtoRequest: proto::LspRequestMessage,
13068    {
13069        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13070        let version = deserialize_version(proto_request.buffer_version());
13071        let buffer = lsp_store.update(cx, |this, cx| {
13072            this.buffer_store.read(cx).get_existing(buffer_id)
13073        })?;
13074        buffer
13075            .update(cx, |buffer, _| buffer.wait_for_version(version))
13076            .await?;
13077        lsp_store.update(cx, |lsp_store, cx| {
13078            let buffer_snapshot = buffer.read(cx).snapshot();
13079            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13080            let chunks_queried_for = lsp_data
13081                .inlay_hints
13082                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
13083                .collect::<Vec<_>>();
13084            match chunks_queried_for.as_slice() {
13085                &[chunk] => {
13086                    let key = LspKey {
13087                        request_type: TypeId::of::<T>(),
13088                        server_queried: server_id,
13089                    };
13090                    let previous_request = lsp_data
13091                        .chunk_lsp_requests
13092                        .entry(key)
13093                        .or_default()
13094                        .insert(chunk, lsp_request_id);
13095                    if let Some((previous_request, running_requests)) =
13096                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13097                    {
13098                        running_requests.remove(&previous_request);
13099                    }
13100                }
13101                _ambiguous_chunks => {
13102                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13103                    // there, a buffer version-based check will be performed and outdated requests discarded.
13104                }
13105            }
13106            anyhow::Ok(())
13107        })?;
13108
13109        Ok(())
13110    }
13111
13112    async fn query_lsp_locally<T>(
13113        lsp_store: Entity<Self>,
13114        for_server_id: Option<LanguageServerId>,
13115        sender_id: proto::PeerId,
13116        lsp_request_id: LspRequestId,
13117        proto_request: T::ProtoRequest,
13118        position: Option<Anchor>,
13119        cx: &mut AsyncApp,
13120    ) -> Result<()>
13121    where
13122        T: LspCommand + Clone,
13123        T::ProtoRequest: proto::LspRequestMessage,
13124        <T::ProtoRequest as proto::RequestMessage>::Response:
13125            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13126    {
13127        let (buffer_version, buffer) =
13128            Self::wait_for_buffer_version::<T>(&lsp_store, &proto_request, cx).await?;
13129        let request =
13130            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13131        let key = LspKey {
13132            request_type: TypeId::of::<T>(),
13133            server_queried: for_server_id,
13134        };
13135        lsp_store.update(cx, |lsp_store, cx| {
13136            let request_task = match for_server_id {
13137                Some(server_id) => {
13138                    let server_task = lsp_store.request_lsp(
13139                        buffer.clone(),
13140                        LanguageServerToQuery::Other(server_id),
13141                        request.clone(),
13142                        cx,
13143                    );
13144                    cx.background_spawn(async move {
13145                        let mut responses = Vec::new();
13146                        match server_task.await {
13147                            Ok(response) => responses.push((server_id, response)),
13148                            // rust-analyzer likes to error with this when its still loading up
13149                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13150                            Err(e) => log::error!(
13151                                "Error handling response for request {request:?}: {e:#}"
13152                            ),
13153                        }
13154                        responses
13155                    })
13156                }
13157                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13158            };
13159            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13160            if T::ProtoRequest::stop_previous_requests() {
13161                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13162                    lsp_requests.clear();
13163                }
13164            }
13165            lsp_data.lsp_requests.entry(key).or_default().insert(
13166                lsp_request_id,
13167                cx.spawn(async move |lsp_store, cx| {
13168                    let response = request_task.await;
13169                    lsp_store
13170                        .update(cx, |lsp_store, cx| {
13171                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13172                            {
13173                                let response = response
13174                                    .into_iter()
13175                                    .map(|(server_id, response)| {
13176                                        (
13177                                            server_id.to_proto(),
13178                                            T::response_to_proto(
13179                                                response,
13180                                                lsp_store,
13181                                                sender_id,
13182                                                &buffer_version,
13183                                                cx,
13184                                            )
13185                                            .into(),
13186                                        )
13187                                    })
13188                                    .collect::<HashMap<_, _>>();
13189                                match client.send_lsp_response::<T::ProtoRequest>(
13190                                    project_id,
13191                                    lsp_request_id,
13192                                    response,
13193                                ) {
13194                                    Ok(()) => {}
13195                                    Err(e) => {
13196                                        log::error!("Failed to send LSP response: {e:#}",)
13197                                    }
13198                                }
13199                            }
13200                        })
13201                        .ok();
13202                }),
13203            );
13204        });
13205        Ok(())
13206    }
13207
13208    async fn wait_for_buffer_version<T>(
13209        lsp_store: &Entity<Self>,
13210        proto_request: &T::ProtoRequest,
13211        cx: &mut AsyncApp,
13212    ) -> Result<(Global, Entity<Buffer>)>
13213    where
13214        T: LspCommand,
13215        T::ProtoRequest: proto::LspRequestMessage,
13216    {
13217        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13218        let version = deserialize_version(proto_request.buffer_version());
13219        let buffer = lsp_store.update(cx, |this, cx| {
13220            this.buffer_store.read(cx).get_existing(buffer_id)
13221        })?;
13222        buffer
13223            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13224            .await?;
13225        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13226        Ok((buffer_version, buffer))
13227    }
13228
13229    fn take_text_document_sync_options(
13230        capabilities: &mut lsp::ServerCapabilities,
13231    ) -> lsp::TextDocumentSyncOptions {
13232        match capabilities.text_document_sync.take() {
13233            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13234            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13235                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13236                sync_options.change = Some(sync_kind);
13237                sync_options
13238            }
13239            None => lsp::TextDocumentSyncOptions::default(),
13240        }
13241    }
13242
13243    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13244        self.downstream_client.clone()
13245    }
13246
13247    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13248        self.worktree_store.clone()
13249    }
13250
13251    /// Gets what's stored in the LSP data for the given buffer.
13252    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13253        self.lsp_data.get_mut(&buffer_id)
13254    }
13255
13256    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13257    /// new [`BufferLspData`] will be created to replace the previous state.
13258    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13259        let (buffer_id, buffer_version) =
13260            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13261        let lsp_data = self
13262            .lsp_data
13263            .entry(buffer_id)
13264            .or_insert_with(|| BufferLspData::new(buffer, cx));
13265        if buffer_version.changed_since(&lsp_data.buffer_version) {
13266            // To send delta requests for semantic tokens, the previous tokens
13267            // need to be kept between buffer changes.
13268            let semantic_tokens = lsp_data.semantic_tokens.take();
13269            *lsp_data = BufferLspData::new(buffer, cx);
13270            lsp_data.semantic_tokens = semantic_tokens;
13271        }
13272        lsp_data
13273    }
13274}
13275
13276// Registration with registerOptions as null, should fallback to true.
13277// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13278fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13279    reg: lsp::Registration,
13280) -> Result<OneOf<bool, T>> {
13281    Ok(match reg.register_options {
13282        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13283        None => OneOf::Left(true),
13284    })
13285}
13286
13287fn subscribe_to_binary_statuses(
13288    languages: &Arc<LanguageRegistry>,
13289    cx: &mut Context<'_, LspStore>,
13290) -> Task<()> {
13291    let mut server_statuses = languages.language_server_binary_statuses();
13292    cx.spawn(async move |lsp_store, cx| {
13293        while let Some((server_name, binary_status)) = server_statuses.next().await {
13294            if lsp_store
13295                .update(cx, |_, cx| {
13296                    let mut message = None;
13297                    let binary_status = match binary_status {
13298                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13299                        BinaryStatus::CheckingForUpdate => {
13300                            proto::ServerBinaryStatus::CheckingForUpdate
13301                        }
13302                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13303                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13304                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13305                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13306                        BinaryStatus::Failed { error } => {
13307                            message = Some(error);
13308                            proto::ServerBinaryStatus::Failed
13309                        }
13310                    };
13311                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13312                        // Binary updates are about the binary that might not have any language server id at that point.
13313                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13314                        language_server_id: LanguageServerId(0),
13315                        name: Some(server_name),
13316                        message: proto::update_language_server::Variant::StatusUpdate(
13317                            proto::StatusUpdate {
13318                                message,
13319                                status: Some(proto::status_update::Status::Binary(
13320                                    binary_status as i32,
13321                                )),
13322                            },
13323                        ),
13324                    });
13325                })
13326                .is_err()
13327            {
13328                break;
13329            }
13330        }
13331    })
13332}
13333
13334fn lsp_workspace_diagnostics_refresh(
13335    registration_id: Option<String>,
13336    options: DiagnosticServerCapabilities,
13337    server: Arc<LanguageServer>,
13338    cx: &mut Context<'_, LspStore>,
13339) -> Option<WorkspaceRefreshTask> {
13340    let identifier = workspace_diagnostic_identifier(&options)?;
13341    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13342
13343    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13344    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13345    refresh_tx.try_send(()).ok();
13346
13347    let request_timeout = ProjectSettings::get_global(cx)
13348        .global_lsp_settings
13349        .get_request_timeout();
13350
13351    // 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.
13352    // This allows users to increase the duration if need be
13353    let timeout = if request_timeout != Duration::ZERO {
13354        request_timeout.max(DEFAULT_LSP_REQUEST_TIMEOUT)
13355    } else {
13356        request_timeout
13357    };
13358
13359    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13360        let mut attempts = 0;
13361        let max_attempts = 50;
13362        let mut requests = 0;
13363
13364        loop {
13365            let Some(()) = refresh_rx.recv().await else {
13366                return;
13367            };
13368
13369            'request: loop {
13370                requests += 1;
13371                if attempts > max_attempts {
13372                    log::error!(
13373                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13374                    );
13375                    return;
13376                }
13377                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13378                cx.background_executor()
13379                    .timer(Duration::from_millis(backoff_millis))
13380                    .await;
13381                attempts += 1;
13382
13383                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13384                    lsp_store
13385                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13386                        .into_iter()
13387                        .filter_map(|(abs_path, result_id)| {
13388                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13389                            Some(lsp::PreviousResultId {
13390                                uri,
13391                                value: result_id.to_string(),
13392                            })
13393                        })
13394                        .collect()
13395                }) else {
13396                    return;
13397                };
13398
13399                let token = if let Some(registration_id) = &registration_id {
13400                    format!(
13401                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13402                        server.server_id(),
13403                    )
13404                } else {
13405                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13406                };
13407
13408                progress_rx.try_recv().ok();
13409                let timer = server.request_timer(timeout).fuse();
13410                let progress = pin!(progress_rx.recv().fuse());
13411                let response_result = server
13412                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13413                        lsp::WorkspaceDiagnosticParams {
13414                            previous_result_ids,
13415                            identifier: identifier.clone(),
13416                            work_done_progress_params: Default::default(),
13417                            partial_result_params: lsp::PartialResultParams {
13418                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13419                            },
13420                        },
13421                        select(timer, progress).then(|either| match either {
13422                            Either::Left((message, ..)) => ready(message).left_future(),
13423                            Either::Right(..) => pending::<String>().right_future(),
13424                        }),
13425                    )
13426                    .await;
13427
13428                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13429                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13430                match response_result {
13431                    ConnectionResult::Timeout => {
13432                        log::error!("Timeout during workspace diagnostics pull");
13433                        continue 'request;
13434                    }
13435                    ConnectionResult::ConnectionReset => {
13436                        log::error!("Server closed a workspace diagnostics pull request");
13437                        continue 'request;
13438                    }
13439                    ConnectionResult::Result(Err(e)) => {
13440                        log::error!("Error during workspace diagnostics pull: {e:#}");
13441                        break 'request;
13442                    }
13443                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13444                        attempts = 0;
13445                        if lsp_store
13446                            .update(cx, |lsp_store, cx| {
13447                                lsp_store.apply_workspace_diagnostic_report(
13448                                    server.server_id(),
13449                                    pulled_diagnostics,
13450                                    registration_id_shared.clone(),
13451                                    cx,
13452                                )
13453                            })
13454                            .is_err()
13455                        {
13456                            return;
13457                        }
13458                        break 'request;
13459                    }
13460                }
13461            }
13462        }
13463    });
13464
13465    Some(WorkspaceRefreshTask {
13466        refresh_tx,
13467        progress_tx,
13468        task: workspace_query_language_server,
13469    })
13470}
13471
13472fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<SharedString> {
13473    match &options {
13474        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => diagnostic_options
13475            .identifier
13476            .as_deref()
13477            .map(SharedString::new),
13478        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13479            let diagnostic_options = &registration_options.diagnostic_options;
13480            diagnostic_options
13481                .identifier
13482                .as_deref()
13483                .map(SharedString::new)
13484        }
13485    }
13486}
13487
13488fn workspace_diagnostic_identifier(
13489    options: &DiagnosticServerCapabilities,
13490) -> Option<Option<String>> {
13491    match &options {
13492        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13493            if !diagnostic_options.workspace_diagnostics {
13494                return None;
13495            }
13496            Some(diagnostic_options.identifier.clone())
13497        }
13498        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13499            let diagnostic_options = &registration_options.diagnostic_options;
13500            if !diagnostic_options.workspace_diagnostics {
13501                return None;
13502            }
13503            Some(diagnostic_options.identifier.clone())
13504        }
13505    }
13506}
13507
13508fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13509    let CompletionSource::BufferWord {
13510        word_range,
13511        resolved,
13512    } = &mut completion.source
13513    else {
13514        return;
13515    };
13516    if *resolved {
13517        return;
13518    }
13519
13520    if completion.new_text
13521        != snapshot
13522            .text_for_range(word_range.clone())
13523            .collect::<String>()
13524    {
13525        return;
13526    }
13527
13528    let mut offset = 0;
13529    for chunk in snapshot.chunks(word_range.clone(), true) {
13530        let end_offset = offset + chunk.text.len();
13531        if let Some(highlight_id) = chunk.syntax_highlight_id {
13532            completion
13533                .label
13534                .runs
13535                .push((offset..end_offset, highlight_id));
13536        }
13537        offset = end_offset;
13538    }
13539    *resolved = true;
13540}
13541
13542impl EventEmitter<LspStoreEvent> for LspStore {}
13543
13544fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13545    hover
13546        .contents
13547        .retain(|hover_block| !hover_block.text.trim().is_empty());
13548    if hover.contents.is_empty() {
13549        None
13550    } else {
13551        Some(hover)
13552    }
13553}
13554
13555async fn populate_labels_for_completions(
13556    new_completions: Vec<CoreCompletion>,
13557    language: Option<Arc<Language>>,
13558    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13559) -> Vec<Completion> {
13560    let lsp_completions = new_completions
13561        .iter()
13562        .filter_map(|new_completion| {
13563            new_completion
13564                .source
13565                .lsp_completion(true)
13566                .map(|lsp_completion| lsp_completion.into_owned())
13567        })
13568        .collect::<Vec<_>>();
13569
13570    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13571        lsp_adapter
13572            .labels_for_completions(&lsp_completions, language)
13573            .await
13574            .log_err()
13575            .unwrap_or_default()
13576    } else {
13577        Vec::new()
13578    }
13579    .into_iter()
13580    .fuse();
13581
13582    let mut completions = Vec::new();
13583    for completion in new_completions {
13584        match completion.source.lsp_completion(true) {
13585            Some(lsp_completion) => {
13586                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13587
13588                let mut label = labels.next().flatten().unwrap_or_else(|| {
13589                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13590                });
13591                ensure_uniform_list_compatible_label(&mut label);
13592                completions.push(Completion {
13593                    label,
13594                    documentation,
13595                    replace_range: completion.replace_range,
13596                    new_text: completion.new_text,
13597                    insert_text_mode: lsp_completion.insert_text_mode,
13598                    source: completion.source,
13599                    icon_path: None,
13600                    confirm: None,
13601                    match_start: None,
13602                    snippet_deduplication_key: None,
13603                });
13604            }
13605            None => {
13606                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13607                ensure_uniform_list_compatible_label(&mut label);
13608                completions.push(Completion {
13609                    label,
13610                    documentation: None,
13611                    replace_range: completion.replace_range,
13612                    new_text: completion.new_text,
13613                    source: completion.source,
13614                    insert_text_mode: None,
13615                    icon_path: None,
13616                    confirm: None,
13617                    match_start: None,
13618                    snippet_deduplication_key: None,
13619                });
13620            }
13621        }
13622    }
13623    completions
13624}
13625
13626#[derive(Debug)]
13627pub enum LanguageServerToQuery {
13628    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13629    FirstCapable,
13630    /// Query a specific language server.
13631    Other(LanguageServerId),
13632}
13633
13634#[derive(Default)]
13635struct RenamePathsWatchedForServer {
13636    did_rename: Vec<RenameActionPredicate>,
13637    will_rename: Vec<RenameActionPredicate>,
13638}
13639
13640impl RenamePathsWatchedForServer {
13641    fn with_did_rename_patterns(
13642        mut self,
13643        did_rename: Option<&FileOperationRegistrationOptions>,
13644    ) -> Self {
13645        if let Some(did_rename) = did_rename {
13646            self.did_rename = did_rename
13647                .filters
13648                .iter()
13649                .filter_map(|filter| filter.try_into().log_err())
13650                .collect();
13651        }
13652        self
13653    }
13654    fn with_will_rename_patterns(
13655        mut self,
13656        will_rename: Option<&FileOperationRegistrationOptions>,
13657    ) -> Self {
13658        if let Some(will_rename) = will_rename {
13659            self.will_rename = will_rename
13660                .filters
13661                .iter()
13662                .filter_map(|filter| filter.try_into().log_err())
13663                .collect();
13664        }
13665        self
13666    }
13667
13668    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13669        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13670    }
13671    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13672        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13673    }
13674}
13675
13676impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13677    type Error = globset::Error;
13678    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13679        Ok(Self {
13680            kind: ops.pattern.matches.clone(),
13681            glob: GlobBuilder::new(&ops.pattern.glob)
13682                .case_insensitive(
13683                    ops.pattern
13684                        .options
13685                        .as_ref()
13686                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13687                )
13688                .build()?
13689                .compile_matcher(),
13690        })
13691    }
13692}
13693struct RenameActionPredicate {
13694    glob: GlobMatcher,
13695    kind: Option<FileOperationPatternKind>,
13696}
13697
13698impl RenameActionPredicate {
13699    // Returns true if language server should be notified
13700    fn eval(&self, path: &str, is_dir: bool) -> bool {
13701        self.kind.as_ref().is_none_or(|kind| {
13702            let expected_kind = if is_dir {
13703                FileOperationPatternKind::Folder
13704            } else {
13705                FileOperationPatternKind::File
13706            };
13707            kind == &expected_kind
13708        }) && self.glob.is_match(path)
13709    }
13710}
13711
13712#[derive(Default)]
13713struct LanguageServerWatchedPaths {
13714    worktree_paths: HashMap<WorktreeId, GlobSet>,
13715    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13716}
13717
13718#[derive(Default)]
13719struct LanguageServerWatchedPathsBuilder {
13720    worktree_paths: HashMap<WorktreeId, GlobSet>,
13721    abs_paths: HashMap<Arc<Path>, GlobSet>,
13722}
13723
13724impl LanguageServerWatchedPathsBuilder {
13725    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13726        self.worktree_paths.insert(worktree_id, glob_set);
13727    }
13728    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13729        self.abs_paths.insert(path, glob_set);
13730    }
13731    fn build(
13732        self,
13733        fs: Arc<dyn Fs>,
13734        language_server_id: LanguageServerId,
13735        cx: &mut Context<LspStore>,
13736    ) -> LanguageServerWatchedPaths {
13737        let lsp_store = cx.weak_entity();
13738
13739        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13740        let abs_paths = self
13741            .abs_paths
13742            .into_iter()
13743            .map(|(abs_path, globset)| {
13744                let task = cx.spawn({
13745                    let abs_path = abs_path.clone();
13746                    let fs = fs.clone();
13747
13748                    let lsp_store = lsp_store.clone();
13749                    async move |_, cx| {
13750                        maybe!(async move {
13751                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13752                            while let Some(update) = push_updates.0.next().await {
13753                                let action = lsp_store
13754                                    .update(cx, |this, _| {
13755                                        let Some(local) = this.as_local() else {
13756                                            return ControlFlow::Break(());
13757                                        };
13758                                        let Some(watcher) = local
13759                                            .language_server_watched_paths
13760                                            .get(&language_server_id)
13761                                        else {
13762                                            return ControlFlow::Break(());
13763                                        };
13764                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13765                                            "Watched abs path is not registered with a watcher",
13766                                        );
13767                                        let matching_entries = update
13768                                            .into_iter()
13769                                            .filter(|event| globs.is_match(&event.path))
13770                                            .collect::<Vec<_>>();
13771                                        this.lsp_notify_abs_paths_changed(
13772                                            language_server_id,
13773                                            matching_entries,
13774                                        );
13775                                        ControlFlow::Continue(())
13776                                    })
13777                                    .ok()?;
13778
13779                                if action.is_break() {
13780                                    break;
13781                                }
13782                            }
13783                            Some(())
13784                        })
13785                        .await;
13786                    }
13787                });
13788                (abs_path, (globset, task))
13789            })
13790            .collect();
13791        LanguageServerWatchedPaths {
13792            worktree_paths: self.worktree_paths,
13793            abs_paths,
13794        }
13795    }
13796}
13797
13798struct LspBufferSnapshot {
13799    version: i32,
13800    snapshot: TextBufferSnapshot,
13801}
13802
13803/// A prompt requested by LSP server.
13804#[derive(Clone, Debug)]
13805pub struct LanguageServerPromptRequest {
13806    pub id: usize,
13807    pub level: PromptLevel,
13808    pub message: String,
13809    pub actions: Vec<MessageActionItem>,
13810    pub lsp_name: String,
13811    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13812}
13813
13814impl LanguageServerPromptRequest {
13815    pub fn new(
13816        level: PromptLevel,
13817        message: String,
13818        actions: Vec<MessageActionItem>,
13819        lsp_name: String,
13820        response_channel: smol::channel::Sender<MessageActionItem>,
13821    ) -> Self {
13822        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13823        LanguageServerPromptRequest {
13824            id,
13825            level,
13826            message,
13827            actions,
13828            lsp_name,
13829            response_channel,
13830        }
13831    }
13832    pub async fn respond(self, index: usize) -> Option<()> {
13833        if let Some(response) = self.actions.into_iter().nth(index) {
13834            self.response_channel.send(response).await.ok()
13835        } else {
13836            None
13837        }
13838    }
13839
13840    #[cfg(any(test, feature = "test-support"))]
13841    pub fn test(
13842        level: PromptLevel,
13843        message: String,
13844        actions: Vec<MessageActionItem>,
13845        lsp_name: String,
13846    ) -> Self {
13847        let (tx, _rx) = smol::channel::unbounded();
13848        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13849    }
13850}
13851impl PartialEq for LanguageServerPromptRequest {
13852    fn eq(&self, other: &Self) -> bool {
13853        self.message == other.message && self.actions == other.actions
13854    }
13855}
13856
13857#[derive(Clone, Debug, PartialEq)]
13858pub enum LanguageServerLogType {
13859    Log(MessageType),
13860    Trace { verbose_info: Option<String> },
13861    Rpc { received: bool },
13862}
13863
13864impl LanguageServerLogType {
13865    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13866        match self {
13867            Self::Log(log_type) => {
13868                use proto::log_message::LogLevel;
13869                let level = match *log_type {
13870                    MessageType::ERROR => LogLevel::Error,
13871                    MessageType::WARNING => LogLevel::Warning,
13872                    MessageType::INFO => LogLevel::Info,
13873                    MessageType::LOG => LogLevel::Log,
13874                    other => {
13875                        log::warn!("Unknown lsp log message type: {other:?}");
13876                        LogLevel::Log
13877                    }
13878                };
13879                proto::language_server_log::LogType::Log(proto::LogMessage {
13880                    level: level as i32,
13881                })
13882            }
13883            Self::Trace { verbose_info } => {
13884                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13885                    verbose_info: verbose_info.to_owned(),
13886                })
13887            }
13888            Self::Rpc { received } => {
13889                let kind = if *received {
13890                    proto::rpc_message::Kind::Received
13891                } else {
13892                    proto::rpc_message::Kind::Sent
13893                };
13894                let kind = kind as i32;
13895                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13896            }
13897        }
13898    }
13899
13900    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13901        use proto::log_message::LogLevel;
13902        use proto::rpc_message;
13903        match log_type {
13904            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13905                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13906                    LogLevel::Error => MessageType::ERROR,
13907                    LogLevel::Warning => MessageType::WARNING,
13908                    LogLevel::Info => MessageType::INFO,
13909                    LogLevel::Log => MessageType::LOG,
13910                },
13911            ),
13912            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13913                verbose_info: trace_message.verbose_info,
13914            },
13915            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13916                received: match rpc_message::Kind::from_i32(message.kind)
13917                    .unwrap_or(rpc_message::Kind::Received)
13918                {
13919                    rpc_message::Kind::Received => true,
13920                    rpc_message::Kind::Sent => false,
13921                },
13922            },
13923        }
13924    }
13925}
13926
13927pub struct WorkspaceRefreshTask {
13928    refresh_tx: mpsc::Sender<()>,
13929    progress_tx: mpsc::Sender<()>,
13930    #[allow(dead_code)]
13931    task: Task<()>,
13932}
13933
13934pub enum LanguageServerState {
13935    Starting {
13936        startup: Task<Option<Arc<LanguageServer>>>,
13937        /// List of language servers that will be added to the workspace once it's initialization completes.
13938        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13939    },
13940
13941    Running {
13942        adapter: Arc<CachedLspAdapter>,
13943        server: Arc<LanguageServer>,
13944        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13945        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13946    },
13947}
13948
13949impl LanguageServerState {
13950    fn add_workspace_folder(&self, uri: Uri) {
13951        match self {
13952            LanguageServerState::Starting {
13953                pending_workspace_folders,
13954                ..
13955            } => {
13956                pending_workspace_folders.lock().insert(uri);
13957            }
13958            LanguageServerState::Running { server, .. } => {
13959                server.add_workspace_folder(uri);
13960            }
13961        }
13962    }
13963    fn _remove_workspace_folder(&self, uri: Uri) {
13964        match self {
13965            LanguageServerState::Starting {
13966                pending_workspace_folders,
13967                ..
13968            } => {
13969                pending_workspace_folders.lock().remove(&uri);
13970            }
13971            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13972        }
13973    }
13974}
13975
13976impl std::fmt::Debug for LanguageServerState {
13977    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13978        match self {
13979            LanguageServerState::Starting { .. } => {
13980                f.debug_struct("LanguageServerState::Starting").finish()
13981            }
13982            LanguageServerState::Running { .. } => {
13983                f.debug_struct("LanguageServerState::Running").finish()
13984            }
13985        }
13986    }
13987}
13988
13989#[derive(Clone, Debug, Serialize)]
13990pub struct LanguageServerProgress {
13991    pub is_disk_based_diagnostics_progress: bool,
13992    pub is_cancellable: bool,
13993    pub title: Option<String>,
13994    pub message: Option<String>,
13995    pub percentage: Option<usize>,
13996    #[serde(skip_serializing)]
13997    pub last_update_at: Instant,
13998}
13999
14000#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
14001pub struct DiagnosticSummary {
14002    pub error_count: usize,
14003    pub warning_count: usize,
14004}
14005
14006impl DiagnosticSummary {
14007    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
14008        let mut this = Self {
14009            error_count: 0,
14010            warning_count: 0,
14011        };
14012
14013        for entry in diagnostics {
14014            if entry.diagnostic.is_primary {
14015                match entry.diagnostic.severity {
14016                    DiagnosticSeverity::ERROR => this.error_count += 1,
14017                    DiagnosticSeverity::WARNING => this.warning_count += 1,
14018                    _ => {}
14019                }
14020            }
14021        }
14022
14023        this
14024    }
14025
14026    pub fn is_empty(&self) -> bool {
14027        self.error_count == 0 && self.warning_count == 0
14028    }
14029
14030    pub fn to_proto(
14031        self,
14032        language_server_id: LanguageServerId,
14033        path: &RelPath,
14034    ) -> proto::DiagnosticSummary {
14035        proto::DiagnosticSummary {
14036            path: path.to_proto(),
14037            language_server_id: language_server_id.0 as u64,
14038            error_count: self.error_count as u32,
14039            warning_count: self.warning_count as u32,
14040        }
14041    }
14042}
14043
14044#[derive(Clone, Debug)]
14045pub enum CompletionDocumentation {
14046    /// There is no documentation for this completion.
14047    Undocumented,
14048    /// A single line of documentation.
14049    SingleLine(SharedString),
14050    /// Multiple lines of plain text documentation.
14051    MultiLinePlainText(SharedString),
14052    /// Markdown documentation.
14053    MultiLineMarkdown(SharedString),
14054    /// Both single line and multiple lines of plain text documentation.
14055    SingleLineAndMultiLinePlainText {
14056        single_line: SharedString,
14057        plain_text: Option<SharedString>,
14058    },
14059}
14060
14061impl CompletionDocumentation {
14062    #[cfg(any(test, feature = "test-support"))]
14063    pub fn text(&self) -> SharedString {
14064        match self {
14065            CompletionDocumentation::Undocumented => "".into(),
14066            CompletionDocumentation::SingleLine(s) => s.clone(),
14067            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
14068            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
14069            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
14070                single_line.clone()
14071            }
14072        }
14073    }
14074}
14075
14076impl From<lsp::Documentation> for CompletionDocumentation {
14077    fn from(docs: lsp::Documentation) -> Self {
14078        match docs {
14079            lsp::Documentation::String(text) => {
14080                if text.lines().count() <= 1 {
14081                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
14082                } else {
14083                    CompletionDocumentation::MultiLinePlainText(text.into())
14084                }
14085            }
14086
14087            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
14088                lsp::MarkupKind::PlainText => {
14089                    if value.lines().count() <= 1 {
14090                        CompletionDocumentation::SingleLine(value.into())
14091                    } else {
14092                        CompletionDocumentation::MultiLinePlainText(value.into())
14093                    }
14094                }
14095
14096                lsp::MarkupKind::Markdown => {
14097                    CompletionDocumentation::MultiLineMarkdown(value.into())
14098                }
14099            },
14100        }
14101    }
14102}
14103
14104pub enum ResolvedHint {
14105    Resolved(InlayHint),
14106    Resolving(Shared<Task<()>>),
14107}
14108
14109pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
14110    glob.components()
14111        .take_while(|component| match component {
14112            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
14113            _ => true,
14114        })
14115        .collect()
14116}
14117
14118pub struct SshLspAdapter {
14119    name: LanguageServerName,
14120    binary: LanguageServerBinary,
14121    initialization_options: Option<String>,
14122    code_action_kinds: Option<Vec<CodeActionKind>>,
14123}
14124
14125impl SshLspAdapter {
14126    pub fn new(
14127        name: LanguageServerName,
14128        binary: LanguageServerBinary,
14129        initialization_options: Option<String>,
14130        code_action_kinds: Option<String>,
14131    ) -> Self {
14132        Self {
14133            name,
14134            binary,
14135            initialization_options,
14136            code_action_kinds: code_action_kinds
14137                .as_ref()
14138                .and_then(|c| serde_json::from_str(c).ok()),
14139        }
14140    }
14141}
14142
14143impl LspInstaller for SshLspAdapter {
14144    type BinaryVersion = ();
14145    async fn check_if_user_installed(
14146        &self,
14147        _: &dyn LspAdapterDelegate,
14148        _: Option<Toolchain>,
14149        _: &AsyncApp,
14150    ) -> Option<LanguageServerBinary> {
14151        Some(self.binary.clone())
14152    }
14153
14154    async fn cached_server_binary(
14155        &self,
14156        _: PathBuf,
14157        _: &dyn LspAdapterDelegate,
14158    ) -> Option<LanguageServerBinary> {
14159        None
14160    }
14161
14162    async fn fetch_latest_server_version(
14163        &self,
14164        _: &dyn LspAdapterDelegate,
14165        _: bool,
14166        _: &mut AsyncApp,
14167    ) -> Result<()> {
14168        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14169    }
14170
14171    async fn fetch_server_binary(
14172        &self,
14173        _: (),
14174        _: PathBuf,
14175        _: &dyn LspAdapterDelegate,
14176    ) -> Result<LanguageServerBinary> {
14177        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14178    }
14179}
14180
14181#[async_trait(?Send)]
14182impl LspAdapter for SshLspAdapter {
14183    fn name(&self) -> LanguageServerName {
14184        self.name.clone()
14185    }
14186
14187    async fn initialization_options(
14188        self: Arc<Self>,
14189        _: &Arc<dyn LspAdapterDelegate>,
14190        _: &mut AsyncApp,
14191    ) -> Result<Option<serde_json::Value>> {
14192        let Some(options) = &self.initialization_options else {
14193            return Ok(None);
14194        };
14195        let result = serde_json::from_str(options)?;
14196        Ok(result)
14197    }
14198
14199    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14200        self.code_action_kinds.clone()
14201    }
14202}
14203
14204pub fn language_server_settings<'a>(
14205    delegate: &'a dyn LspAdapterDelegate,
14206    language: &LanguageServerName,
14207    cx: &'a App,
14208) -> Option<&'a LspSettings> {
14209    language_server_settings_for(
14210        SettingsLocation {
14211            worktree_id: delegate.worktree_id(),
14212            path: RelPath::empty(),
14213        },
14214        language,
14215        cx,
14216    )
14217}
14218
14219pub fn language_server_settings_for<'a>(
14220    location: SettingsLocation<'a>,
14221    language: &LanguageServerName,
14222    cx: &'a App,
14223) -> Option<&'a LspSettings> {
14224    ProjectSettings::get(Some(location), cx).lsp.get(language)
14225}
14226
14227pub struct LocalLspAdapterDelegate {
14228    lsp_store: WeakEntity<LspStore>,
14229    worktree: worktree::Snapshot,
14230    fs: Arc<dyn Fs>,
14231    http_client: Arc<dyn HttpClient>,
14232    language_registry: Arc<LanguageRegistry>,
14233    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14234}
14235
14236impl LocalLspAdapterDelegate {
14237    pub fn new(
14238        language_registry: Arc<LanguageRegistry>,
14239        environment: &Entity<ProjectEnvironment>,
14240        lsp_store: WeakEntity<LspStore>,
14241        worktree: &Entity<Worktree>,
14242        http_client: Arc<dyn HttpClient>,
14243        fs: Arc<dyn Fs>,
14244        cx: &mut App,
14245    ) -> Arc<Self> {
14246        let load_shell_env_task =
14247            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14248
14249        Arc::new(Self {
14250            lsp_store,
14251            worktree: worktree.read(cx).snapshot(),
14252            fs,
14253            http_client,
14254            language_registry,
14255            load_shell_env_task,
14256        })
14257    }
14258
14259    pub fn from_local_lsp(
14260        local: &LocalLspStore,
14261        worktree: &Entity<Worktree>,
14262        cx: &mut App,
14263    ) -> Arc<Self> {
14264        Self::new(
14265            local.languages.clone(),
14266            &local.environment,
14267            local.weak.clone(),
14268            worktree,
14269            local.http_client.clone(),
14270            local.fs.clone(),
14271            cx,
14272        )
14273    }
14274}
14275
14276#[async_trait]
14277impl LspAdapterDelegate for LocalLspAdapterDelegate {
14278    fn show_notification(&self, message: &str, cx: &mut App) {
14279        self.lsp_store
14280            .update(cx, |_, cx| {
14281                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14282            })
14283            .ok();
14284    }
14285
14286    fn http_client(&self) -> Arc<dyn HttpClient> {
14287        self.http_client.clone()
14288    }
14289
14290    fn worktree_id(&self) -> WorktreeId {
14291        self.worktree.id()
14292    }
14293
14294    fn worktree_root_path(&self) -> &Path {
14295        self.worktree.abs_path().as_ref()
14296    }
14297
14298    fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
14299        self.worktree.resolve_relative_path(path)
14300    }
14301
14302    async fn shell_env(&self) -> HashMap<String, String> {
14303        let task = self.load_shell_env_task.clone();
14304        task.await.unwrap_or_default()
14305    }
14306
14307    async fn npm_package_installed_version(
14308        &self,
14309        package_name: &str,
14310    ) -> Result<Option<(PathBuf, Version)>> {
14311        let local_package_directory = self.worktree_root_path();
14312        let node_modules_directory = local_package_directory.join("node_modules");
14313
14314        if let Some(version) =
14315            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14316        {
14317            return Ok(Some((node_modules_directory, version)));
14318        }
14319        let Some(npm) = self.which("npm".as_ref()).await else {
14320            log::warn!(
14321                "Failed to find npm executable for {:?}",
14322                local_package_directory
14323            );
14324            return Ok(None);
14325        };
14326
14327        let env = self.shell_env().await;
14328        let output = util::command::new_command(&npm)
14329            .args(["root", "-g"])
14330            .envs(env)
14331            .current_dir(local_package_directory)
14332            .output()
14333            .await?;
14334        let global_node_modules =
14335            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14336
14337        if let Some(version) =
14338            read_package_installed_version(global_node_modules.clone(), package_name).await?
14339        {
14340            return Ok(Some((global_node_modules, version)));
14341        }
14342        return Ok(None);
14343    }
14344
14345    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14346        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14347        if self.fs.is_file(&worktree_abs_path).await {
14348            worktree_abs_path.pop();
14349        }
14350
14351        let env = self.shell_env().await;
14352
14353        let shell_path = env.get("PATH").cloned();
14354
14355        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14356    }
14357
14358    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14359        let mut working_dir = self.worktree_root_path().to_path_buf();
14360        if self.fs.is_file(&working_dir).await {
14361            working_dir.pop();
14362        }
14363        let output = util::command::new_command(&command.path)
14364            .args(command.arguments)
14365            .envs(command.env.clone().unwrap_or_default())
14366            .current_dir(working_dir)
14367            .output()
14368            .await?;
14369
14370        anyhow::ensure!(
14371            output.status.success(),
14372            "{}, stdout: {:?}, stderr: {:?}",
14373            output.status,
14374            String::from_utf8_lossy(&output.stdout),
14375            String::from_utf8_lossy(&output.stderr)
14376        );
14377        Ok(())
14378    }
14379
14380    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14381        self.language_registry
14382            .update_lsp_binary_status(server_name, status);
14383    }
14384
14385    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14386        self.language_registry
14387            .all_lsp_adapters()
14388            .into_iter()
14389            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14390            .collect()
14391    }
14392
14393    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14394        let dir = self.language_registry.language_server_download_dir(name)?;
14395
14396        if !dir.exists() {
14397            smol::fs::create_dir_all(&dir)
14398                .await
14399                .context("failed to create container directory")
14400                .log_err()?;
14401        }
14402
14403        Some(dir)
14404    }
14405
14406    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14407        let entry = self
14408            .worktree
14409            .entry_for_path(path)
14410            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14411        let abs_path = self.worktree.absolutize(&entry.path);
14412        self.fs.load(&abs_path).await
14413    }
14414}
14415
14416async fn populate_labels_for_symbols(
14417    symbols: Vec<CoreSymbol>,
14418    language_registry: &Arc<LanguageRegistry>,
14419    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14420    output: &mut Vec<Symbol>,
14421) {
14422    #[allow(clippy::mutable_key_type)]
14423    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14424
14425    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14426    for symbol in symbols {
14427        let Some(file_name) = symbol.path.file_name() else {
14428            continue;
14429        };
14430        let language = language_registry
14431            .load_language_for_file_path(Path::new(file_name))
14432            .await
14433            .ok()
14434            .or_else(|| {
14435                unknown_paths.insert(file_name.into());
14436                None
14437            });
14438        symbols_by_language
14439            .entry(language)
14440            .or_default()
14441            .push(symbol);
14442    }
14443
14444    for unknown_path in unknown_paths {
14445        log::info!("no language found for symbol in file {unknown_path:?}");
14446    }
14447
14448    let mut label_params = Vec::new();
14449    for (language, mut symbols) in symbols_by_language {
14450        label_params.clear();
14451        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14452            name: mem::take(&mut symbol.name),
14453            kind: symbol.kind,
14454            container_name: symbol.container_name.take(),
14455        }));
14456
14457        let mut labels = Vec::new();
14458        if let Some(language) = language {
14459            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14460                language_registry
14461                    .lsp_adapters(&language.name())
14462                    .first()
14463                    .cloned()
14464            });
14465            if let Some(lsp_adapter) = lsp_adapter {
14466                labels = lsp_adapter
14467                    .labels_for_symbols(&label_params, &language)
14468                    .await
14469                    .log_err()
14470                    .unwrap_or_default();
14471            }
14472        }
14473
14474        for (
14475            (
14476                symbol,
14477                language::Symbol {
14478                    name,
14479                    container_name,
14480                    ..
14481                },
14482            ),
14483            label,
14484        ) in symbols
14485            .into_iter()
14486            .zip(label_params.drain(..))
14487            .zip(labels.into_iter().chain(iter::repeat(None)))
14488        {
14489            output.push(Symbol {
14490                language_server_name: symbol.language_server_name,
14491                source_worktree_id: symbol.source_worktree_id,
14492                source_language_server_id: symbol.source_language_server_id,
14493                path: symbol.path,
14494                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14495                name,
14496                kind: symbol.kind,
14497                range: symbol.range,
14498                container_name,
14499            });
14500        }
14501    }
14502}
14503
14504pub(crate) fn collapse_newlines(text: &str, separator: &str) -> String {
14505    text.lines()
14506        .map(|line| line.trim())
14507        .filter(|line| !line.is_empty())
14508        .join(separator)
14509}
14510
14511fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14512    match server.capabilities().text_document_sync.as_ref()? {
14513        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14514            // Server wants didSave but didn't specify includeText.
14515            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14516            // Server doesn't want didSave at all.
14517            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14518            // Server provided SaveOptions.
14519            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14520                Some(save_options.include_text.unwrap_or(false))
14521            }
14522        },
14523        // We do not have any save info. Kind affects didChange only.
14524        lsp::TextDocumentSyncCapability::Kind(_) => None,
14525    }
14526}
14527
14528/// Completion items are displayed in a `UniformList`.
14529/// Usually, those items are single-line strings, but in LSP responses,
14530/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14531/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14532/// 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,
14533/// breaking the completions menu presentation.
14534///
14535/// 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.
14536pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14537    let mut new_text = String::with_capacity(label.text.len());
14538    let mut offset_map = vec![0; label.text.len() + 1];
14539    let mut last_char_was_space = false;
14540    let mut new_idx = 0;
14541    let chars = label.text.char_indices().fuse();
14542    let mut newlines_removed = false;
14543
14544    for (idx, c) in chars {
14545        offset_map[idx] = new_idx;
14546
14547        match c {
14548            '\n' if last_char_was_space => {
14549                newlines_removed = true;
14550            }
14551            '\t' | ' ' if last_char_was_space => {}
14552            '\n' if !last_char_was_space => {
14553                new_text.push(' ');
14554                new_idx += 1;
14555                last_char_was_space = true;
14556                newlines_removed = true;
14557            }
14558            ' ' | '\t' => {
14559                new_text.push(' ');
14560                new_idx += 1;
14561                last_char_was_space = true;
14562            }
14563            _ => {
14564                new_text.push(c);
14565                new_idx += c.len_utf8();
14566                last_char_was_space = false;
14567            }
14568        }
14569    }
14570    offset_map[label.text.len()] = new_idx;
14571
14572    // Only modify the label if newlines were removed.
14573    if !newlines_removed {
14574        return;
14575    }
14576
14577    let last_index = new_idx;
14578    let mut run_ranges_errors = Vec::new();
14579    label.runs.retain_mut(|(range, _)| {
14580        match offset_map.get(range.start) {
14581            Some(&start) => range.start = start,
14582            None => {
14583                run_ranges_errors.push(range.clone());
14584                return false;
14585            }
14586        }
14587
14588        match offset_map.get(range.end) {
14589            Some(&end) => range.end = end,
14590            None => {
14591                run_ranges_errors.push(range.clone());
14592                range.end = last_index;
14593            }
14594        }
14595        true
14596    });
14597    if !run_ranges_errors.is_empty() {
14598        log::error!(
14599            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14600            label.text
14601        );
14602    }
14603
14604    let mut wrong_filter_range = None;
14605    if label.filter_range == (0..label.text.len()) {
14606        label.filter_range = 0..new_text.len();
14607    } else {
14608        let mut original_filter_range = Some(label.filter_range.clone());
14609        match offset_map.get(label.filter_range.start) {
14610            Some(&start) => label.filter_range.start = start,
14611            None => {
14612                wrong_filter_range = original_filter_range.take();
14613                label.filter_range.start = last_index;
14614            }
14615        }
14616
14617        match offset_map.get(label.filter_range.end) {
14618            Some(&end) => label.filter_range.end = end,
14619            None => {
14620                wrong_filter_range = original_filter_range.take();
14621                label.filter_range.end = last_index;
14622            }
14623        }
14624    }
14625    if let Some(wrong_filter_range) = wrong_filter_range {
14626        log::error!(
14627            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14628            label.text
14629        );
14630    }
14631
14632    label.text = new_text;
14633}
14634
14635/// Apply edits to the buffer that will become part of the formatting transaction.
14636/// Fails if the buffer has been edited since the start of that transaction.
14637fn extend_formatting_transaction(
14638    buffer: &FormattableBuffer,
14639    formatting_transaction_id: text::TransactionId,
14640    cx: &mut AsyncApp,
14641    operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
14642) -> anyhow::Result<()> {
14643    buffer.handle.update(cx, |buffer, cx| {
14644        let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
14645        if last_transaction_id != Some(formatting_transaction_id) {
14646            anyhow::bail!("Buffer edited while formatting. Aborting")
14647        }
14648        buffer.start_transaction();
14649        operation(buffer, cx);
14650        if let Some(transaction_id) = buffer.end_transaction(cx) {
14651            buffer.merge_transactions(transaction_id, formatting_transaction_id);
14652        }
14653        Ok(())
14654    })
14655}