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                })
 4418                .detach()
 4419            }
 4420            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4421            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4422                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4423            }
 4424            WorktreeStoreEvent::WorktreeUpdatedEntries(worktree_id, changes) => {
 4425                self.invalidate_diagnostic_summaries_for_removed_entries(*worktree_id, changes, cx);
 4426            }
 4427            WorktreeStoreEvent::WorktreeReleased(..)
 4428            | WorktreeStoreEvent::WorktreeOrderChanged
 4429            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4430            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4431        }
 4432    }
 4433
 4434    fn on_prettier_store_event(
 4435        &mut self,
 4436        _: Entity<PrettierStore>,
 4437        event: &PrettierStoreEvent,
 4438        cx: &mut Context<Self>,
 4439    ) {
 4440        match event {
 4441            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4442                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4443            }
 4444            PrettierStoreEvent::LanguageServerAdded {
 4445                new_server_id,
 4446                name,
 4447                prettier_server,
 4448            } => {
 4449                self.register_supplementary_language_server(
 4450                    *new_server_id,
 4451                    name.clone(),
 4452                    prettier_server.clone(),
 4453                    cx,
 4454                );
 4455            }
 4456        }
 4457    }
 4458
 4459    fn on_toolchain_store_event(
 4460        &mut self,
 4461        _: Entity<LocalToolchainStore>,
 4462        event: &ToolchainStoreEvent,
 4463        _: &mut Context<Self>,
 4464    ) {
 4465        if let ToolchainStoreEvent::ToolchainActivated = event {
 4466            self.request_workspace_config_refresh()
 4467        }
 4468    }
 4469
 4470    fn request_workspace_config_refresh(&mut self) {
 4471        *self._maintain_workspace_config.1.borrow_mut() = ();
 4472    }
 4473
 4474    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4475        self.as_local().map(|local| local.prettier_store.clone())
 4476    }
 4477
 4478    fn on_buffer_event(
 4479        &mut self,
 4480        buffer: Entity<Buffer>,
 4481        event: &language::BufferEvent,
 4482        cx: &mut Context<Self>,
 4483    ) {
 4484        match event {
 4485            language::BufferEvent::Edited { .. } => {
 4486                self.on_buffer_edited(buffer, cx);
 4487            }
 4488
 4489            language::BufferEvent::Saved => {
 4490                self.on_buffer_saved(buffer, cx);
 4491            }
 4492
 4493            language::BufferEvent::Reloaded => {
 4494                self.on_buffer_reloaded(buffer, cx);
 4495            }
 4496
 4497            _ => {}
 4498        }
 4499    }
 4500
 4501    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4502        buffer
 4503            .read(cx)
 4504            .set_language_registry(self.languages.clone());
 4505
 4506        cx.subscribe(buffer, |this, buffer, event, cx| {
 4507            this.on_buffer_event(buffer, event, cx);
 4508        })
 4509        .detach();
 4510
 4511        self.parse_modeline(buffer, cx);
 4512        self.detect_language_for_buffer(buffer, cx);
 4513        if let Some(local) = self.as_local_mut() {
 4514            local.initialize_buffer(buffer, cx);
 4515        }
 4516
 4517        Ok(())
 4518    }
 4519
 4520    pub fn refresh_background_diagnostics_for_buffers(
 4521        &mut self,
 4522        buffers: HashSet<BufferId>,
 4523        cx: &mut Context<Self>,
 4524    ) -> Shared<Task<()>> {
 4525        let Some(local) = self.as_local_mut() else {
 4526            return Task::ready(()).shared();
 4527        };
 4528        for buffer in buffers {
 4529            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4530                local.buffers_to_refresh_queue.push_back(buffer);
 4531                if local.buffers_to_refresh_queue.len() == 1 {
 4532                    local._background_diagnostics_worker =
 4533                        Self::background_diagnostics_worker(cx).shared();
 4534                }
 4535            }
 4536        }
 4537
 4538        local._background_diagnostics_worker.clone()
 4539    }
 4540
 4541    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4542        let buffer_store = self.buffer_store.clone();
 4543        let local = self.as_local_mut()?;
 4544        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4545            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4546            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4547                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4548            }
 4549        }
 4550        None
 4551    }
 4552
 4553    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4554        cx.spawn(async move |this, cx| {
 4555            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4556                task.await.log_err();
 4557            }
 4558        })
 4559    }
 4560
 4561    fn on_buffer_reloaded(&mut self, buffer: Entity<Buffer>, cx: &mut Context<Self>) {
 4562        if self.parse_modeline(&buffer, cx) {
 4563            self.detect_language_for_buffer(&buffer, cx);
 4564        }
 4565
 4566        let buffer_id = buffer.read(cx).remote_id();
 4567        let task = self.pull_diagnostics_for_buffer(buffer, cx);
 4568        self.buffer_reload_tasks.insert(buffer_id, task);
 4569    }
 4570
 4571    pub(crate) fn register_buffer_with_language_servers(
 4572        &mut self,
 4573        buffer: &Entity<Buffer>,
 4574        only_register_servers: HashSet<LanguageServerSelector>,
 4575        ignore_refcounts: bool,
 4576        cx: &mut Context<Self>,
 4577    ) -> OpenLspBufferHandle {
 4578        let buffer_id = buffer.read(cx).remote_id();
 4579        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4580        if let Some(local) = self.as_local_mut() {
 4581            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4582            if !ignore_refcounts {
 4583                *refcount += 1;
 4584            }
 4585
 4586            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4587            // 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
 4588            // 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
 4589            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4590            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4591                return handle;
 4592            };
 4593            if !file.is_local() {
 4594                return handle;
 4595            }
 4596
 4597            if ignore_refcounts || *refcount == 1 {
 4598                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4599            }
 4600            if !ignore_refcounts {
 4601                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4602                    let refcount = {
 4603                        let local = lsp_store.as_local_mut().unwrap();
 4604                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4605                            debug_panic!("bad refcounting");
 4606                            return;
 4607                        };
 4608
 4609                        *refcount -= 1;
 4610                        *refcount
 4611                    };
 4612                    if refcount == 0 {
 4613                        lsp_store.lsp_data.remove(&buffer_id);
 4614                        lsp_store.buffer_reload_tasks.remove(&buffer_id);
 4615                        let local = lsp_store.as_local_mut().unwrap();
 4616                        local.registered_buffers.remove(&buffer_id);
 4617
 4618                        local.buffers_opened_in_servers.remove(&buffer_id);
 4619                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4620                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4621
 4622                            let buffer_abs_path = file.abs_path(cx);
 4623                            for (_, buffer_pull_diagnostics_result_ids) in
 4624                                &mut local.buffer_pull_diagnostics_result_ids
 4625                            {
 4626                                buffer_pull_diagnostics_result_ids.retain(
 4627                                    |_, buffer_result_ids| {
 4628                                        buffer_result_ids.remove(&buffer_abs_path);
 4629                                        !buffer_result_ids.is_empty()
 4630                                    },
 4631                                );
 4632                            }
 4633
 4634                            let diagnostic_updates = local
 4635                                .language_servers
 4636                                .keys()
 4637                                .cloned()
 4638                                .map(|server_id| DocumentDiagnosticsUpdate {
 4639                                    diagnostics: DocumentDiagnostics {
 4640                                        document_abs_path: buffer_abs_path.clone(),
 4641                                        version: None,
 4642                                        diagnostics: Vec::new(),
 4643                                    },
 4644                                    result_id: None,
 4645                                    registration_id: None,
 4646                                    server_id,
 4647                                    disk_based_sources: Cow::Borrowed(&[]),
 4648                                })
 4649                                .collect::<Vec<_>>();
 4650
 4651                            lsp_store
 4652                                .merge_diagnostic_entries(
 4653                                    diagnostic_updates,
 4654                                    |_, diagnostic, _| {
 4655                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4656                                    },
 4657                                    cx,
 4658                                )
 4659                                .context("Clearing diagnostics for the closed buffer")
 4660                                .log_err();
 4661                        }
 4662                    }
 4663                })
 4664                .detach();
 4665            }
 4666        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4667            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4668            cx.background_spawn(async move {
 4669                upstream_client
 4670                    .request(proto::RegisterBufferWithLanguageServers {
 4671                        project_id: upstream_project_id,
 4672                        buffer_id,
 4673                        only_servers: only_register_servers
 4674                            .into_iter()
 4675                            .map(|selector| {
 4676                                let selector = match selector {
 4677                                    LanguageServerSelector::Id(language_server_id) => {
 4678                                        proto::language_server_selector::Selector::ServerId(
 4679                                            language_server_id.to_proto(),
 4680                                        )
 4681                                    }
 4682                                    LanguageServerSelector::Name(language_server_name) => {
 4683                                        proto::language_server_selector::Selector::Name(
 4684                                            language_server_name.to_string(),
 4685                                        )
 4686                                    }
 4687                                };
 4688                                proto::LanguageServerSelector {
 4689                                    selector: Some(selector),
 4690                                }
 4691                            })
 4692                            .collect(),
 4693                    })
 4694                    .await
 4695            })
 4696            .detach();
 4697        } else {
 4698            // Our remote connection got closed
 4699        }
 4700        handle
 4701    }
 4702
 4703    fn maintain_buffer_languages(
 4704        languages: Arc<LanguageRegistry>,
 4705        cx: &mut Context<Self>,
 4706    ) -> Task<()> {
 4707        let mut subscription = languages.subscribe();
 4708        let mut prev_reload_count = languages.reload_count();
 4709        cx.spawn(async move |this, cx| {
 4710            while let Some(()) = subscription.next().await {
 4711                if let Some(this) = this.upgrade() {
 4712                    // If the language registry has been reloaded, then remove and
 4713                    // re-assign the languages on all open buffers.
 4714                    let reload_count = languages.reload_count();
 4715                    if reload_count > prev_reload_count {
 4716                        prev_reload_count = reload_count;
 4717                        this.update(cx, |this, cx| {
 4718                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4719                                for buffer in buffer_store.buffers() {
 4720                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4721                                    {
 4722                                        buffer.update(cx, |buffer, cx| {
 4723                                            buffer.set_language_async(None, cx)
 4724                                        });
 4725                                        if let Some(local) = this.as_local_mut() {
 4726                                            local.reset_buffer(&buffer, &f, cx);
 4727
 4728                                            if local
 4729                                                .registered_buffers
 4730                                                .contains_key(&buffer.read(cx).remote_id())
 4731                                                && let Some(file_url) =
 4732                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4733                                            {
 4734                                                local.unregister_buffer_from_language_servers(
 4735                                                    &buffer, &file_url, cx,
 4736                                                );
 4737                                            }
 4738                                        }
 4739                                    }
 4740                                }
 4741                            });
 4742                        });
 4743                    }
 4744
 4745                    this.update(cx, |this, cx| {
 4746                        let mut plain_text_buffers = Vec::new();
 4747                        let mut buffers_with_unknown_injections = Vec::new();
 4748                        for handle in this.buffer_store.read(cx).buffers() {
 4749                            let buffer = handle.read(cx);
 4750                            if buffer.language().is_none()
 4751                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4752                            {
 4753                                plain_text_buffers.push(handle);
 4754                            } else if buffer.contains_unknown_injections() {
 4755                                buffers_with_unknown_injections.push(handle);
 4756                            }
 4757                        }
 4758
 4759                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4760                        // and reused later in the invisible worktrees.
 4761                        plain_text_buffers.sort_by_key(|buffer| {
 4762                            Reverse(
 4763                                File::from_dyn(buffer.read(cx).file())
 4764                                    .map(|file| file.worktree.read(cx).is_visible()),
 4765                            )
 4766                        });
 4767
 4768                        for buffer in plain_text_buffers {
 4769                            this.detect_language_for_buffer(&buffer, cx);
 4770                            if let Some(local) = this.as_local_mut() {
 4771                                local.initialize_buffer(&buffer, cx);
 4772                                if local
 4773                                    .registered_buffers
 4774                                    .contains_key(&buffer.read(cx).remote_id())
 4775                                {
 4776                                    local.register_buffer_with_language_servers(
 4777                                        &buffer,
 4778                                        HashSet::default(),
 4779                                        cx,
 4780                                    );
 4781                                }
 4782                            }
 4783                        }
 4784
 4785                        for buffer in buffers_with_unknown_injections {
 4786                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4787                        }
 4788                    });
 4789                }
 4790            }
 4791        })
 4792    }
 4793
 4794    fn parse_modeline(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<Self>) -> bool {
 4795        let buffer = buffer_handle.read(cx);
 4796        let content = buffer.as_rope();
 4797
 4798        let modeline_settings = {
 4799            let settings_store = cx.global::<SettingsStore>();
 4800            let modeline_lines = settings_store
 4801                .raw_user_settings()
 4802                .and_then(|s| s.content.modeline_lines)
 4803                .or(settings_store.raw_default_settings().modeline_lines)
 4804                .unwrap_or(5);
 4805
 4806            const MAX_MODELINE_BYTES: usize = 1024;
 4807
 4808            let first_bytes =
 4809                content.clip_offset(content.len().min(MAX_MODELINE_BYTES), Bias::Left);
 4810            let mut first_lines = Vec::new();
 4811            let mut lines = content.chunks_in_range(0..first_bytes).lines();
 4812            for _ in 0..modeline_lines {
 4813                if let Some(line) = lines.next() {
 4814                    first_lines.push(line.to_string());
 4815                } else {
 4816                    break;
 4817                }
 4818            }
 4819            let first_lines_ref: Vec<_> = first_lines.iter().map(|line| line.as_str()).collect();
 4820
 4821            let last_start =
 4822                content.clip_offset(content.len().saturating_sub(MAX_MODELINE_BYTES), Bias::Left);
 4823            let mut last_lines = Vec::new();
 4824            let mut lines = content
 4825                .reversed_chunks_in_range(last_start..content.len())
 4826                .lines();
 4827            for _ in 0..modeline_lines {
 4828                if let Some(line) = lines.next() {
 4829                    last_lines.push(line.to_string());
 4830                } else {
 4831                    break;
 4832                }
 4833            }
 4834            let last_lines_ref: Vec<_> =
 4835                last_lines.iter().rev().map(|line| line.as_str()).collect();
 4836            modeline::parse_modeline(&first_lines_ref, &last_lines_ref)
 4837        };
 4838
 4839        log::debug!("Parsed modeline settings: {:?}", modeline_settings);
 4840
 4841        buffer_handle.update(cx, |buffer, _cx| buffer.set_modeline(modeline_settings))
 4842    }
 4843
 4844    fn detect_language_for_buffer(
 4845        &mut self,
 4846        buffer_handle: &Entity<Buffer>,
 4847        cx: &mut Context<Self>,
 4848    ) -> Option<language::AvailableLanguage> {
 4849        // If the buffer has a language, set it and start the language server if we haven't already.
 4850        let buffer = buffer_handle.read(cx);
 4851        let file = buffer.file()?;
 4852        let content = buffer.as_rope();
 4853        let modeline_settings = buffer.modeline().map(Arc::as_ref);
 4854
 4855        let available_language = if let Some(ModelineSettings {
 4856            mode: Some(mode_name),
 4857            ..
 4858        }) = modeline_settings
 4859        {
 4860            self.languages
 4861                .available_language_for_modeline_name(mode_name)
 4862        } else {
 4863            self.languages.language_for_file(file, Some(content), cx)
 4864        };
 4865        if let Some(available_language) = &available_language {
 4866            if let Some(Ok(Ok(new_language))) = self
 4867                .languages
 4868                .load_language(available_language)
 4869                .now_or_never()
 4870            {
 4871                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4872            }
 4873        } else {
 4874            cx.emit(LspStoreEvent::LanguageDetected {
 4875                buffer: buffer_handle.clone(),
 4876                new_language: None,
 4877            });
 4878        }
 4879
 4880        available_language
 4881    }
 4882
 4883    pub(crate) fn set_language_for_buffer(
 4884        &mut self,
 4885        buffer_entity: &Entity<Buffer>,
 4886        new_language: Arc<Language>,
 4887        cx: &mut Context<Self>,
 4888    ) {
 4889        let buffer = buffer_entity.read(cx);
 4890        let buffer_file = buffer.file().cloned();
 4891        let buffer_id = buffer.remote_id();
 4892        if let Some(local_store) = self.as_local_mut()
 4893            && local_store.registered_buffers.contains_key(&buffer_id)
 4894            && let Some(abs_path) =
 4895                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4896            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4897        {
 4898            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4899        }
 4900        buffer_entity.update(cx, |buffer, cx| {
 4901            if buffer
 4902                .language()
 4903                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4904            {
 4905                buffer.set_language_async(Some(new_language.clone()), cx);
 4906            }
 4907        });
 4908
 4909        let settings = LanguageSettings::resolve(
 4910            Some(&buffer_entity.read(cx)),
 4911            Some(&new_language.name()),
 4912            cx,
 4913        )
 4914        .into_owned();
 4915        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4916
 4917        let worktree_id = if let Some(file) = buffer_file {
 4918            let worktree = file.worktree.clone();
 4919
 4920            if let Some(local) = self.as_local_mut()
 4921                && local.registered_buffers.contains_key(&buffer_id)
 4922            {
 4923                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4924            }
 4925            Some(worktree.read(cx).id())
 4926        } else {
 4927            None
 4928        };
 4929
 4930        if settings.prettier.allowed
 4931            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4932        {
 4933            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4934            if let Some(prettier_store) = prettier_store {
 4935                prettier_store.update(cx, |prettier_store, cx| {
 4936                    prettier_store.install_default_prettier(
 4937                        worktree_id,
 4938                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4939                        cx,
 4940                    )
 4941                })
 4942            }
 4943        }
 4944
 4945        cx.emit(LspStoreEvent::LanguageDetected {
 4946            buffer: buffer_entity.clone(),
 4947            new_language: Some(new_language),
 4948        })
 4949    }
 4950
 4951    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4952        self.buffer_store.clone()
 4953    }
 4954
 4955    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4956        self.active_entry = active_entry;
 4957    }
 4958
 4959    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4960        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4961            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4962        {
 4963            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4964                summaries
 4965                    .iter()
 4966                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4967            });
 4968            if let Some(summary) = summaries.next() {
 4969                client
 4970                    .send(proto::UpdateDiagnosticSummary {
 4971                        project_id: downstream_project_id,
 4972                        worktree_id: worktree.id().to_proto(),
 4973                        summary: Some(summary),
 4974                        more_summaries: summaries.collect(),
 4975                    })
 4976                    .log_err();
 4977            }
 4978        }
 4979    }
 4980
 4981    fn is_capable_for_proto_request<R>(
 4982        &self,
 4983        buffer: &Entity<Buffer>,
 4984        request: &R,
 4985        cx: &App,
 4986    ) -> bool
 4987    where
 4988        R: LspCommand,
 4989    {
 4990        self.check_if_capable_for_proto_request(
 4991            buffer,
 4992            |capabilities| {
 4993                request.check_capabilities(AdapterServerCapabilities {
 4994                    server_capabilities: capabilities.clone(),
 4995                    code_action_kinds: None,
 4996                })
 4997            },
 4998            cx,
 4999        )
 5000    }
 5001
 5002    fn check_if_capable_for_proto_request<F>(
 5003        &self,
 5004        buffer: &Entity<Buffer>,
 5005        check: F,
 5006        cx: &App,
 5007    ) -> bool
 5008    where
 5009        F: FnMut(&lsp::ServerCapabilities) -> bool,
 5010    {
 5011        let Some(language) = buffer.read(cx).language().cloned() else {
 5012            return false;
 5013        };
 5014        let registered_language_servers = self
 5015            .languages
 5016            .lsp_adapters(&language.name())
 5017            .into_iter()
 5018            .map(|lsp_adapter| lsp_adapter.name())
 5019            .collect::<HashSet<_>>();
 5020        self.language_server_statuses
 5021            .iter()
 5022            .filter_map(|(server_id, server_status)| {
 5023                // Include servers that are either registered for this language OR
 5024                // available to be loaded (for SSH remote mode where adapters like
 5025                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 5026                // but only loaded on the server side)
 5027                let is_relevant = registered_language_servers.contains(&server_status.name)
 5028                    || self.languages.is_lsp_adapter_available(&server_status.name);
 5029                is_relevant.then_some(server_id)
 5030            })
 5031            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 5032            .any(check)
 5033    }
 5034
 5035    fn all_capable_for_proto_request<F>(
 5036        &self,
 5037        buffer: &Entity<Buffer>,
 5038        mut check: F,
 5039        cx: &App,
 5040    ) -> Vec<(lsp::LanguageServerId, lsp::LanguageServerName)>
 5041    where
 5042        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 5043    {
 5044        let Some(language) = buffer.read(cx).language().cloned() else {
 5045            return Vec::default();
 5046        };
 5047        let registered_language_servers = self
 5048            .languages
 5049            .lsp_adapters(&language.name())
 5050            .into_iter()
 5051            .map(|lsp_adapter| lsp_adapter.name())
 5052            .collect::<HashSet<_>>();
 5053        self.language_server_statuses
 5054            .iter()
 5055            .filter_map(|(server_id, server_status)| {
 5056                // Include servers that are either registered for this language OR
 5057                // available to be loaded (for SSH remote mode where adapters like
 5058                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 5059                // but only loaded on the server side)
 5060                let is_relevant = registered_language_servers.contains(&server_status.name)
 5061                    || self.languages.is_lsp_adapter_available(&server_status.name);
 5062                is_relevant.then_some((server_id, &server_status.name))
 5063            })
 5064            .filter_map(|(server_id, server_name)| {
 5065                self.lsp_server_capabilities
 5066                    .get(server_id)
 5067                    .map(|c| (server_id, server_name, c))
 5068            })
 5069            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 5070            .map(|(server_id, server_name, _)| (*server_id, server_name.clone()))
 5071            .collect()
 5072    }
 5073
 5074    pub fn request_lsp<R>(
 5075        &mut self,
 5076        buffer: Entity<Buffer>,
 5077        server: LanguageServerToQuery,
 5078        request: R,
 5079        cx: &mut Context<Self>,
 5080    ) -> Task<Result<R::Response>>
 5081    where
 5082        R: LspCommand,
 5083        <R::LspRequest as lsp::request::Request>::Result: Send,
 5084        <R::LspRequest as lsp::request::Request>::Params: Send,
 5085    {
 5086        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 5087            return self.send_lsp_proto_request(
 5088                buffer,
 5089                upstream_client,
 5090                upstream_project_id,
 5091                request,
 5092                cx,
 5093            );
 5094        }
 5095
 5096        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 5097            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 5098                local
 5099                    .language_servers_for_buffer(buffer, cx)
 5100                    .find(|(_, server)| {
 5101                        request.check_capabilities(server.adapter_server_capabilities())
 5102                    })
 5103                    .map(|(_, server)| server.clone())
 5104            }),
 5105            LanguageServerToQuery::Other(id) => self
 5106                .language_server_for_local_buffer(buffer, id, cx)
 5107                .and_then(|(_, server)| {
 5108                    request
 5109                        .check_capabilities(server.adapter_server_capabilities())
 5110                        .then(|| Arc::clone(server))
 5111                }),
 5112        }) else {
 5113            return Task::ready(Ok(Default::default()));
 5114        };
 5115
 5116        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 5117
 5118        let Some(file) = file else {
 5119            return Task::ready(Ok(Default::default()));
 5120        };
 5121
 5122        let lsp_params = match request.to_lsp_params_or_response(
 5123            &file.abs_path(cx),
 5124            buffer.read(cx),
 5125            &language_server,
 5126            cx,
 5127        ) {
 5128            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 5129            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 5130            Err(err) => {
 5131                let message = format!(
 5132                    "{} via {} failed: {}",
 5133                    request.display_name(),
 5134                    language_server.name(),
 5135                    err
 5136                );
 5137                // rust-analyzer likes to error with this when its still loading up
 5138                if !message.ends_with("content modified") {
 5139                    log::warn!("{message}");
 5140                }
 5141                return Task::ready(Err(anyhow!(message)));
 5142            }
 5143        };
 5144
 5145        let status = request.status();
 5146        let request_timeout = ProjectSettings::get_global(cx)
 5147            .global_lsp_settings
 5148            .get_request_timeout();
 5149
 5150        cx.spawn(async move |this, cx| {
 5151            let lsp_request = language_server.request::<R::LspRequest>(lsp_params, request_timeout);
 5152
 5153            let id = lsp_request.id();
 5154            let _cleanup = if status.is_some() {
 5155                cx.update(|cx| {
 5156                    this.update(cx, |this, cx| {
 5157                        this.on_lsp_work_start(
 5158                            language_server.server_id(),
 5159                            ProgressToken::Number(id),
 5160                            LanguageServerProgress {
 5161                                is_disk_based_diagnostics_progress: false,
 5162                                is_cancellable: false,
 5163                                title: None,
 5164                                message: status.clone(),
 5165                                percentage: None,
 5166                                last_update_at: cx.background_executor().now(),
 5167                            },
 5168                            cx,
 5169                        );
 5170                    })
 5171                })
 5172                .log_err();
 5173
 5174                Some(defer(|| {
 5175                    cx.update(|cx| {
 5176                        this.update(cx, |this, cx| {
 5177                            this.on_lsp_work_end(
 5178                                language_server.server_id(),
 5179                                ProgressToken::Number(id),
 5180                                cx,
 5181                            );
 5182                        })
 5183                    })
 5184                    .log_err();
 5185                }))
 5186            } else {
 5187                None
 5188            };
 5189
 5190            let result = lsp_request.await.into_response();
 5191
 5192            let response = result.map_err(|err| {
 5193                let message = format!(
 5194                    "{} via {} failed: {}",
 5195                    request.display_name(),
 5196                    language_server.name(),
 5197                    err
 5198                );
 5199                // rust-analyzer likes to error with this when its still loading up
 5200                if !message.ends_with("content modified") {
 5201                    log::warn!("{message}");
 5202                }
 5203                anyhow::anyhow!(message)
 5204            })?;
 5205
 5206            request
 5207                .response_from_lsp(
 5208                    response,
 5209                    this.upgrade().context("no app context")?,
 5210                    buffer,
 5211                    language_server.server_id(),
 5212                    cx.clone(),
 5213                )
 5214                .await
 5215        })
 5216    }
 5217
 5218    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 5219        let mut language_formatters_to_check = Vec::new();
 5220        for buffer in self.buffer_store.read(cx).buffers() {
 5221            let buffer = buffer.read(cx);
 5222            let settings = LanguageSettings::for_buffer(buffer, cx);
 5223            if buffer.language().is_some() {
 5224                let buffer_file = File::from_dyn(buffer.file());
 5225                language_formatters_to_check.push((
 5226                    buffer_file.map(|f| f.worktree_id(cx)),
 5227                    settings.into_owned(),
 5228                ));
 5229            }
 5230        }
 5231
 5232        self.request_workspace_config_refresh();
 5233
 5234        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 5235            prettier_store.update(cx, |prettier_store, cx| {
 5236                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 5237            })
 5238        }
 5239
 5240        let new_semantic_token_rules = crate::project_settings::ProjectSettings::get_global(cx)
 5241            .global_lsp_settings
 5242            .semantic_token_rules
 5243            .clone();
 5244        self.semantic_token_config
 5245            .update_rules(new_semantic_token_rules);
 5246        // Always clear cached stylizers so that changes to language-specific
 5247        // semantic token rules (e.g. from extension install/uninstall) are
 5248        // picked up. Stylizers are recreated lazily, so this is cheap.
 5249        self.semantic_token_config.clear_stylizers();
 5250
 5251        let new_global_semantic_tokens_mode =
 5252            all_language_settings(None, cx).defaults.semantic_tokens;
 5253        if self
 5254            .semantic_token_config
 5255            .update_global_mode(new_global_semantic_tokens_mode)
 5256        {
 5257            self.restart_all_language_servers(cx);
 5258        }
 5259
 5260        cx.notify();
 5261    }
 5262
 5263    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 5264        let buffer_store = self.buffer_store.clone();
 5265        let Some(local) = self.as_local_mut() else {
 5266            return;
 5267        };
 5268        let mut adapters = BTreeMap::default();
 5269        let get_adapter = {
 5270            let languages = local.languages.clone();
 5271            let environment = local.environment.clone();
 5272            let weak = local.weak.clone();
 5273            let worktree_store = local.worktree_store.clone();
 5274            let http_client = local.http_client.clone();
 5275            let fs = local.fs.clone();
 5276            move |worktree_id, cx: &mut App| {
 5277                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 5278                Some(LocalLspAdapterDelegate::new(
 5279                    languages.clone(),
 5280                    &environment,
 5281                    weak.clone(),
 5282                    &worktree,
 5283                    http_client.clone(),
 5284                    fs.clone(),
 5285                    cx,
 5286                ))
 5287            }
 5288        };
 5289
 5290        let mut messages_to_report = Vec::new();
 5291        let (new_tree, to_stop) = {
 5292            let mut rebase = local.lsp_tree.rebase();
 5293            let buffers = buffer_store
 5294                .read(cx)
 5295                .buffers()
 5296                .filter_map(|buffer| {
 5297                    let raw_buffer = buffer.read(cx);
 5298                    if !local
 5299                        .registered_buffers
 5300                        .contains_key(&raw_buffer.remote_id())
 5301                    {
 5302                        return None;
 5303                    }
 5304                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5305                    let language = raw_buffer.language().cloned()?;
 5306                    Some((file, language, raw_buffer.remote_id()))
 5307                })
 5308                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5309            for (file, language, buffer_id) in buffers {
 5310                let worktree_id = file.worktree_id(cx);
 5311                let Some(worktree) = local
 5312                    .worktree_store
 5313                    .read(cx)
 5314                    .worktree_for_id(worktree_id, cx)
 5315                else {
 5316                    continue;
 5317                };
 5318
 5319                if let Some((_, apply)) = local.reuse_existing_language_server(
 5320                    rebase.server_tree(),
 5321                    &worktree,
 5322                    &language.name(),
 5323                    cx,
 5324                ) {
 5325                    (apply)(rebase.server_tree());
 5326                } else if let Some(lsp_delegate) = adapters
 5327                    .entry(worktree_id)
 5328                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5329                    .clone()
 5330                {
 5331                    let delegate =
 5332                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5333                    let path = file
 5334                        .path()
 5335                        .parent()
 5336                        .map(Arc::from)
 5337                        .unwrap_or_else(|| file.path().clone());
 5338                    let worktree_path = ProjectPath { worktree_id, path };
 5339                    let abs_path = file.abs_path(cx);
 5340                    let nodes = rebase
 5341                        .walk(
 5342                            worktree_path,
 5343                            language.name(),
 5344                            language.manifest(),
 5345                            delegate.clone(),
 5346                            cx,
 5347                        )
 5348                        .collect::<Vec<_>>();
 5349                    for node in nodes {
 5350                        let server_id = node.server_id_or_init(|disposition| {
 5351                            let path = &disposition.path;
 5352                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5353                            let key = LanguageServerSeed {
 5354                                worktree_id,
 5355                                name: disposition.server_name.clone(),
 5356                                settings: LanguageServerSeedSettings {
 5357                                    binary: disposition.settings.binary.clone(),
 5358                                    initialization_options: disposition
 5359                                        .settings
 5360                                        .initialization_options
 5361                                        .clone(),
 5362                                },
 5363                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5364                                    path.worktree_id,
 5365                                    &path.path,
 5366                                    language.name(),
 5367                                ),
 5368                            };
 5369                            local.language_server_ids.remove(&key);
 5370
 5371                            let server_id = local.get_or_insert_language_server(
 5372                                &worktree,
 5373                                lsp_delegate.clone(),
 5374                                disposition,
 5375                                &language.name(),
 5376                                cx,
 5377                            );
 5378                            if let Some(state) = local.language_servers.get(&server_id)
 5379                                && let Ok(uri) = uri
 5380                            {
 5381                                state.add_workspace_folder(uri);
 5382                            };
 5383                            server_id
 5384                        });
 5385
 5386                        if let Some(language_server_id) = server_id {
 5387                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5388                                language_server_id,
 5389                                name: node.name(),
 5390                                message:
 5391                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5392                                        proto::RegisteredForBuffer {
 5393                                            buffer_abs_path: abs_path
 5394                                                .to_string_lossy()
 5395                                                .into_owned(),
 5396                                            buffer_id: buffer_id.to_proto(),
 5397                                        },
 5398                                    ),
 5399                            });
 5400                        }
 5401                    }
 5402                } else {
 5403                    continue;
 5404                }
 5405            }
 5406            rebase.finish()
 5407        };
 5408        for message in messages_to_report {
 5409            cx.emit(message);
 5410        }
 5411        local.lsp_tree = new_tree;
 5412        for (id, _) in to_stop {
 5413            self.stop_local_language_server(id, cx).detach();
 5414        }
 5415    }
 5416
 5417    pub fn apply_code_action(
 5418        &self,
 5419        buffer_handle: Entity<Buffer>,
 5420        mut action: CodeAction,
 5421        push_to_history: bool,
 5422        cx: &mut Context<Self>,
 5423    ) -> Task<Result<ProjectTransaction>> {
 5424        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5425            let request = proto::ApplyCodeAction {
 5426                project_id,
 5427                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5428                action: Some(Self::serialize_code_action(&action)),
 5429            };
 5430            let buffer_store = self.buffer_store();
 5431            cx.spawn(async move |_, cx| {
 5432                let response = upstream_client
 5433                    .request(request)
 5434                    .await?
 5435                    .transaction
 5436                    .context("missing transaction")?;
 5437
 5438                buffer_store
 5439                    .update(cx, |buffer_store, cx| {
 5440                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5441                    })
 5442                    .await
 5443            })
 5444        } else if self.mode.is_local() {
 5445            let Some((_, lang_server, request_timeout)) = buffer_handle.update(cx, |buffer, cx| {
 5446                let request_timeout = ProjectSettings::get_global(cx)
 5447                    .global_lsp_settings
 5448                    .get_request_timeout();
 5449                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5450                    .map(|(adapter, server)| (adapter.clone(), server.clone(), request_timeout))
 5451            }) else {
 5452                return Task::ready(Ok(ProjectTransaction::default()));
 5453            };
 5454
 5455            cx.spawn(async move |this, cx| {
 5456                LocalLspStore::try_resolve_code_action(&lang_server, &mut action, request_timeout)
 5457                    .await
 5458                    .context("resolving a code action")?;
 5459                if let Some(edit) = action.lsp_action.edit()
 5460                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5461                        return LocalLspStore::deserialize_workspace_edit(
 5462                            this.upgrade().context("no app present")?,
 5463                            edit.clone(),
 5464                            push_to_history,
 5465
 5466                            lang_server.clone(),
 5467                            cx,
 5468                        )
 5469                        .await;
 5470                    }
 5471
 5472                let Some(command) = action.lsp_action.command() else {
 5473                    return Ok(ProjectTransaction::default())
 5474                };
 5475
 5476                let server_capabilities = lang_server.capabilities();
 5477                let available_commands = server_capabilities
 5478                    .execute_command_provider
 5479                    .as_ref()
 5480                    .map(|options| options.commands.as_slice())
 5481                    .unwrap_or_default();
 5482
 5483                if !available_commands.contains(&command.command) {
 5484                    log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5485                    return Ok(ProjectTransaction::default())
 5486                }
 5487
 5488                let request_timeout = cx.update(|app|
 5489                    ProjectSettings::get_global(app)
 5490                    .global_lsp_settings
 5491                    .get_request_timeout()
 5492                );
 5493
 5494                this.update(cx, |this, _| {
 5495                    this.as_local_mut()
 5496                        .unwrap()
 5497                        .last_workspace_edits_by_language_server
 5498                        .remove(&lang_server.server_id());
 5499                })?;
 5500
 5501                let _result = lang_server
 5502                    .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5503                        command: command.command.clone(),
 5504                        arguments: command.arguments.clone().unwrap_or_default(),
 5505                        ..lsp::ExecuteCommandParams::default()
 5506                    }, request_timeout)
 5507                    .await.into_response()
 5508                    .context("execute command")?;
 5509
 5510                return this.update(cx, |this, _| {
 5511                    this.as_local_mut()
 5512                        .unwrap()
 5513                        .last_workspace_edits_by_language_server
 5514                        .remove(&lang_server.server_id())
 5515                        .unwrap_or_default()
 5516                });
 5517            })
 5518        } else {
 5519            Task::ready(Err(anyhow!("no upstream client and not local")))
 5520        }
 5521    }
 5522
 5523    pub fn apply_code_action_kind(
 5524        &mut self,
 5525        buffers: HashSet<Entity<Buffer>>,
 5526        kind: CodeActionKind,
 5527        push_to_history: bool,
 5528        cx: &mut Context<Self>,
 5529    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5530        if self.as_local().is_some() {
 5531            cx.spawn(async move |lsp_store, cx| {
 5532                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5533                let result = LocalLspStore::execute_code_action_kind_locally(
 5534                    lsp_store.clone(),
 5535                    buffers,
 5536                    kind,
 5537                    push_to_history,
 5538                    cx,
 5539                )
 5540                .await;
 5541                lsp_store.update(cx, |lsp_store, _| {
 5542                    lsp_store.update_last_formatting_failure(&result);
 5543                })?;
 5544                result
 5545            })
 5546        } else if let Some((client, project_id)) = self.upstream_client() {
 5547            let buffer_store = self.buffer_store();
 5548            cx.spawn(async move |lsp_store, cx| {
 5549                let result = client
 5550                    .request(proto::ApplyCodeActionKind {
 5551                        project_id,
 5552                        kind: kind.as_str().to_owned(),
 5553                        buffer_ids: buffers
 5554                            .iter()
 5555                            .map(|buffer| {
 5556                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5557                            })
 5558                            .collect(),
 5559                    })
 5560                    .await
 5561                    .and_then(|result| result.transaction.context("missing transaction"));
 5562                lsp_store.update(cx, |lsp_store, _| {
 5563                    lsp_store.update_last_formatting_failure(&result);
 5564                })?;
 5565
 5566                let transaction_response = result?;
 5567                buffer_store
 5568                    .update(cx, |buffer_store, cx| {
 5569                        buffer_store.deserialize_project_transaction(
 5570                            transaction_response,
 5571                            push_to_history,
 5572                            cx,
 5573                        )
 5574                    })
 5575                    .await
 5576            })
 5577        } else {
 5578            Task::ready(Ok(ProjectTransaction::default()))
 5579        }
 5580    }
 5581
 5582    pub fn resolved_hint(
 5583        &mut self,
 5584        buffer_id: BufferId,
 5585        id: InlayId,
 5586        cx: &mut Context<Self>,
 5587    ) -> Option<ResolvedHint> {
 5588        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5589
 5590        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5591        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5592        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5593        let (server_id, resolve_data) = match &hint.resolve_state {
 5594            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5595            ResolveState::Resolving => {
 5596                return Some(ResolvedHint::Resolving(
 5597                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5598                ));
 5599            }
 5600            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5601        };
 5602
 5603        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5604        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5605        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5606            id,
 5607            cx.spawn(async move |lsp_store, cx| {
 5608                let resolved_hint = resolve_task.await;
 5609                lsp_store
 5610                    .update(cx, |lsp_store, _| {
 5611                        if let Some(old_inlay_hint) = lsp_store
 5612                            .lsp_data
 5613                            .get_mut(&buffer_id)
 5614                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5615                        {
 5616                            match resolved_hint {
 5617                                Ok(resolved_hint) => {
 5618                                    *old_inlay_hint = resolved_hint;
 5619                                }
 5620                                Err(e) => {
 5621                                    old_inlay_hint.resolve_state =
 5622                                        ResolveState::CanResolve(server_id, resolve_data);
 5623                                    log::error!("Inlay hint resolve failed: {e:#}");
 5624                                }
 5625                            }
 5626                        }
 5627                    })
 5628                    .ok();
 5629            })
 5630            .shared(),
 5631        );
 5632        debug_assert!(
 5633            previous_task.is_none(),
 5634            "Did not change hint's resolve state after spawning its resolve"
 5635        );
 5636        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5637        None
 5638    }
 5639
 5640    pub(crate) fn linked_edits(
 5641        &mut self,
 5642        buffer: &Entity<Buffer>,
 5643        position: Anchor,
 5644        cx: &mut Context<Self>,
 5645    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5646        let snapshot = buffer.read(cx).snapshot();
 5647        let scope = snapshot.language_scope_at(position);
 5648        let Some(server_id) = self
 5649            .as_local()
 5650            .and_then(|local| {
 5651                buffer.update(cx, |buffer, cx| {
 5652                    local
 5653                        .language_servers_for_buffer(buffer, cx)
 5654                        .filter(|(_, server)| {
 5655                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5656                        })
 5657                        .filter(|(adapter, _)| {
 5658                            scope
 5659                                .as_ref()
 5660                                .map(|scope| scope.language_allowed(&adapter.name))
 5661                                .unwrap_or(true)
 5662                        })
 5663                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5664                        .next()
 5665                })
 5666            })
 5667            .or_else(|| {
 5668                self.upstream_client()
 5669                    .is_some()
 5670                    .then_some(LanguageServerToQuery::FirstCapable)
 5671            })
 5672            .filter(|_| {
 5673                maybe!({
 5674                    buffer.read(cx).language_at(position)?;
 5675                    Some(
 5676                        LanguageSettings::for_buffer_at(&buffer.read(cx), position, cx)
 5677                            .linked_edits,
 5678                    )
 5679                }) == Some(true)
 5680            })
 5681        else {
 5682            return Task::ready(Ok(Vec::new()));
 5683        };
 5684
 5685        self.request_lsp(
 5686            buffer.clone(),
 5687            server_id,
 5688            LinkedEditingRange { position },
 5689            cx,
 5690        )
 5691    }
 5692
 5693    fn apply_on_type_formatting(
 5694        &mut self,
 5695        buffer: Entity<Buffer>,
 5696        position: Anchor,
 5697        trigger: String,
 5698        cx: &mut Context<Self>,
 5699    ) -> Task<Result<Option<Transaction>>> {
 5700        if let Some((client, project_id)) = self.upstream_client() {
 5701            if !self.check_if_capable_for_proto_request(
 5702                &buffer,
 5703                |capabilities| {
 5704                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5705                },
 5706                cx,
 5707            ) {
 5708                return Task::ready(Ok(None));
 5709            }
 5710            let request = proto::OnTypeFormatting {
 5711                project_id,
 5712                buffer_id: buffer.read(cx).remote_id().into(),
 5713                position: Some(serialize_anchor(&position)),
 5714                trigger,
 5715                version: serialize_version(&buffer.read(cx).version()),
 5716            };
 5717            cx.background_spawn(async move {
 5718                client
 5719                    .request(request)
 5720                    .await?
 5721                    .transaction
 5722                    .map(language::proto::deserialize_transaction)
 5723                    .transpose()
 5724            })
 5725        } else if let Some(local) = self.as_local_mut() {
 5726            let buffer_id = buffer.read(cx).remote_id();
 5727            local.buffers_being_formatted.insert(buffer_id);
 5728            cx.spawn(async move |this, cx| {
 5729                let _cleanup = defer({
 5730                    let this = this.clone();
 5731                    let mut cx = cx.clone();
 5732                    move || {
 5733                        this.update(&mut cx, |this, _| {
 5734                            if let Some(local) = this.as_local_mut() {
 5735                                local.buffers_being_formatted.remove(&buffer_id);
 5736                            }
 5737                        })
 5738                        .ok();
 5739                    }
 5740                });
 5741
 5742                buffer
 5743                    .update(cx, |buffer, _| {
 5744                        buffer.wait_for_edits(Some(position.timestamp()))
 5745                    })
 5746                    .await?;
 5747                this.update(cx, |this, cx| {
 5748                    let position = position.to_point_utf16(buffer.read(cx));
 5749                    this.on_type_format(buffer, position, trigger, false, cx)
 5750                })?
 5751                .await
 5752            })
 5753        } else {
 5754            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5755        }
 5756    }
 5757
 5758    pub fn on_type_format<T: ToPointUtf16>(
 5759        &mut self,
 5760        buffer: Entity<Buffer>,
 5761        position: T,
 5762        trigger: String,
 5763        push_to_history: bool,
 5764        cx: &mut Context<Self>,
 5765    ) -> Task<Result<Option<Transaction>>> {
 5766        let position = position.to_point_utf16(buffer.read(cx));
 5767        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5768    }
 5769
 5770    fn on_type_format_impl(
 5771        &mut self,
 5772        buffer: Entity<Buffer>,
 5773        position: PointUtf16,
 5774        trigger: String,
 5775        push_to_history: bool,
 5776        cx: &mut Context<Self>,
 5777    ) -> Task<Result<Option<Transaction>>> {
 5778        let options = buffer.update(cx, |buffer, cx| {
 5779            lsp_command::lsp_formatting_options(
 5780                LanguageSettings::for_buffer_at(buffer, position, cx).as_ref(),
 5781            )
 5782        });
 5783
 5784        cx.spawn(async move |this, cx| {
 5785            if let Some(waiter) =
 5786                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5787            {
 5788                waiter.await?;
 5789            }
 5790            cx.update(|cx| {
 5791                this.update(cx, |this, cx| {
 5792                    this.request_lsp(
 5793                        buffer.clone(),
 5794                        LanguageServerToQuery::FirstCapable,
 5795                        OnTypeFormatting {
 5796                            position,
 5797                            trigger,
 5798                            options,
 5799                            push_to_history,
 5800                        },
 5801                        cx,
 5802                    )
 5803                })
 5804            })?
 5805            .await
 5806        })
 5807    }
 5808
 5809    pub fn definitions(
 5810        &mut self,
 5811        buffer: &Entity<Buffer>,
 5812        position: PointUtf16,
 5813        cx: &mut Context<Self>,
 5814    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5815        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5816            let request = GetDefinitions { position };
 5817            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5818                return Task::ready(Ok(None));
 5819            }
 5820
 5821            let request_timeout = ProjectSettings::get_global(cx)
 5822                .global_lsp_settings
 5823                .get_request_timeout();
 5824
 5825            let request_task = upstream_client.request_lsp(
 5826                project_id,
 5827                None,
 5828                request_timeout,
 5829                cx.background_executor().clone(),
 5830                request.to_proto(project_id, buffer.read(cx)),
 5831            );
 5832            let buffer = buffer.clone();
 5833            cx.spawn(async move |weak_lsp_store, cx| {
 5834                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5835                    return Ok(None);
 5836                };
 5837                let Some(responses) = request_task.await? else {
 5838                    return Ok(None);
 5839                };
 5840                let actions = join_all(responses.payload.into_iter().map(|response| {
 5841                    GetDefinitions { position }.response_from_proto(
 5842                        response.response,
 5843                        lsp_store.clone(),
 5844                        buffer.clone(),
 5845                        cx.clone(),
 5846                    )
 5847                }))
 5848                .await;
 5849
 5850                Ok(Some(
 5851                    actions
 5852                        .into_iter()
 5853                        .collect::<Result<Vec<Vec<_>>>>()?
 5854                        .into_iter()
 5855                        .flatten()
 5856                        .dedup()
 5857                        .collect(),
 5858                ))
 5859            })
 5860        } else {
 5861            let definitions_task = self.request_multiple_lsp_locally(
 5862                buffer,
 5863                Some(position),
 5864                GetDefinitions { position },
 5865                cx,
 5866            );
 5867            cx.background_spawn(async move {
 5868                Ok(Some(
 5869                    definitions_task
 5870                        .await
 5871                        .into_iter()
 5872                        .flat_map(|(_, definitions)| definitions)
 5873                        .dedup()
 5874                        .collect(),
 5875                ))
 5876            })
 5877        }
 5878    }
 5879
 5880    pub fn declarations(
 5881        &mut self,
 5882        buffer: &Entity<Buffer>,
 5883        position: PointUtf16,
 5884        cx: &mut Context<Self>,
 5885    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5886        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5887            let request = GetDeclarations { position };
 5888            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5889                return Task::ready(Ok(None));
 5890            }
 5891            let request_timeout = ProjectSettings::get_global(cx)
 5892                .global_lsp_settings
 5893                .get_request_timeout();
 5894            let request_task = upstream_client.request_lsp(
 5895                project_id,
 5896                None,
 5897                request_timeout,
 5898                cx.background_executor().clone(),
 5899                request.to_proto(project_id, buffer.read(cx)),
 5900            );
 5901            let buffer = buffer.clone();
 5902            cx.spawn(async move |weak_lsp_store, cx| {
 5903                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5904                    return Ok(None);
 5905                };
 5906                let Some(responses) = request_task.await? else {
 5907                    return Ok(None);
 5908                };
 5909                let actions = join_all(responses.payload.into_iter().map(|response| {
 5910                    GetDeclarations { position }.response_from_proto(
 5911                        response.response,
 5912                        lsp_store.clone(),
 5913                        buffer.clone(),
 5914                        cx.clone(),
 5915                    )
 5916                }))
 5917                .await;
 5918
 5919                Ok(Some(
 5920                    actions
 5921                        .into_iter()
 5922                        .collect::<Result<Vec<Vec<_>>>>()?
 5923                        .into_iter()
 5924                        .flatten()
 5925                        .dedup()
 5926                        .collect(),
 5927                ))
 5928            })
 5929        } else {
 5930            let declarations_task = self.request_multiple_lsp_locally(
 5931                buffer,
 5932                Some(position),
 5933                GetDeclarations { position },
 5934                cx,
 5935            );
 5936            cx.background_spawn(async move {
 5937                Ok(Some(
 5938                    declarations_task
 5939                        .await
 5940                        .into_iter()
 5941                        .flat_map(|(_, declarations)| declarations)
 5942                        .dedup()
 5943                        .collect(),
 5944                ))
 5945            })
 5946        }
 5947    }
 5948
 5949    pub fn type_definitions(
 5950        &mut self,
 5951        buffer: &Entity<Buffer>,
 5952        position: PointUtf16,
 5953        cx: &mut Context<Self>,
 5954    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5955        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5956            let request = GetTypeDefinitions { position };
 5957            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5958                return Task::ready(Ok(None));
 5959            }
 5960            let request_timeout = ProjectSettings::get_global(cx)
 5961                .global_lsp_settings
 5962                .get_request_timeout();
 5963            let request_task = upstream_client.request_lsp(
 5964                project_id,
 5965                None,
 5966                request_timeout,
 5967                cx.background_executor().clone(),
 5968                request.to_proto(project_id, buffer.read(cx)),
 5969            );
 5970            let buffer = buffer.clone();
 5971            cx.spawn(async move |weak_lsp_store, cx| {
 5972                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5973                    return Ok(None);
 5974                };
 5975                let Some(responses) = request_task.await? else {
 5976                    return Ok(None);
 5977                };
 5978                let actions = join_all(responses.payload.into_iter().map(|response| {
 5979                    GetTypeDefinitions { position }.response_from_proto(
 5980                        response.response,
 5981                        lsp_store.clone(),
 5982                        buffer.clone(),
 5983                        cx.clone(),
 5984                    )
 5985                }))
 5986                .await;
 5987
 5988                Ok(Some(
 5989                    actions
 5990                        .into_iter()
 5991                        .collect::<Result<Vec<Vec<_>>>>()?
 5992                        .into_iter()
 5993                        .flatten()
 5994                        .dedup()
 5995                        .collect(),
 5996                ))
 5997            })
 5998        } else {
 5999            let type_definitions_task = self.request_multiple_lsp_locally(
 6000                buffer,
 6001                Some(position),
 6002                GetTypeDefinitions { position },
 6003                cx,
 6004            );
 6005            cx.background_spawn(async move {
 6006                Ok(Some(
 6007                    type_definitions_task
 6008                        .await
 6009                        .into_iter()
 6010                        .flat_map(|(_, type_definitions)| type_definitions)
 6011                        .dedup()
 6012                        .collect(),
 6013                ))
 6014            })
 6015        }
 6016    }
 6017
 6018    pub fn implementations(
 6019        &mut self,
 6020        buffer: &Entity<Buffer>,
 6021        position: PointUtf16,
 6022        cx: &mut Context<Self>,
 6023    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 6024        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6025            let request = GetImplementations { position };
 6026            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6027                return Task::ready(Ok(None));
 6028            }
 6029
 6030            let request_timeout = ProjectSettings::get_global(cx)
 6031                .global_lsp_settings
 6032                .get_request_timeout();
 6033            let request_task = upstream_client.request_lsp(
 6034                project_id,
 6035                None,
 6036                request_timeout,
 6037                cx.background_executor().clone(),
 6038                request.to_proto(project_id, buffer.read(cx)),
 6039            );
 6040            let buffer = buffer.clone();
 6041            cx.spawn(async move |weak_lsp_store, cx| {
 6042                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6043                    return Ok(None);
 6044                };
 6045                let Some(responses) = request_task.await? else {
 6046                    return Ok(None);
 6047                };
 6048                let actions = join_all(responses.payload.into_iter().map(|response| {
 6049                    GetImplementations { position }.response_from_proto(
 6050                        response.response,
 6051                        lsp_store.clone(),
 6052                        buffer.clone(),
 6053                        cx.clone(),
 6054                    )
 6055                }))
 6056                .await;
 6057
 6058                Ok(Some(
 6059                    actions
 6060                        .into_iter()
 6061                        .collect::<Result<Vec<Vec<_>>>>()?
 6062                        .into_iter()
 6063                        .flatten()
 6064                        .dedup()
 6065                        .collect(),
 6066                ))
 6067            })
 6068        } else {
 6069            let implementations_task = self.request_multiple_lsp_locally(
 6070                buffer,
 6071                Some(position),
 6072                GetImplementations { position },
 6073                cx,
 6074            );
 6075            cx.background_spawn(async move {
 6076                Ok(Some(
 6077                    implementations_task
 6078                        .await
 6079                        .into_iter()
 6080                        .flat_map(|(_, implementations)| implementations)
 6081                        .dedup()
 6082                        .collect(),
 6083                ))
 6084            })
 6085        }
 6086    }
 6087
 6088    pub fn references(
 6089        &mut self,
 6090        buffer: &Entity<Buffer>,
 6091        position: PointUtf16,
 6092        cx: &mut Context<Self>,
 6093    ) -> Task<Result<Option<Vec<Location>>>> {
 6094        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6095            let request = GetReferences { position };
 6096            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6097                return Task::ready(Ok(None));
 6098            }
 6099
 6100            let request_timeout = ProjectSettings::get_global(cx)
 6101                .global_lsp_settings
 6102                .get_request_timeout();
 6103            let request_task = upstream_client.request_lsp(
 6104                project_id,
 6105                None,
 6106                request_timeout,
 6107                cx.background_executor().clone(),
 6108                request.to_proto(project_id, buffer.read(cx)),
 6109            );
 6110            let buffer = buffer.clone();
 6111            cx.spawn(async move |weak_lsp_store, cx| {
 6112                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6113                    return Ok(None);
 6114                };
 6115                let Some(responses) = request_task.await? else {
 6116                    return Ok(None);
 6117                };
 6118
 6119                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 6120                    GetReferences { position }.response_from_proto(
 6121                        lsp_response.response,
 6122                        lsp_store.clone(),
 6123                        buffer.clone(),
 6124                        cx.clone(),
 6125                    )
 6126                }))
 6127                .await
 6128                .into_iter()
 6129                .collect::<Result<Vec<Vec<_>>>>()?
 6130                .into_iter()
 6131                .flatten()
 6132                .dedup()
 6133                .collect();
 6134                Ok(Some(locations))
 6135            })
 6136        } else {
 6137            let references_task = self.request_multiple_lsp_locally(
 6138                buffer,
 6139                Some(position),
 6140                GetReferences { position },
 6141                cx,
 6142            );
 6143            cx.background_spawn(async move {
 6144                Ok(Some(
 6145                    references_task
 6146                        .await
 6147                        .into_iter()
 6148                        .flat_map(|(_, references)| references)
 6149                        .dedup()
 6150                        .collect(),
 6151                ))
 6152            })
 6153        }
 6154    }
 6155
 6156    pub fn code_actions(
 6157        &mut self,
 6158        buffer: &Entity<Buffer>,
 6159        range: Range<Anchor>,
 6160        kinds: Option<Vec<CodeActionKind>>,
 6161        cx: &mut Context<Self>,
 6162    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6163        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6164            let request = GetCodeActions {
 6165                range: range.clone(),
 6166                kinds: kinds.clone(),
 6167            };
 6168            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6169                return Task::ready(Ok(None));
 6170            }
 6171            let request_timeout = ProjectSettings::get_global(cx)
 6172                .global_lsp_settings
 6173                .get_request_timeout();
 6174            let request_task = upstream_client.request_lsp(
 6175                project_id,
 6176                None,
 6177                request_timeout,
 6178                cx.background_executor().clone(),
 6179                request.to_proto(project_id, buffer.read(cx)),
 6180            );
 6181            let buffer = buffer.clone();
 6182            cx.spawn(async move |weak_lsp_store, cx| {
 6183                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6184                    return Ok(None);
 6185                };
 6186                let Some(responses) = request_task.await? else {
 6187                    return Ok(None);
 6188                };
 6189                let actions = join_all(responses.payload.into_iter().map(|response| {
 6190                    GetCodeActions {
 6191                        range: range.clone(),
 6192                        kinds: kinds.clone(),
 6193                    }
 6194                    .response_from_proto(
 6195                        response.response,
 6196                        lsp_store.clone(),
 6197                        buffer.clone(),
 6198                        cx.clone(),
 6199                    )
 6200                }))
 6201                .await;
 6202
 6203                Ok(Some(
 6204                    actions
 6205                        .into_iter()
 6206                        .collect::<Result<Vec<Vec<_>>>>()?
 6207                        .into_iter()
 6208                        .flatten()
 6209                        .collect(),
 6210                ))
 6211            })
 6212        } else {
 6213            let all_actions_task = self.request_multiple_lsp_locally(
 6214                buffer,
 6215                Some(range.start),
 6216                GetCodeActions { range, kinds },
 6217                cx,
 6218            );
 6219            cx.background_spawn(async move {
 6220                Ok(Some(
 6221                    all_actions_task
 6222                        .await
 6223                        .into_iter()
 6224                        .flat_map(|(_, actions)| actions)
 6225                        .collect(),
 6226                ))
 6227            })
 6228        }
 6229    }
 6230
 6231    #[inline(never)]
 6232    pub fn completions(
 6233        &self,
 6234        buffer: &Entity<Buffer>,
 6235        position: PointUtf16,
 6236        context: CompletionContext,
 6237        cx: &mut Context<Self>,
 6238    ) -> Task<Result<Vec<CompletionResponse>>> {
 6239        let language_registry = self.languages.clone();
 6240
 6241        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6242            let snapshot = buffer.read(cx).snapshot();
 6243            let offset = position.to_offset(&snapshot);
 6244            let scope = snapshot.language_scope_at(offset);
 6245            let capable_lsps = self.all_capable_for_proto_request(
 6246                buffer,
 6247                |server_name, capabilities| {
 6248                    capabilities.completion_provider.is_some()
 6249                        && scope
 6250                            .as_ref()
 6251                            .map(|scope| scope.language_allowed(server_name))
 6252                            .unwrap_or(true)
 6253                },
 6254                cx,
 6255            );
 6256            if capable_lsps.is_empty() {
 6257                return Task::ready(Ok(Vec::new()));
 6258            }
 6259
 6260            let language = buffer.read(cx).language().cloned();
 6261
 6262            let buffer = buffer.clone();
 6263
 6264            cx.spawn(async move |this, cx| {
 6265                let requests = join_all(
 6266                    capable_lsps
 6267                        .into_iter()
 6268                        .map(|(id, server_name)| {
 6269                            let request = GetCompletions {
 6270                                position,
 6271                                context: context.clone(),
 6272                                server_id: Some(id),
 6273                            };
 6274                            let buffer = buffer.clone();
 6275                            let language = language.clone();
 6276                            let lsp_adapter = language.as_ref().and_then(|language| {
 6277                                let adapters = language_registry.lsp_adapters(&language.name());
 6278                                adapters
 6279                                    .iter()
 6280                                    .find(|adapter| adapter.name() == server_name)
 6281                                    .or_else(|| adapters.first())
 6282                                    .cloned()
 6283                            });
 6284                            let upstream_client = upstream_client.clone();
 6285                            let response = this
 6286                                .update(cx, |this, cx| {
 6287                                    this.send_lsp_proto_request(
 6288                                        buffer,
 6289                                        upstream_client,
 6290                                        project_id,
 6291                                        request,
 6292                                        cx,
 6293                                    )
 6294                                })
 6295                                .log_err();
 6296                            async move {
 6297                                let response = response?.await.log_err()?;
 6298
 6299                                let completions = populate_labels_for_completions(
 6300                                    response.completions,
 6301                                    language,
 6302                                    lsp_adapter,
 6303                                )
 6304                                .await;
 6305
 6306                                Some(CompletionResponse {
 6307                                    completions,
 6308                                    display_options: CompletionDisplayOptions::default(),
 6309                                    is_incomplete: response.is_incomplete,
 6310                                })
 6311                            }
 6312                        })
 6313                        .collect::<Vec<_>>(),
 6314                );
 6315                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6316            })
 6317        } else if let Some(local) = self.as_local() {
 6318            let snapshot = buffer.read(cx).snapshot();
 6319            let offset = position.to_offset(&snapshot);
 6320            let scope = snapshot.language_scope_at(offset);
 6321            let language = snapshot.language().cloned();
 6322            let completion_settings = LanguageSettings::for_buffer(&buffer.read(cx), cx)
 6323                .completions
 6324                .clone();
 6325            if !completion_settings.lsp {
 6326                return Task::ready(Ok(Vec::new()));
 6327            }
 6328
 6329            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6330                local
 6331                    .language_servers_for_buffer(buffer, cx)
 6332                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6333                    .filter(|(adapter, _)| {
 6334                        scope
 6335                            .as_ref()
 6336                            .map(|scope| scope.language_allowed(&adapter.name))
 6337                            .unwrap_or(true)
 6338                    })
 6339                    .map(|(_, server)| server.server_id())
 6340                    .collect()
 6341            });
 6342
 6343            let buffer = buffer.clone();
 6344            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6345            let lsp_timeout = if lsp_timeout > 0 {
 6346                Some(Duration::from_millis(lsp_timeout))
 6347            } else {
 6348                None
 6349            };
 6350            cx.spawn(async move |this,  cx| {
 6351                let mut tasks = Vec::with_capacity(server_ids.len());
 6352                this.update(cx, |lsp_store, cx| {
 6353                    for server_id in server_ids {
 6354                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6355                        let lsp_timeout = lsp_timeout
 6356                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6357                        let mut timeout = cx.background_spawn(async move {
 6358                            match lsp_timeout {
 6359                                Some(lsp_timeout) => {
 6360                                    lsp_timeout.await;
 6361                                    true
 6362                                },
 6363                                None => false,
 6364                            }
 6365                        }).fuse();
 6366                        let mut lsp_request = lsp_store.request_lsp(
 6367                            buffer.clone(),
 6368                            LanguageServerToQuery::Other(server_id),
 6369                            GetCompletions {
 6370                                position,
 6371                                context: context.clone(),
 6372                                server_id: Some(server_id),
 6373                            },
 6374                            cx,
 6375                        ).fuse();
 6376                        let new_task = cx.background_spawn(async move {
 6377                            select_biased! {
 6378                                response = lsp_request => anyhow::Ok(Some(response?)),
 6379                                timeout_happened = timeout => {
 6380                                    if timeout_happened {
 6381                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6382                                        Ok(None)
 6383                                    } else {
 6384                                        let completions = lsp_request.await?;
 6385                                        Ok(Some(completions))
 6386                                    }
 6387                                },
 6388                            }
 6389                        });
 6390                        tasks.push((lsp_adapter, new_task));
 6391                    }
 6392                })?;
 6393
 6394                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6395                    let completion_response = task.await.ok()??;
 6396                    let completions = populate_labels_for_completions(
 6397                            completion_response.completions,
 6398                            language.clone(),
 6399                            lsp_adapter,
 6400                        )
 6401                        .await;
 6402                    Some(CompletionResponse {
 6403                        completions,
 6404                        display_options: CompletionDisplayOptions::default(),
 6405                        is_incomplete: completion_response.is_incomplete,
 6406                    })
 6407                });
 6408
 6409                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6410
 6411                Ok(responses.into_iter().flatten().collect())
 6412            })
 6413        } else {
 6414            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6415        }
 6416    }
 6417
 6418    pub fn resolve_completions(
 6419        &self,
 6420        buffer: Entity<Buffer>,
 6421        completion_indices: Vec<usize>,
 6422        completions: Rc<RefCell<Box<[Completion]>>>,
 6423        cx: &mut Context<Self>,
 6424    ) -> Task<Result<bool>> {
 6425        let client = self.upstream_client();
 6426        let buffer_id = buffer.read(cx).remote_id();
 6427        let buffer_snapshot = buffer.read(cx).snapshot();
 6428
 6429        if !self.check_if_capable_for_proto_request(
 6430            &buffer,
 6431            GetCompletions::can_resolve_completions,
 6432            cx,
 6433        ) {
 6434            return Task::ready(Ok(false));
 6435        }
 6436        cx.spawn(async move |lsp_store, cx| {
 6437            let request_timeout = cx.update(|app| {
 6438                ProjectSettings::get_global(app)
 6439                    .global_lsp_settings
 6440                    .get_request_timeout()
 6441            });
 6442
 6443            let mut did_resolve = false;
 6444            if let Some((client, project_id)) = client {
 6445                for completion_index in completion_indices {
 6446                    let server_id = {
 6447                        let completion = &completions.borrow()[completion_index];
 6448                        completion.source.server_id()
 6449                    };
 6450                    if let Some(server_id) = server_id {
 6451                        if Self::resolve_completion_remote(
 6452                            project_id,
 6453                            server_id,
 6454                            buffer_id,
 6455                            completions.clone(),
 6456                            completion_index,
 6457                            client.clone(),
 6458                        )
 6459                        .await
 6460                        .log_err()
 6461                        .is_some()
 6462                        {
 6463                            did_resolve = true;
 6464                        }
 6465                    } else {
 6466                        resolve_word_completion(
 6467                            &buffer_snapshot,
 6468                            &mut completions.borrow_mut()[completion_index],
 6469                        );
 6470                    }
 6471                }
 6472            } else {
 6473                for completion_index in completion_indices {
 6474                    let server_id = {
 6475                        let completion = &completions.borrow()[completion_index];
 6476                        completion.source.server_id()
 6477                    };
 6478                    if let Some(server_id) = server_id {
 6479                        let server_and_adapter = lsp_store
 6480                            .read_with(cx, |lsp_store, _| {
 6481                                let server = lsp_store.language_server_for_id(server_id)?;
 6482                                let adapter =
 6483                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6484                                Some((server, adapter))
 6485                            })
 6486                            .ok()
 6487                            .flatten();
 6488                        let Some((server, adapter)) = server_and_adapter else {
 6489                            continue;
 6490                        };
 6491
 6492                        let resolved = Self::resolve_completion_local(
 6493                            server,
 6494                            completions.clone(),
 6495                            completion_index,
 6496                            request_timeout,
 6497                        )
 6498                        .await
 6499                        .log_err()
 6500                        .is_some();
 6501                        if resolved {
 6502                            Self::regenerate_completion_labels(
 6503                                adapter,
 6504                                &buffer_snapshot,
 6505                                completions.clone(),
 6506                                completion_index,
 6507                            )
 6508                            .await
 6509                            .log_err();
 6510                            did_resolve = true;
 6511                        }
 6512                    } else {
 6513                        resolve_word_completion(
 6514                            &buffer_snapshot,
 6515                            &mut completions.borrow_mut()[completion_index],
 6516                        );
 6517                    }
 6518                }
 6519            }
 6520
 6521            Ok(did_resolve)
 6522        })
 6523    }
 6524
 6525    async fn resolve_completion_local(
 6526        server: Arc<lsp::LanguageServer>,
 6527        completions: Rc<RefCell<Box<[Completion]>>>,
 6528        completion_index: usize,
 6529        request_timeout: Duration,
 6530    ) -> Result<()> {
 6531        let server_id = server.server_id();
 6532        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6533            return Ok(());
 6534        }
 6535
 6536        let request = {
 6537            let completion = &completions.borrow()[completion_index];
 6538            match &completion.source {
 6539                CompletionSource::Lsp {
 6540                    lsp_completion,
 6541                    resolved,
 6542                    server_id: completion_server_id,
 6543                    ..
 6544                } => {
 6545                    if *resolved {
 6546                        return Ok(());
 6547                    }
 6548                    anyhow::ensure!(
 6549                        server_id == *completion_server_id,
 6550                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6551                    );
 6552                    server.request::<lsp::request::ResolveCompletionItem>(
 6553                        *lsp_completion.clone(),
 6554                        request_timeout,
 6555                    )
 6556                }
 6557                CompletionSource::BufferWord { .. }
 6558                | CompletionSource::Dap { .. }
 6559                | CompletionSource::Custom => {
 6560                    return Ok(());
 6561                }
 6562            }
 6563        };
 6564        let resolved_completion = request
 6565            .await
 6566            .into_response()
 6567            .context("resolve completion")?;
 6568
 6569        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6570        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6571
 6572        let mut completions = completions.borrow_mut();
 6573        let completion = &mut completions[completion_index];
 6574        if let CompletionSource::Lsp {
 6575            lsp_completion,
 6576            resolved,
 6577            server_id: completion_server_id,
 6578            ..
 6579        } = &mut completion.source
 6580        {
 6581            if *resolved {
 6582                return Ok(());
 6583            }
 6584            anyhow::ensure!(
 6585                server_id == *completion_server_id,
 6586                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6587            );
 6588            **lsp_completion = resolved_completion;
 6589            *resolved = true;
 6590        }
 6591        Ok(())
 6592    }
 6593
 6594    async fn regenerate_completion_labels(
 6595        adapter: Arc<CachedLspAdapter>,
 6596        snapshot: &BufferSnapshot,
 6597        completions: Rc<RefCell<Box<[Completion]>>>,
 6598        completion_index: usize,
 6599    ) -> Result<()> {
 6600        let completion_item = completions.borrow()[completion_index]
 6601            .source
 6602            .lsp_completion(true)
 6603            .map(Cow::into_owned);
 6604        if let Some(lsp_documentation) = completion_item
 6605            .as_ref()
 6606            .and_then(|completion_item| completion_item.documentation.clone())
 6607        {
 6608            let mut completions = completions.borrow_mut();
 6609            let completion = &mut completions[completion_index];
 6610            completion.documentation = Some(lsp_documentation.into());
 6611        } else {
 6612            let mut completions = completions.borrow_mut();
 6613            let completion = &mut completions[completion_index];
 6614            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6615        }
 6616
 6617        let mut new_label = match completion_item {
 6618            Some(completion_item) => {
 6619                // Some language servers always return `detail` lazily via resolve, regardless of
 6620                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6621                // See: https://github.com/yioneko/vtsls/issues/213
 6622                let language = snapshot.language();
 6623                match language {
 6624                    Some(language) => {
 6625                        adapter
 6626                            .labels_for_completions(
 6627                                std::slice::from_ref(&completion_item),
 6628                                language,
 6629                            )
 6630                            .await?
 6631                    }
 6632                    None => Vec::new(),
 6633                }
 6634                .pop()
 6635                .flatten()
 6636                .unwrap_or_else(|| {
 6637                    CodeLabel::fallback_for_completion(
 6638                        &completion_item,
 6639                        language.map(|language| language.as_ref()),
 6640                    )
 6641                })
 6642            }
 6643            None => CodeLabel::plain(
 6644                completions.borrow()[completion_index].new_text.clone(),
 6645                None,
 6646            ),
 6647        };
 6648        ensure_uniform_list_compatible_label(&mut new_label);
 6649
 6650        let mut completions = completions.borrow_mut();
 6651        let completion = &mut completions[completion_index];
 6652        if completion.label.filter_text() == new_label.filter_text() {
 6653            completion.label = new_label;
 6654        } else {
 6655            log::error!(
 6656                "Resolved completion changed display label from {} to {}. \
 6657                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6658                completion.label.text(),
 6659                new_label.text(),
 6660                completion.label.filter_text(),
 6661                new_label.filter_text()
 6662            );
 6663        }
 6664
 6665        Ok(())
 6666    }
 6667
 6668    async fn resolve_completion_remote(
 6669        project_id: u64,
 6670        server_id: LanguageServerId,
 6671        buffer_id: BufferId,
 6672        completions: Rc<RefCell<Box<[Completion]>>>,
 6673        completion_index: usize,
 6674        client: AnyProtoClient,
 6675    ) -> Result<()> {
 6676        let lsp_completion = {
 6677            let completion = &completions.borrow()[completion_index];
 6678            match &completion.source {
 6679                CompletionSource::Lsp {
 6680                    lsp_completion,
 6681                    resolved,
 6682                    server_id: completion_server_id,
 6683                    ..
 6684                } => {
 6685                    anyhow::ensure!(
 6686                        server_id == *completion_server_id,
 6687                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6688                    );
 6689                    if *resolved {
 6690                        return Ok(());
 6691                    }
 6692                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6693                }
 6694                CompletionSource::Custom
 6695                | CompletionSource::Dap { .. }
 6696                | CompletionSource::BufferWord { .. } => {
 6697                    return Ok(());
 6698                }
 6699            }
 6700        };
 6701        let request = proto::ResolveCompletionDocumentation {
 6702            project_id,
 6703            language_server_id: server_id.0 as u64,
 6704            lsp_completion,
 6705            buffer_id: buffer_id.into(),
 6706        };
 6707
 6708        let response = client
 6709            .request(request)
 6710            .await
 6711            .context("completion documentation resolve proto request")?;
 6712        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6713
 6714        let documentation = if response.documentation.is_empty() {
 6715            CompletionDocumentation::Undocumented
 6716        } else if response.documentation_is_markdown {
 6717            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6718        } else if response.documentation.lines().count() <= 1 {
 6719            CompletionDocumentation::SingleLine(response.documentation.into())
 6720        } else {
 6721            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6722        };
 6723
 6724        let mut completions = completions.borrow_mut();
 6725        let completion = &mut completions[completion_index];
 6726        completion.documentation = Some(documentation);
 6727        if let CompletionSource::Lsp {
 6728            insert_range,
 6729            lsp_completion,
 6730            resolved,
 6731            server_id: completion_server_id,
 6732            lsp_defaults: _,
 6733        } = &mut completion.source
 6734        {
 6735            let completion_insert_range = response
 6736                .old_insert_start
 6737                .and_then(deserialize_anchor)
 6738                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6739            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6740
 6741            if *resolved {
 6742                return Ok(());
 6743            }
 6744            anyhow::ensure!(
 6745                server_id == *completion_server_id,
 6746                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6747            );
 6748            **lsp_completion = resolved_lsp_completion;
 6749            *resolved = true;
 6750        }
 6751
 6752        let replace_range = response
 6753            .old_replace_start
 6754            .and_then(deserialize_anchor)
 6755            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6756        if let Some((old_replace_start, old_replace_end)) = replace_range
 6757            && !response.new_text.is_empty()
 6758        {
 6759            completion.new_text = response.new_text;
 6760            completion.replace_range = old_replace_start..old_replace_end;
 6761        }
 6762
 6763        Ok(())
 6764    }
 6765
 6766    pub fn apply_additional_edits_for_completion(
 6767        &self,
 6768        buffer_handle: Entity<Buffer>,
 6769        completions: Rc<RefCell<Box<[Completion]>>>,
 6770        completion_index: usize,
 6771        push_to_history: bool,
 6772        all_commit_ranges: Vec<Range<language::Anchor>>,
 6773        cx: &mut Context<Self>,
 6774    ) -> Task<Result<Option<Transaction>>> {
 6775        if let Some((client, project_id)) = self.upstream_client() {
 6776            let buffer = buffer_handle.read(cx);
 6777            let buffer_id = buffer.remote_id();
 6778            cx.spawn(async move |_, cx| {
 6779                let request = {
 6780                    let completion = completions.borrow()[completion_index].clone();
 6781                    proto::ApplyCompletionAdditionalEdits {
 6782                        project_id,
 6783                        buffer_id: buffer_id.into(),
 6784                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6785                            replace_range: completion.replace_range,
 6786                            new_text: completion.new_text,
 6787                            source: completion.source,
 6788                        })),
 6789                        all_commit_ranges: all_commit_ranges
 6790                            .iter()
 6791                            .cloned()
 6792                            .map(language::proto::serialize_anchor_range)
 6793                            .collect(),
 6794                    }
 6795                };
 6796
 6797                let Some(transaction) = client.request(request).await?.transaction else {
 6798                    return Ok(None);
 6799                };
 6800
 6801                let transaction = language::proto::deserialize_transaction(transaction)?;
 6802                buffer_handle
 6803                    .update(cx, |buffer, _| {
 6804                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6805                    })
 6806                    .await?;
 6807                if push_to_history {
 6808                    buffer_handle.update(cx, |buffer, _| {
 6809                        buffer.push_transaction(transaction.clone(), Instant::now());
 6810                        buffer.finalize_last_transaction();
 6811                    });
 6812                }
 6813                Ok(Some(transaction))
 6814            })
 6815        } else {
 6816            let request_timeout = ProjectSettings::get_global(cx)
 6817                .global_lsp_settings
 6818                .get_request_timeout();
 6819
 6820            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6821                let completion = &completions.borrow()[completion_index];
 6822                let server_id = completion.source.server_id()?;
 6823                Some(
 6824                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6825                        .1
 6826                        .clone(),
 6827                )
 6828            }) else {
 6829                return Task::ready(Ok(None));
 6830            };
 6831
 6832            cx.spawn(async move |this, cx| {
 6833                Self::resolve_completion_local(
 6834                    server.clone(),
 6835                    completions.clone(),
 6836                    completion_index,
 6837                    request_timeout,
 6838                )
 6839                .await
 6840                .context("resolving completion")?;
 6841                let completion = completions.borrow()[completion_index].clone();
 6842                let additional_text_edits = completion
 6843                    .source
 6844                    .lsp_completion(true)
 6845                    .as_ref()
 6846                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6847                if let Some(edits) = additional_text_edits {
 6848                    let edits = this
 6849                        .update(cx, |this, cx| {
 6850                            this.as_local_mut().unwrap().edits_from_lsp(
 6851                                &buffer_handle,
 6852                                edits,
 6853                                server.server_id(),
 6854                                None,
 6855                                cx,
 6856                            )
 6857                        })?
 6858                        .await?;
 6859
 6860                    buffer_handle.update(cx, |buffer, cx| {
 6861                        buffer.finalize_last_transaction();
 6862                        buffer.start_transaction();
 6863
 6864                        for (range, text) in edits {
 6865                            let primary = &completion.replace_range;
 6866
 6867                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6868                            // and the primary completion is just an insertion (empty range), then this is likely
 6869                            // an auto-import scenario and should not be considered overlapping
 6870                            // https://github.com/zed-industries/zed/issues/26136
 6871                            let is_file_start_auto_import = {
 6872                                let snapshot = buffer.snapshot();
 6873                                let primary_start_point = primary.start.to_point(&snapshot);
 6874                                let range_start_point = range.start.to_point(&snapshot);
 6875
 6876                                let result = primary_start_point.row == 0
 6877                                    && primary_start_point.column == 0
 6878                                    && range_start_point.row == 0
 6879                                    && range_start_point.column == 0;
 6880
 6881                                result
 6882                            };
 6883
 6884                            let has_overlap = if is_file_start_auto_import {
 6885                                false
 6886                            } else {
 6887                                all_commit_ranges.iter().any(|commit_range| {
 6888                                    let start_within =
 6889                                        commit_range.start.cmp(&range.start, buffer).is_le()
 6890                                            && commit_range.end.cmp(&range.start, buffer).is_ge();
 6891                                    let end_within =
 6892                                        range.start.cmp(&commit_range.end, buffer).is_le()
 6893                                            && range.end.cmp(&commit_range.end, buffer).is_ge();
 6894                                    start_within || end_within
 6895                                })
 6896                            };
 6897
 6898                            //Skip additional edits which overlap with the primary completion edit
 6899                            //https://github.com/zed-industries/zed/pull/1871
 6900                            if !has_overlap {
 6901                                buffer.edit([(range, text)], None, cx);
 6902                            }
 6903                        }
 6904
 6905                        let transaction = if buffer.end_transaction(cx).is_some() {
 6906                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6907                            if !push_to_history {
 6908                                buffer.forget_transaction(transaction.id);
 6909                            }
 6910                            Some(transaction)
 6911                        } else {
 6912                            None
 6913                        };
 6914                        Ok(transaction)
 6915                    })
 6916                } else {
 6917                    Ok(None)
 6918                }
 6919            })
 6920        }
 6921    }
 6922
 6923    pub fn pull_diagnostics(
 6924        &mut self,
 6925        buffer: Entity<Buffer>,
 6926        cx: &mut Context<Self>,
 6927    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6928        let buffer_id = buffer.read(cx).remote_id();
 6929
 6930        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6931            let mut suitable_capabilities = None;
 6932            // Are we capable for proto request?
 6933            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6934                &buffer,
 6935                |capabilities| {
 6936                    if let Some(caps) = &capabilities.diagnostic_provider {
 6937                        suitable_capabilities = Some(caps.clone());
 6938                        true
 6939                    } else {
 6940                        false
 6941                    }
 6942                },
 6943                cx,
 6944            );
 6945            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6946            let Some(dynamic_caps) = suitable_capabilities else {
 6947                return Task::ready(Ok(None));
 6948            };
 6949            assert!(any_server_has_diagnostics_provider);
 6950
 6951            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6952            let request = GetDocumentDiagnostics {
 6953                previous_result_id: None,
 6954                identifier,
 6955                registration_id: None,
 6956            };
 6957            let request_timeout = ProjectSettings::get_global(cx)
 6958                .global_lsp_settings
 6959                .get_request_timeout();
 6960            let request_task = client.request_lsp(
 6961                upstream_project_id,
 6962                None,
 6963                request_timeout,
 6964                cx.background_executor().clone(),
 6965                request.to_proto(upstream_project_id, buffer.read(cx)),
 6966            );
 6967            cx.background_spawn(async move {
 6968                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6969                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6970                // Do not attempt to further process the dummy responses here.
 6971                let _response = request_task.await?;
 6972                Ok(None)
 6973            })
 6974        } else {
 6975            let servers = buffer.update(cx, |buffer, cx| {
 6976                self.running_language_servers_for_local_buffer(buffer, cx)
 6977                    .map(|(_, server)| server.clone())
 6978                    .collect::<Vec<_>>()
 6979            });
 6980
 6981            let pull_diagnostics = servers
 6982                .into_iter()
 6983                .flat_map(|server| {
 6984                    let result = maybe!({
 6985                        let local = self.as_local()?;
 6986                        let server_id = server.server_id();
 6987                        let providers_with_identifiers = local
 6988                            .language_server_dynamic_registrations
 6989                            .get(&server_id)
 6990                            .into_iter()
 6991                            .flat_map(|registrations| registrations.diagnostics.clone())
 6992                            .collect::<Vec<_>>();
 6993                        Some(
 6994                            providers_with_identifiers
 6995                                .into_iter()
 6996                                .map(|(registration_id, dynamic_caps)| {
 6997                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6998                                    let registration_id = registration_id.map(SharedString::from);
 6999                                    let result_id = self.result_id_for_buffer_pull(
 7000                                        server_id,
 7001                                        buffer_id,
 7002                                        &registration_id,
 7003                                        cx,
 7004                                    );
 7005                                    self.request_lsp(
 7006                                        buffer.clone(),
 7007                                        LanguageServerToQuery::Other(server_id),
 7008                                        GetDocumentDiagnostics {
 7009                                            previous_result_id: result_id,
 7010                                            registration_id,
 7011                                            identifier,
 7012                                        },
 7013                                        cx,
 7014                                    )
 7015                                })
 7016                                .collect::<Vec<_>>(),
 7017                        )
 7018                    });
 7019
 7020                    result.unwrap_or_default()
 7021                })
 7022                .collect::<Vec<_>>();
 7023
 7024            cx.background_spawn(async move {
 7025                let mut responses = Vec::new();
 7026                for diagnostics in join_all(pull_diagnostics).await {
 7027                    responses.extend(diagnostics?);
 7028                }
 7029                Ok(Some(responses))
 7030            })
 7031        }
 7032    }
 7033
 7034    pub fn applicable_inlay_chunks(
 7035        &mut self,
 7036        buffer: &Entity<Buffer>,
 7037        ranges: &[Range<text::Anchor>],
 7038        cx: &mut Context<Self>,
 7039    ) -> Vec<Range<BufferRow>> {
 7040        let buffer_snapshot = buffer.read(cx).snapshot();
 7041        let ranges = ranges
 7042            .iter()
 7043            .map(|range| range.to_point(&buffer_snapshot))
 7044            .collect::<Vec<_>>();
 7045
 7046        self.latest_lsp_data(buffer, cx)
 7047            .inlay_hints
 7048            .applicable_chunks(ranges.as_slice())
 7049            .map(|chunk| chunk.row_range())
 7050            .collect()
 7051    }
 7052
 7053    pub fn invalidate_inlay_hints<'a>(
 7054        &'a mut self,
 7055        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 7056    ) {
 7057        for buffer_id in for_buffers {
 7058            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 7059                lsp_data.inlay_hints.clear();
 7060            }
 7061        }
 7062    }
 7063
 7064    pub fn inlay_hints(
 7065        &mut self,
 7066        invalidate: InvalidationStrategy,
 7067        buffer: Entity<Buffer>,
 7068        ranges: Vec<Range<text::Anchor>>,
 7069        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 7070        cx: &mut Context<Self>,
 7071    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 7072        let next_hint_id = self.next_hint_id.clone();
 7073        let lsp_data = self.latest_lsp_data(&buffer, cx);
 7074        let query_version = lsp_data.buffer_version.clone();
 7075        let mut lsp_refresh_requested = false;
 7076        let for_server = if let InvalidationStrategy::RefreshRequested {
 7077            server_id,
 7078            request_id,
 7079        } = invalidate
 7080        {
 7081            let invalidated = lsp_data
 7082                .inlay_hints
 7083                .invalidate_for_server_refresh(server_id, request_id);
 7084            lsp_refresh_requested = invalidated;
 7085            Some(server_id)
 7086        } else {
 7087            None
 7088        };
 7089        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 7090        let known_chunks = known_chunks
 7091            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 7092            .map(|(_, known_chunks)| known_chunks)
 7093            .unwrap_or_default();
 7094
 7095        let buffer_snapshot = buffer.read(cx).snapshot();
 7096        let ranges = ranges
 7097            .iter()
 7098            .map(|range| range.to_point(&buffer_snapshot))
 7099            .collect::<Vec<_>>();
 7100
 7101        let mut hint_fetch_tasks = Vec::new();
 7102        let mut cached_inlay_hints = None;
 7103        let mut ranges_to_query = None;
 7104        let applicable_chunks = existing_inlay_hints
 7105            .applicable_chunks(ranges.as_slice())
 7106            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7107            .collect::<Vec<_>>();
 7108        if applicable_chunks.is_empty() {
 7109            return HashMap::default();
 7110        }
 7111
 7112        for row_chunk in applicable_chunks {
 7113            match (
 7114                existing_inlay_hints
 7115                    .cached_hints(&row_chunk)
 7116                    .filter(|_| !lsp_refresh_requested)
 7117                    .cloned(),
 7118                existing_inlay_hints
 7119                    .fetched_hints(&row_chunk)
 7120                    .as_ref()
 7121                    .filter(|_| !lsp_refresh_requested)
 7122                    .cloned(),
 7123            ) {
 7124                (None, None) => {
 7125                    let chunk_range = row_chunk.anchor_range();
 7126                    ranges_to_query
 7127                        .get_or_insert_with(Vec::new)
 7128                        .push((row_chunk, chunk_range));
 7129                }
 7130                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7131                (Some(cached_hints), None) => {
 7132                    for (server_id, cached_hints) in cached_hints {
 7133                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7134                            cached_inlay_hints
 7135                                .get_or_insert_with(HashMap::default)
 7136                                .entry(row_chunk.row_range())
 7137                                .or_insert_with(HashMap::default)
 7138                                .entry(server_id)
 7139                                .or_insert_with(Vec::new)
 7140                                .extend(cached_hints);
 7141                        }
 7142                    }
 7143                }
 7144                (Some(cached_hints), Some(fetched_hints)) => {
 7145                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7146                    for (server_id, cached_hints) in cached_hints {
 7147                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7148                            cached_inlay_hints
 7149                                .get_or_insert_with(HashMap::default)
 7150                                .entry(row_chunk.row_range())
 7151                                .or_insert_with(HashMap::default)
 7152                                .entry(server_id)
 7153                                .or_insert_with(Vec::new)
 7154                                .extend(cached_hints);
 7155                        }
 7156                    }
 7157                }
 7158            }
 7159        }
 7160
 7161        if hint_fetch_tasks.is_empty()
 7162            && ranges_to_query
 7163                .as_ref()
 7164                .is_none_or(|ranges| ranges.is_empty())
 7165            && let Some(cached_inlay_hints) = cached_inlay_hints
 7166        {
 7167            cached_inlay_hints
 7168                .into_iter()
 7169                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7170                .collect()
 7171        } else {
 7172            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7173                // When a server refresh was requested, other servers' cached hints
 7174                // are unaffected by the refresh and must be included in the result.
 7175                // Otherwise apply_fetched_hints (with should_invalidate()=true)
 7176                // removes all visible hints but only adds back the requesting
 7177                // server's new hints, permanently losing other servers' hints.
 7178                let other_servers_cached: CacheInlayHints = if lsp_refresh_requested {
 7179                    lsp_data
 7180                        .inlay_hints
 7181                        .cached_hints(&chunk)
 7182                        .cloned()
 7183                        .unwrap_or_default()
 7184                } else {
 7185                    HashMap::default()
 7186                };
 7187
 7188                let next_hint_id = next_hint_id.clone();
 7189                let buffer = buffer.clone();
 7190                let query_version = query_version.clone();
 7191                let new_inlay_hints = cx
 7192                    .spawn(async move |lsp_store, cx| {
 7193                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7194                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7195                        })?;
 7196                        new_fetch_task
 7197                            .await
 7198                            .and_then(|new_hints_by_server| {
 7199                                lsp_store.update(cx, |lsp_store, cx| {
 7200                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7201                                    let update_cache = lsp_data.buffer_version == query_version;
 7202                                    if new_hints_by_server.is_empty() {
 7203                                        if update_cache {
 7204                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7205                                        }
 7206                                        other_servers_cached
 7207                                    } else {
 7208                                        let mut result = other_servers_cached;
 7209                                        for (server_id, new_hints) in new_hints_by_server {
 7210                                            let new_hints = new_hints
 7211                                                .into_iter()
 7212                                                .map(|new_hint| {
 7213                                                    (
 7214                                                        InlayId::Hint(next_hint_id.fetch_add(
 7215                                                            1,
 7216                                                            atomic::Ordering::AcqRel,
 7217                                                        )),
 7218                                                        new_hint,
 7219                                                    )
 7220                                                })
 7221                                                .collect::<Vec<_>>();
 7222                                            if update_cache {
 7223                                                lsp_data.inlay_hints.insert_new_hints(
 7224                                                    chunk,
 7225                                                    server_id,
 7226                                                    new_hints.clone(),
 7227                                                );
 7228                                            }
 7229                                            result.insert(server_id, new_hints);
 7230                                        }
 7231                                        result
 7232                                    }
 7233                                })
 7234                            })
 7235                            .map_err(Arc::new)
 7236                    })
 7237                    .shared();
 7238
 7239                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7240                *fetch_task = Some(new_inlay_hints.clone());
 7241                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7242            }
 7243
 7244            cached_inlay_hints
 7245                .unwrap_or_default()
 7246                .into_iter()
 7247                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7248                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7249                    (
 7250                        chunk.row_range(),
 7251                        cx.spawn(async move |_, _| {
 7252                            hints_fetch.await.map_err(|e| {
 7253                                if e.error_code() != ErrorCode::Internal {
 7254                                    anyhow!(e.error_code())
 7255                                } else {
 7256                                    anyhow!("{e:#}")
 7257                                }
 7258                            })
 7259                        }),
 7260                    )
 7261                }))
 7262                .collect()
 7263        }
 7264    }
 7265
 7266    fn fetch_inlay_hints(
 7267        &mut self,
 7268        for_server: Option<LanguageServerId>,
 7269        buffer: &Entity<Buffer>,
 7270        range: Range<Anchor>,
 7271        cx: &mut Context<Self>,
 7272    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7273        let request = InlayHints {
 7274            range: range.clone(),
 7275        };
 7276        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7277            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7278                return Task::ready(Ok(HashMap::default()));
 7279            }
 7280            let request_timeout = ProjectSettings::get_global(cx)
 7281                .global_lsp_settings
 7282                .get_request_timeout();
 7283            let request_task = upstream_client.request_lsp(
 7284                project_id,
 7285                for_server.map(|id| id.to_proto()),
 7286                request_timeout,
 7287                cx.background_executor().clone(),
 7288                request.to_proto(project_id, buffer.read(cx)),
 7289            );
 7290            let buffer = buffer.clone();
 7291            cx.spawn(async move |weak_lsp_store, cx| {
 7292                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7293                    return Ok(HashMap::default());
 7294                };
 7295                let Some(responses) = request_task.await? else {
 7296                    return Ok(HashMap::default());
 7297                };
 7298
 7299                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7300                    let lsp_store = lsp_store.clone();
 7301                    let buffer = buffer.clone();
 7302                    let cx = cx.clone();
 7303                    let request = request.clone();
 7304                    async move {
 7305                        (
 7306                            LanguageServerId::from_proto(response.server_id),
 7307                            request
 7308                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7309                                .await,
 7310                        )
 7311                    }
 7312                }))
 7313                .await;
 7314
 7315                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7316                let mut has_errors = false;
 7317                let inlay_hints = inlay_hints
 7318                    .into_iter()
 7319                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7320                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7321                        Err(e) => {
 7322                            has_errors = true;
 7323                            log::error!("{e:#}");
 7324                            None
 7325                        }
 7326                    })
 7327                    .map(|(server_id, mut new_hints)| {
 7328                        new_hints.retain(|hint| {
 7329                            hint.position.is_valid(&buffer_snapshot)
 7330                                && range.start.is_valid(&buffer_snapshot)
 7331                                && range.end.is_valid(&buffer_snapshot)
 7332                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7333                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7334                        });
 7335                        (server_id, new_hints)
 7336                    })
 7337                    .collect::<HashMap<_, _>>();
 7338                anyhow::ensure!(
 7339                    !has_errors || !inlay_hints.is_empty(),
 7340                    "Failed to fetch inlay hints"
 7341                );
 7342                Ok(inlay_hints)
 7343            })
 7344        } else {
 7345            let inlay_hints_task = match for_server {
 7346                Some(server_id) => {
 7347                    let server_task = self.request_lsp(
 7348                        buffer.clone(),
 7349                        LanguageServerToQuery::Other(server_id),
 7350                        request,
 7351                        cx,
 7352                    );
 7353                    cx.background_spawn(async move {
 7354                        let mut responses = Vec::new();
 7355                        match server_task.await {
 7356                            Ok(response) => responses.push((server_id, response)),
 7357                            // rust-analyzer likes to error with this when its still loading up
 7358                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7359                            Err(e) => log::error!(
 7360                                "Error handling response for inlay hints request: {e:#}"
 7361                            ),
 7362                        }
 7363                        responses
 7364                    })
 7365                }
 7366                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7367            };
 7368            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7369            cx.background_spawn(async move {
 7370                Ok(inlay_hints_task
 7371                    .await
 7372                    .into_iter()
 7373                    .map(|(server_id, mut new_hints)| {
 7374                        new_hints.retain(|hint| {
 7375                            hint.position.is_valid(&buffer_snapshot)
 7376                                && range.start.is_valid(&buffer_snapshot)
 7377                                && range.end.is_valid(&buffer_snapshot)
 7378                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7379                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7380                        });
 7381                        (server_id, new_hints)
 7382                    })
 7383                    .collect())
 7384            })
 7385        }
 7386    }
 7387
 7388    fn diagnostic_registration_exists(
 7389        &self,
 7390        server_id: LanguageServerId,
 7391        registration_id: &Option<SharedString>,
 7392    ) -> bool {
 7393        let Some(local) = self.as_local() else {
 7394            return false;
 7395        };
 7396        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7397        else {
 7398            return false;
 7399        };
 7400        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7401        registrations.diagnostics.contains_key(&registration_key)
 7402    }
 7403
 7404    pub fn pull_diagnostics_for_buffer(
 7405        &mut self,
 7406        buffer: Entity<Buffer>,
 7407        cx: &mut Context<Self>,
 7408    ) -> Task<anyhow::Result<()>> {
 7409        let diagnostics = self.pull_diagnostics(buffer, cx);
 7410        cx.spawn(async move |lsp_store, cx| {
 7411            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7412                return Ok(());
 7413            };
 7414            lsp_store.update(cx, |lsp_store, cx| {
 7415                if lsp_store.as_local().is_none() {
 7416                    return;
 7417                }
 7418
 7419                let mut unchanged_buffers = HashMap::default();
 7420                let server_diagnostics_updates = diagnostics
 7421                    .into_iter()
 7422                    .filter_map(|diagnostics_set| match diagnostics_set {
 7423                        LspPullDiagnostics::Response {
 7424                            server_id,
 7425                            uri,
 7426                            diagnostics,
 7427                            registration_id,
 7428                        } => Some((server_id, uri, diagnostics, registration_id)),
 7429                        LspPullDiagnostics::Default => None,
 7430                    })
 7431                    .filter(|(server_id, _, _, registration_id)| {
 7432                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7433                    })
 7434                    .fold(
 7435                        HashMap::default(),
 7436                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7437                            let (result_id, diagnostics) = match diagnostics {
 7438                                PulledDiagnostics::Unchanged { result_id } => {
 7439                                    unchanged_buffers
 7440                                        .entry(new_registration_id.clone())
 7441                                        .or_insert_with(HashSet::default)
 7442                                        .insert(uri.clone());
 7443                                    (Some(result_id), Vec::new())
 7444                                }
 7445                                PulledDiagnostics::Changed {
 7446                                    result_id,
 7447                                    diagnostics,
 7448                                } => (result_id, diagnostics),
 7449                            };
 7450                            let disk_based_sources = Cow::Owned(
 7451                                lsp_store
 7452                                    .language_server_adapter_for_id(server_id)
 7453                                    .as_ref()
 7454                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7455                                    .unwrap_or(&[])
 7456                                    .to_vec(),
 7457                            );
 7458                            acc.entry(server_id)
 7459                                .or_insert_with(HashMap::default)
 7460                                .entry(new_registration_id.clone())
 7461                                .or_insert_with(Vec::new)
 7462                                .push(DocumentDiagnosticsUpdate {
 7463                                    server_id,
 7464                                    diagnostics: lsp::PublishDiagnosticsParams {
 7465                                        uri,
 7466                                        diagnostics,
 7467                                        version: None,
 7468                                    },
 7469                                    result_id: result_id.map(SharedString::new),
 7470                                    disk_based_sources,
 7471                                    registration_id: new_registration_id,
 7472                                });
 7473                            acc
 7474                        },
 7475                    );
 7476
 7477                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7478                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7479                        lsp_store
 7480                            .merge_lsp_diagnostics(
 7481                                DiagnosticSourceKind::Pulled,
 7482                                diagnostic_updates,
 7483                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7484                                    DiagnosticSourceKind::Pulled => {
 7485                                        old_diagnostic.registration_id != registration_id
 7486                                            || unchanged_buffers
 7487                                                .get(&old_diagnostic.registration_id)
 7488                                                .is_some_and(|unchanged_buffers| {
 7489                                                    unchanged_buffers.contains(&document_uri)
 7490                                                })
 7491                                    }
 7492                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7493                                        true
 7494                                    }
 7495                                },
 7496                                cx,
 7497                            )
 7498                            .log_err();
 7499                    }
 7500                }
 7501            })
 7502        })
 7503    }
 7504
 7505    pub fn signature_help<T: ToPointUtf16>(
 7506        &mut self,
 7507        buffer: &Entity<Buffer>,
 7508        position: T,
 7509        cx: &mut Context<Self>,
 7510    ) -> Task<Option<Vec<SignatureHelp>>> {
 7511        let position = position.to_point_utf16(buffer.read(cx));
 7512
 7513        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7514            let request = GetSignatureHelp { position };
 7515            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7516                return Task::ready(None);
 7517            }
 7518            let request_timeout = ProjectSettings::get_global(cx)
 7519                .global_lsp_settings
 7520                .get_request_timeout();
 7521            let request_task = client.request_lsp(
 7522                upstream_project_id,
 7523                None,
 7524                request_timeout,
 7525                cx.background_executor().clone(),
 7526                request.to_proto(upstream_project_id, buffer.read(cx)),
 7527            );
 7528            let buffer = buffer.clone();
 7529            cx.spawn(async move |weak_lsp_store, cx| {
 7530                let lsp_store = weak_lsp_store.upgrade()?;
 7531                let signatures = join_all(
 7532                    request_task
 7533                        .await
 7534                        .log_err()
 7535                        .flatten()
 7536                        .map(|response| response.payload)
 7537                        .unwrap_or_default()
 7538                        .into_iter()
 7539                        .map(|response| {
 7540                            let response = GetSignatureHelp { position }.response_from_proto(
 7541                                response.response,
 7542                                lsp_store.clone(),
 7543                                buffer.clone(),
 7544                                cx.clone(),
 7545                            );
 7546                            async move { response.await.log_err().flatten() }
 7547                        }),
 7548                )
 7549                .await
 7550                .into_iter()
 7551                .flatten()
 7552                .collect();
 7553                Some(signatures)
 7554            })
 7555        } else {
 7556            let all_actions_task = self.request_multiple_lsp_locally(
 7557                buffer,
 7558                Some(position),
 7559                GetSignatureHelp { position },
 7560                cx,
 7561            );
 7562            cx.background_spawn(async move {
 7563                Some(
 7564                    all_actions_task
 7565                        .await
 7566                        .into_iter()
 7567                        .flat_map(|(_, actions)| actions)
 7568                        .collect::<Vec<_>>(),
 7569                )
 7570            })
 7571        }
 7572    }
 7573
 7574    pub fn hover(
 7575        &mut self,
 7576        buffer: &Entity<Buffer>,
 7577        position: PointUtf16,
 7578        cx: &mut Context<Self>,
 7579    ) -> Task<Option<Vec<Hover>>> {
 7580        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7581            let request = GetHover { position };
 7582            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7583                return Task::ready(None);
 7584            }
 7585            let request_timeout = ProjectSettings::get_global(cx)
 7586                .global_lsp_settings
 7587                .get_request_timeout();
 7588            let request_task = client.request_lsp(
 7589                upstream_project_id,
 7590                None,
 7591                request_timeout,
 7592                cx.background_executor().clone(),
 7593                request.to_proto(upstream_project_id, buffer.read(cx)),
 7594            );
 7595            let buffer = buffer.clone();
 7596            cx.spawn(async move |weak_lsp_store, cx| {
 7597                let lsp_store = weak_lsp_store.upgrade()?;
 7598                let hovers = join_all(
 7599                    request_task
 7600                        .await
 7601                        .log_err()
 7602                        .flatten()
 7603                        .map(|response| response.payload)
 7604                        .unwrap_or_default()
 7605                        .into_iter()
 7606                        .map(|response| {
 7607                            let response = GetHover { position }.response_from_proto(
 7608                                response.response,
 7609                                lsp_store.clone(),
 7610                                buffer.clone(),
 7611                                cx.clone(),
 7612                            );
 7613                            async move {
 7614                                response
 7615                                    .await
 7616                                    .log_err()
 7617                                    .flatten()
 7618                                    .and_then(remove_empty_hover_blocks)
 7619                            }
 7620                        }),
 7621                )
 7622                .await
 7623                .into_iter()
 7624                .flatten()
 7625                .collect();
 7626                Some(hovers)
 7627            })
 7628        } else {
 7629            let all_actions_task = self.request_multiple_lsp_locally(
 7630                buffer,
 7631                Some(position),
 7632                GetHover { position },
 7633                cx,
 7634            );
 7635            cx.background_spawn(async move {
 7636                Some(
 7637                    all_actions_task
 7638                        .await
 7639                        .into_iter()
 7640                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7641                        .collect::<Vec<Hover>>(),
 7642                )
 7643            })
 7644        }
 7645    }
 7646
 7647    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7648        let language_registry = self.languages.clone();
 7649
 7650        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7651            let request = upstream_client.request(proto::GetProjectSymbols {
 7652                project_id: *project_id,
 7653                query: query.to_string(),
 7654            });
 7655            cx.foreground_executor().spawn(async move {
 7656                let response = request.await?;
 7657                let mut symbols = Vec::new();
 7658                let core_symbols = response
 7659                    .symbols
 7660                    .into_iter()
 7661                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7662                    .collect::<Vec<_>>();
 7663                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7664                    .await;
 7665                Ok(symbols)
 7666            })
 7667        } else if let Some(local) = self.as_local() {
 7668            struct WorkspaceSymbolsResult {
 7669                server_id: LanguageServerId,
 7670                lsp_adapter: Arc<CachedLspAdapter>,
 7671                worktree: WeakEntity<Worktree>,
 7672                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7673            }
 7674
 7675            let mut requests = Vec::new();
 7676            let mut requested_servers = BTreeSet::new();
 7677            let request_timeout = ProjectSettings::get_global(cx)
 7678                .global_lsp_settings
 7679                .get_request_timeout();
 7680
 7681            for (seed, state) in local.language_server_ids.iter() {
 7682                let Some(worktree_handle) = self
 7683                    .worktree_store
 7684                    .read(cx)
 7685                    .worktree_for_id(seed.worktree_id, cx)
 7686                else {
 7687                    continue;
 7688                };
 7689
 7690                let worktree = worktree_handle.read(cx);
 7691                if !worktree.is_visible() {
 7692                    continue;
 7693                }
 7694
 7695                if !requested_servers.insert(state.id) {
 7696                    continue;
 7697                }
 7698
 7699                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7700                    Some(LanguageServerState::Running {
 7701                        adapter, server, ..
 7702                    }) => (adapter.clone(), server),
 7703
 7704                    _ => continue,
 7705                };
 7706
 7707                let supports_workspace_symbol_request =
 7708                    match server.capabilities().workspace_symbol_provider {
 7709                        Some(OneOf::Left(supported)) => supported,
 7710                        Some(OneOf::Right(_)) => true,
 7711                        None => false,
 7712                    };
 7713
 7714                if !supports_workspace_symbol_request {
 7715                    continue;
 7716                }
 7717
 7718                let worktree_handle = worktree_handle.clone();
 7719                let server_id = server.server_id();
 7720                requests.push(
 7721                    server
 7722                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7723                            lsp::WorkspaceSymbolParams {
 7724                                query: query.to_string(),
 7725                                ..Default::default()
 7726                            },
 7727                            request_timeout,
 7728                        )
 7729                        .map(move |response| {
 7730                            let lsp_symbols = response
 7731                                .into_response()
 7732                                .context("workspace symbols request")
 7733                                .log_err()
 7734                                .flatten()
 7735                                .map(|symbol_response| match symbol_response {
 7736                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7737                                        flat_responses
 7738                                            .into_iter()
 7739                                            .map(|lsp_symbol| {
 7740                                                (
 7741                                                    lsp_symbol.name,
 7742                                                    lsp_symbol.kind,
 7743                                                    lsp_symbol.location,
 7744                                                    lsp_symbol.container_name,
 7745                                                )
 7746                                            })
 7747                                            .collect::<Vec<_>>()
 7748                                    }
 7749                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7750                                        nested_responses
 7751                                            .into_iter()
 7752                                            .filter_map(|lsp_symbol| {
 7753                                                let location = match lsp_symbol.location {
 7754                                                    OneOf::Left(location) => location,
 7755                                                    OneOf::Right(_) => {
 7756                                                        log::error!(
 7757                                                            "Unexpected: client capabilities \
 7758                                                            forbid symbol resolutions in \
 7759                                                            workspace.symbol.resolveSupport"
 7760                                                        );
 7761                                                        return None;
 7762                                                    }
 7763                                                };
 7764                                                Some((
 7765                                                    lsp_symbol.name,
 7766                                                    lsp_symbol.kind,
 7767                                                    location,
 7768                                                    lsp_symbol.container_name,
 7769                                                ))
 7770                                            })
 7771                                            .collect::<Vec<_>>()
 7772                                    }
 7773                                })
 7774                                .unwrap_or_default();
 7775
 7776                            WorkspaceSymbolsResult {
 7777                                server_id,
 7778                                lsp_adapter,
 7779                                worktree: worktree_handle.downgrade(),
 7780                                lsp_symbols,
 7781                            }
 7782                        }),
 7783                );
 7784            }
 7785
 7786            cx.spawn(async move |this, cx| {
 7787                let responses = futures::future::join_all(requests).await;
 7788                let this = match this.upgrade() {
 7789                    Some(this) => this,
 7790                    None => return Ok(Vec::new()),
 7791                };
 7792
 7793                let mut symbols = Vec::new();
 7794                for result in responses {
 7795                    let core_symbols = this.update(cx, |this, cx| {
 7796                        result
 7797                            .lsp_symbols
 7798                            .into_iter()
 7799                            .filter_map(
 7800                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7801                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7802                                    let source_worktree = result.worktree.upgrade()?;
 7803                                    let source_worktree_id = source_worktree.read(cx).id();
 7804
 7805                                    let path = if let Some((tree, rel_path)) =
 7806                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7807                                    {
 7808                                        let worktree_id = tree.read(cx).id();
 7809                                        SymbolLocation::InProject(ProjectPath {
 7810                                            worktree_id,
 7811                                            path: rel_path,
 7812                                        })
 7813                                    } else {
 7814                                        SymbolLocation::OutsideProject {
 7815                                            signature: this.symbol_signature(&abs_path),
 7816                                            abs_path: abs_path.into(),
 7817                                        }
 7818                                    };
 7819
 7820                                    Some(CoreSymbol {
 7821                                        source_language_server_id: result.server_id,
 7822                                        language_server_name: result.lsp_adapter.name.clone(),
 7823                                        source_worktree_id,
 7824                                        path,
 7825                                        kind: symbol_kind,
 7826                                        name: collapse_newlines(&symbol_name, ""),
 7827                                        range: range_from_lsp(symbol_location.range),
 7828                                        container_name: container_name
 7829                                            .map(|c| collapse_newlines(&c, "")),
 7830                                    })
 7831                                },
 7832                            )
 7833                            .collect::<Vec<_>>()
 7834                    });
 7835
 7836                    populate_labels_for_symbols(
 7837                        core_symbols,
 7838                        &language_registry,
 7839                        Some(result.lsp_adapter),
 7840                        &mut symbols,
 7841                    )
 7842                    .await;
 7843                }
 7844
 7845                Ok(symbols)
 7846            })
 7847        } else {
 7848            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7849        }
 7850    }
 7851
 7852    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7853        let mut summary = DiagnosticSummary::default();
 7854        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7855            summary.error_count += path_summary.error_count;
 7856            summary.warning_count += path_summary.warning_count;
 7857        }
 7858        summary
 7859    }
 7860
 7861    /// Returns the diagnostic summary for a specific project path.
 7862    pub fn diagnostic_summary_for_path(
 7863        &self,
 7864        project_path: &ProjectPath,
 7865        _: &App,
 7866    ) -> DiagnosticSummary {
 7867        if let Some(summaries) = self
 7868            .diagnostic_summaries
 7869            .get(&project_path.worktree_id)
 7870            .and_then(|map| map.get(&project_path.path))
 7871        {
 7872            let (error_count, warning_count) = summaries.iter().fold(
 7873                (0, 0),
 7874                |(error_count, warning_count), (_language_server_id, summary)| {
 7875                    (
 7876                        error_count + summary.error_count,
 7877                        warning_count + summary.warning_count,
 7878                    )
 7879                },
 7880            );
 7881
 7882            DiagnosticSummary {
 7883                error_count,
 7884                warning_count,
 7885            }
 7886        } else {
 7887            DiagnosticSummary::default()
 7888        }
 7889    }
 7890
 7891    pub fn diagnostic_summaries<'a>(
 7892        &'a self,
 7893        include_ignored: bool,
 7894        cx: &'a App,
 7895    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7896        self.worktree_store
 7897            .read(cx)
 7898            .visible_worktrees(cx)
 7899            .filter_map(|worktree| {
 7900                let worktree = worktree.read(cx);
 7901                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7902            })
 7903            .flat_map(move |(worktree, summaries)| {
 7904                let worktree_id = worktree.id();
 7905                summaries
 7906                    .iter()
 7907                    .filter(move |(path, _)| {
 7908                        include_ignored
 7909                            || worktree
 7910                                .entry_for_path(path.as_ref())
 7911                                .is_some_and(|entry| !entry.is_ignored)
 7912                    })
 7913                    .flat_map(move |(path, summaries)| {
 7914                        summaries.iter().map(move |(server_id, summary)| {
 7915                            (
 7916                                ProjectPath {
 7917                                    worktree_id,
 7918                                    path: path.clone(),
 7919                                },
 7920                                *server_id,
 7921                                *summary,
 7922                            )
 7923                        })
 7924                    })
 7925            })
 7926    }
 7927
 7928    pub fn on_buffer_edited(
 7929        &mut self,
 7930        buffer: Entity<Buffer>,
 7931        cx: &mut Context<Self>,
 7932    ) -> Option<()> {
 7933        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7934            Some(
 7935                self.as_local()?
 7936                    .language_servers_for_buffer(buffer, cx)
 7937                    .map(|i| i.1.clone())
 7938                    .collect(),
 7939            )
 7940        })?;
 7941
 7942        let buffer = buffer.read(cx);
 7943        let file = File::from_dyn(buffer.file())?;
 7944        let abs_path = file.as_local()?.abs_path(cx);
 7945        let uri = lsp::Uri::from_file_path(&abs_path)
 7946            .ok()
 7947            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7948            .log_err()?;
 7949        let next_snapshot = buffer.text_snapshot();
 7950        for language_server in language_servers {
 7951            let language_server = language_server.clone();
 7952
 7953            let buffer_snapshots = self
 7954                .as_local_mut()?
 7955                .buffer_snapshots
 7956                .get_mut(&buffer.remote_id())
 7957                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7958            let previous_snapshot = buffer_snapshots.last()?;
 7959
 7960            let build_incremental_change = || {
 7961                buffer
 7962                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7963                        previous_snapshot.snapshot.version(),
 7964                    )
 7965                    .map(|edit| {
 7966                        let edit_start = edit.new.start.0;
 7967                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7968                        let new_text = next_snapshot
 7969                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7970                            .collect();
 7971                        lsp::TextDocumentContentChangeEvent {
 7972                            range: Some(lsp::Range::new(
 7973                                point_to_lsp(edit_start),
 7974                                point_to_lsp(edit_end),
 7975                            )),
 7976                            range_length: None,
 7977                            text: new_text,
 7978                        }
 7979                    })
 7980                    .collect()
 7981            };
 7982
 7983            let document_sync_kind = language_server
 7984                .capabilities()
 7985                .text_document_sync
 7986                .as_ref()
 7987                .and_then(|sync| match sync {
 7988                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7989                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7990                });
 7991
 7992            let content_changes: Vec<_> = match document_sync_kind {
 7993                Some(lsp::TextDocumentSyncKind::FULL) => {
 7994                    vec![lsp::TextDocumentContentChangeEvent {
 7995                        range: None,
 7996                        range_length: None,
 7997                        text: next_snapshot.text(),
 7998                    }]
 7999                }
 8000                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8001                _ => {
 8002                    #[cfg(any(test, feature = "test-support"))]
 8003                    {
 8004                        build_incremental_change()
 8005                    }
 8006
 8007                    #[cfg(not(any(test, feature = "test-support")))]
 8008                    {
 8009                        continue;
 8010                    }
 8011                }
 8012            };
 8013
 8014            let next_version = previous_snapshot.version + 1;
 8015            buffer_snapshots.push(LspBufferSnapshot {
 8016                version: next_version,
 8017                snapshot: next_snapshot.clone(),
 8018            });
 8019
 8020            language_server
 8021                .notify::<lsp::notification::DidChangeTextDocument>(
 8022                    lsp::DidChangeTextDocumentParams {
 8023                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8024                            uri.clone(),
 8025                            next_version,
 8026                        ),
 8027                        content_changes,
 8028                    },
 8029                )
 8030                .ok();
 8031            self.pull_workspace_diagnostics(language_server.server_id());
 8032        }
 8033
 8034        None
 8035    }
 8036
 8037    pub fn on_buffer_saved(
 8038        &mut self,
 8039        buffer: Entity<Buffer>,
 8040        cx: &mut Context<Self>,
 8041    ) -> Option<()> {
 8042        let file = File::from_dyn(buffer.read(cx).file())?;
 8043        let worktree_id = file.worktree_id(cx);
 8044        let abs_path = file.as_local()?.abs_path(cx);
 8045        let text_document = lsp::TextDocumentIdentifier {
 8046            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8047        };
 8048        let local = self.as_local()?;
 8049
 8050        for server in local.language_servers_for_worktree(worktree_id) {
 8051            if let Some(include_text) = include_text(server.as_ref()) {
 8052                let text = if include_text {
 8053                    Some(buffer.read(cx).text())
 8054                } else {
 8055                    None
 8056                };
 8057                server
 8058                    .notify::<lsp::notification::DidSaveTextDocument>(
 8059                        lsp::DidSaveTextDocumentParams {
 8060                            text_document: text_document.clone(),
 8061                            text,
 8062                        },
 8063                    )
 8064                    .ok();
 8065            }
 8066        }
 8067
 8068        let language_servers = buffer.update(cx, |buffer, cx| {
 8069            local.language_server_ids_for_buffer(buffer, cx)
 8070        });
 8071        for language_server_id in language_servers {
 8072            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8073        }
 8074
 8075        None
 8076    }
 8077
 8078    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8079        maybe!(async move {
 8080            let mut refreshed_servers = HashSet::default();
 8081            let servers = lsp_store
 8082                .update(cx, |lsp_store, cx| {
 8083                    let local = lsp_store.as_local()?;
 8084
 8085                    let servers = local
 8086                        .language_server_ids
 8087                        .iter()
 8088                        .filter_map(|(seed, state)| {
 8089                            let worktree = lsp_store
 8090                                .worktree_store
 8091                                .read(cx)
 8092                                .worktree_for_id(seed.worktree_id, cx);
 8093                            let delegate: Arc<dyn LspAdapterDelegate> =
 8094                                worktree.map(|worktree| {
 8095                                    LocalLspAdapterDelegate::new(
 8096                                        local.languages.clone(),
 8097                                        &local.environment,
 8098                                        cx.weak_entity(),
 8099                                        &worktree,
 8100                                        local.http_client.clone(),
 8101                                        local.fs.clone(),
 8102                                        cx,
 8103                                    )
 8104                                })?;
 8105                            let server_id = state.id;
 8106
 8107                            let states = local.language_servers.get(&server_id)?;
 8108
 8109                            match states {
 8110                                LanguageServerState::Starting { .. } => None,
 8111                                LanguageServerState::Running {
 8112                                    adapter, server, ..
 8113                                } => {
 8114                                    let adapter = adapter.clone();
 8115                                    let server = server.clone();
 8116                                    refreshed_servers.insert(server.name());
 8117                                    let toolchain = seed.toolchain.clone();
 8118                                    Some(cx.spawn(async move |_, cx| {
 8119                                        let settings =
 8120                                            LocalLspStore::workspace_configuration_for_adapter(
 8121                                                adapter.adapter.clone(),
 8122                                                &delegate,
 8123                                                toolchain,
 8124                                                None,
 8125                                                cx,
 8126                                            )
 8127                                            .await
 8128                                            .ok()?;
 8129                                        server
 8130                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8131                                                lsp::DidChangeConfigurationParams { settings },
 8132                                            )
 8133                                            .ok()?;
 8134                                        Some(())
 8135                                    }))
 8136                                }
 8137                            }
 8138                        })
 8139                        .collect::<Vec<_>>();
 8140
 8141                    Some(servers)
 8142                })
 8143                .ok()
 8144                .flatten()?;
 8145
 8146            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8147            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8148            // to stop and unregister its language server wrapper.
 8149            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8150            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8151            let _: Vec<Option<()>> = join_all(servers).await;
 8152
 8153            Some(())
 8154        })
 8155        .await;
 8156    }
 8157
 8158    fn maintain_workspace_config(
 8159        external_refresh_requests: watch::Receiver<()>,
 8160        cx: &mut Context<Self>,
 8161    ) -> Task<Result<()>> {
 8162        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8163        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8164
 8165        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8166            *settings_changed_tx.borrow_mut() = ();
 8167        });
 8168
 8169        let mut joint_future =
 8170            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8171        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8172        // - 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).
 8173        // - 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.
 8174        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8175        // - 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,
 8176        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8177        cx.spawn(async move |this, cx| {
 8178            while let Some(()) = joint_future.next().await {
 8179                this.update(cx, |this, cx| {
 8180                    this.refresh_server_tree(cx);
 8181                })
 8182                .ok();
 8183
 8184                Self::refresh_workspace_configurations(&this, cx).await;
 8185            }
 8186
 8187            drop(settings_observation);
 8188            anyhow::Ok(())
 8189        })
 8190    }
 8191
 8192    pub fn running_language_servers_for_local_buffer<'a>(
 8193        &'a self,
 8194        buffer: &Buffer,
 8195        cx: &mut App,
 8196    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8197        let local = self.as_local();
 8198        let language_server_ids = local
 8199            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8200            .unwrap_or_default();
 8201
 8202        language_server_ids
 8203            .into_iter()
 8204            .filter_map(
 8205                move |server_id| match local?.language_servers.get(&server_id)? {
 8206                    LanguageServerState::Running {
 8207                        adapter, server, ..
 8208                    } => Some((adapter, server)),
 8209                    _ => None,
 8210                },
 8211            )
 8212    }
 8213
 8214    pub fn language_servers_for_local_buffer(
 8215        &self,
 8216        buffer: &Buffer,
 8217        cx: &mut App,
 8218    ) -> Vec<LanguageServerId> {
 8219        let local = self.as_local();
 8220        local
 8221            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8222            .unwrap_or_default()
 8223    }
 8224
 8225    pub fn language_server_for_local_buffer<'a>(
 8226        &'a self,
 8227        buffer: &'a Buffer,
 8228        server_id: LanguageServerId,
 8229        cx: &'a mut App,
 8230    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8231        self.as_local()?
 8232            .language_servers_for_buffer(buffer, cx)
 8233            .find(|(_, s)| s.server_id() == server_id)
 8234    }
 8235
 8236    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8237        self.diagnostic_summaries.remove(&id_to_remove);
 8238        if let Some(local) = self.as_local_mut() {
 8239            let to_remove = local.remove_worktree(id_to_remove, cx);
 8240            for server in to_remove {
 8241                self.language_server_statuses.remove(&server);
 8242            }
 8243        }
 8244    }
 8245
 8246    fn invalidate_diagnostic_summaries_for_removed_entries(
 8247        &mut self,
 8248        worktree_id: WorktreeId,
 8249        changes: &UpdatedEntriesSet,
 8250        cx: &mut Context<Self>,
 8251    ) {
 8252        let Some(summaries_for_tree) = self.diagnostic_summaries.get_mut(&worktree_id) else {
 8253            return;
 8254        };
 8255
 8256        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
 8257        let mut cleared_server_ids: HashSet<LanguageServerId> = HashSet::default();
 8258        let downstream = self.downstream_client.clone();
 8259
 8260        for (path, _, _) in changes
 8261            .iter()
 8262            .filter(|(_, _, change)| *change == PathChange::Removed)
 8263        {
 8264            if let Some(summaries_by_server_id) = summaries_for_tree.remove(path) {
 8265                for (server_id, _) in &summaries_by_server_id {
 8266                    cleared_server_ids.insert(*server_id);
 8267                    if let Some((client, project_id)) = &downstream {
 8268                        client
 8269                            .send(proto::UpdateDiagnosticSummary {
 8270                                project_id: *project_id,
 8271                                worktree_id: worktree_id.to_proto(),
 8272                                summary: Some(proto::DiagnosticSummary {
 8273                                    path: path.as_ref().to_proto(),
 8274                                    language_server_id: server_id.0 as u64,
 8275                                    error_count: 0,
 8276                                    warning_count: 0,
 8277                                }),
 8278                                more_summaries: Vec::new(),
 8279                            })
 8280                            .ok();
 8281                    }
 8282                }
 8283                cleared_paths.push(ProjectPath {
 8284                    worktree_id,
 8285                    path: path.clone(),
 8286                });
 8287            }
 8288        }
 8289
 8290        if !cleared_paths.is_empty() {
 8291            for server_id in cleared_server_ids {
 8292                cx.emit(LspStoreEvent::DiagnosticsUpdated {
 8293                    server_id,
 8294                    paths: cleared_paths.clone(),
 8295                });
 8296            }
 8297        }
 8298    }
 8299
 8300    pub fn shared(
 8301        &mut self,
 8302        project_id: u64,
 8303        downstream_client: AnyProtoClient,
 8304        _: &mut Context<Self>,
 8305    ) {
 8306        self.downstream_client = Some((downstream_client.clone(), project_id));
 8307
 8308        for (server_id, status) in &self.language_server_statuses {
 8309            if let Some(server) = self.language_server_for_id(*server_id) {
 8310                downstream_client
 8311                    .send(proto::StartLanguageServer {
 8312                        project_id,
 8313                        server: Some(proto::LanguageServer {
 8314                            id: server_id.to_proto(),
 8315                            name: status.name.to_string(),
 8316                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8317                        }),
 8318                        capabilities: serde_json::to_string(&server.capabilities())
 8319                            .expect("serializing server LSP capabilities"),
 8320                    })
 8321                    .log_err();
 8322            }
 8323        }
 8324    }
 8325
 8326    pub fn disconnected_from_host(&mut self) {
 8327        self.downstream_client.take();
 8328    }
 8329
 8330    pub fn disconnected_from_ssh_remote(&mut self) {
 8331        if let LspStoreMode::Remote(RemoteLspStore {
 8332            upstream_client, ..
 8333        }) = &mut self.mode
 8334        {
 8335            upstream_client.take();
 8336        }
 8337    }
 8338
 8339    pub(crate) fn set_language_server_statuses_from_proto(
 8340        &mut self,
 8341        project: WeakEntity<Project>,
 8342        language_servers: Vec<proto::LanguageServer>,
 8343        server_capabilities: Vec<String>,
 8344        cx: &mut Context<Self>,
 8345    ) {
 8346        let lsp_logs = cx
 8347            .try_global::<GlobalLogStore>()
 8348            .map(|lsp_store| lsp_store.0.clone());
 8349
 8350        self.language_server_statuses = language_servers
 8351            .into_iter()
 8352            .zip(server_capabilities)
 8353            .map(|(server, server_capabilities)| {
 8354                let server_id = LanguageServerId(server.id as usize);
 8355                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8356                    self.lsp_server_capabilities
 8357                        .insert(server_id, server_capabilities);
 8358                }
 8359
 8360                let name = LanguageServerName::from_proto(server.name);
 8361                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8362
 8363                if let Some(lsp_logs) = &lsp_logs {
 8364                    lsp_logs.update(cx, |lsp_logs, cx| {
 8365                        lsp_logs.add_language_server(
 8366                            // Only remote clients get their language servers set from proto
 8367                            LanguageServerKind::Remote {
 8368                                project: project.clone(),
 8369                            },
 8370                            server_id,
 8371                            Some(name.clone()),
 8372                            worktree,
 8373                            None,
 8374                            cx,
 8375                        );
 8376                    });
 8377                }
 8378
 8379                (
 8380                    server_id,
 8381                    LanguageServerStatus {
 8382                        name,
 8383                        server_version: None,
 8384                        server_readable_version: None,
 8385                        pending_work: Default::default(),
 8386                        has_pending_diagnostic_updates: false,
 8387                        progress_tokens: Default::default(),
 8388                        worktree,
 8389                        binary: None,
 8390                        configuration: None,
 8391                        workspace_folders: BTreeSet::new(),
 8392                        process_id: None,
 8393                    },
 8394                )
 8395            })
 8396            .collect();
 8397    }
 8398
 8399    #[cfg(feature = "test-support")]
 8400    pub fn update_diagnostic_entries(
 8401        &mut self,
 8402        server_id: LanguageServerId,
 8403        abs_path: PathBuf,
 8404        result_id: Option<SharedString>,
 8405        version: Option<i32>,
 8406        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8407        cx: &mut Context<Self>,
 8408    ) -> anyhow::Result<()> {
 8409        self.merge_diagnostic_entries(
 8410            vec![DocumentDiagnosticsUpdate {
 8411                diagnostics: DocumentDiagnostics {
 8412                    diagnostics,
 8413                    document_abs_path: abs_path,
 8414                    version,
 8415                },
 8416                result_id,
 8417                server_id,
 8418                disk_based_sources: Cow::Borrowed(&[]),
 8419                registration_id: None,
 8420            }],
 8421            |_, _, _| false,
 8422            cx,
 8423        )?;
 8424        Ok(())
 8425    }
 8426
 8427    pub fn merge_diagnostic_entries<'a>(
 8428        &mut self,
 8429        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8430        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8431        cx: &mut Context<Self>,
 8432    ) -> anyhow::Result<()> {
 8433        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8434        let mut updated_diagnostics_paths = HashMap::default();
 8435        for mut update in diagnostic_updates {
 8436            let abs_path = &update.diagnostics.document_abs_path;
 8437            let server_id = update.server_id;
 8438            let Some((worktree, relative_path)) =
 8439                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8440            else {
 8441                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8442                return Ok(());
 8443            };
 8444
 8445            let worktree_id = worktree.read(cx).id();
 8446            let project_path = ProjectPath {
 8447                worktree_id,
 8448                path: relative_path,
 8449            };
 8450
 8451            let document_uri = lsp::Uri::from_file_path(abs_path)
 8452                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8453            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8454                let snapshot = buffer_handle.read(cx).snapshot();
 8455                let buffer = buffer_handle.read(cx);
 8456                let reused_diagnostics = buffer
 8457                    .buffer_diagnostics(Some(server_id))
 8458                    .iter()
 8459                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8460                    .map(|v| {
 8461                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8462                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8463                        DiagnosticEntry {
 8464                            range: start..end,
 8465                            diagnostic: v.diagnostic.clone(),
 8466                        }
 8467                    })
 8468                    .collect::<Vec<_>>();
 8469
 8470                self.as_local_mut()
 8471                    .context("cannot merge diagnostics on a remote LspStore")?
 8472                    .update_buffer_diagnostics(
 8473                        &buffer_handle,
 8474                        server_id,
 8475                        Some(update.registration_id),
 8476                        update.result_id,
 8477                        update.diagnostics.version,
 8478                        update.diagnostics.diagnostics.clone(),
 8479                        reused_diagnostics.clone(),
 8480                        cx,
 8481                    )?;
 8482
 8483                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8484            } else if let Some(local) = self.as_local() {
 8485                let reused_diagnostics = local
 8486                    .diagnostics
 8487                    .get(&worktree_id)
 8488                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8489                    .and_then(|diagnostics_by_server_id| {
 8490                        diagnostics_by_server_id
 8491                            .binary_search_by_key(&server_id, |e| e.0)
 8492                            .ok()
 8493                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8494                    })
 8495                    .into_iter()
 8496                    .flatten()
 8497                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8498
 8499                update
 8500                    .diagnostics
 8501                    .diagnostics
 8502                    .extend(reused_diagnostics.cloned());
 8503            }
 8504
 8505            let updated = worktree.update(cx, |worktree, cx| {
 8506                self.update_worktree_diagnostics(
 8507                    worktree.id(),
 8508                    server_id,
 8509                    project_path.path.clone(),
 8510                    update.diagnostics.diagnostics,
 8511                    cx,
 8512                )
 8513            })?;
 8514            match updated {
 8515                ControlFlow::Continue(new_summary) => {
 8516                    if let Some((project_id, new_summary)) = new_summary {
 8517                        match &mut diagnostics_summary {
 8518                            Some(diagnostics_summary) => {
 8519                                diagnostics_summary
 8520                                    .more_summaries
 8521                                    .push(proto::DiagnosticSummary {
 8522                                        path: project_path.path.as_ref().to_proto(),
 8523                                        language_server_id: server_id.0 as u64,
 8524                                        error_count: new_summary.error_count,
 8525                                        warning_count: new_summary.warning_count,
 8526                                    })
 8527                            }
 8528                            None => {
 8529                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8530                                    project_id,
 8531                                    worktree_id: worktree_id.to_proto(),
 8532                                    summary: Some(proto::DiagnosticSummary {
 8533                                        path: project_path.path.as_ref().to_proto(),
 8534                                        language_server_id: server_id.0 as u64,
 8535                                        error_count: new_summary.error_count,
 8536                                        warning_count: new_summary.warning_count,
 8537                                    }),
 8538                                    more_summaries: Vec::new(),
 8539                                })
 8540                            }
 8541                        }
 8542                    }
 8543                    updated_diagnostics_paths
 8544                        .entry(server_id)
 8545                        .or_insert_with(Vec::new)
 8546                        .push(project_path);
 8547                }
 8548                ControlFlow::Break(()) => {}
 8549            }
 8550        }
 8551
 8552        if let Some((diagnostics_summary, (downstream_client, _))) =
 8553            diagnostics_summary.zip(self.downstream_client.as_ref())
 8554        {
 8555            downstream_client.send(diagnostics_summary).log_err();
 8556        }
 8557        for (server_id, paths) in updated_diagnostics_paths {
 8558            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8559        }
 8560        Ok(())
 8561    }
 8562
 8563    fn update_worktree_diagnostics(
 8564        &mut self,
 8565        worktree_id: WorktreeId,
 8566        server_id: LanguageServerId,
 8567        path_in_worktree: Arc<RelPath>,
 8568        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8569        _: &mut Context<Worktree>,
 8570    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8571        let local = match &mut self.mode {
 8572            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8573            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8574        };
 8575
 8576        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8577        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8578        let summaries_by_server_id = summaries_for_tree
 8579            .entry(path_in_worktree.clone())
 8580            .or_default();
 8581
 8582        let old_summary = summaries_by_server_id
 8583            .remove(&server_id)
 8584            .unwrap_or_default();
 8585
 8586        let new_summary = DiagnosticSummary::new(&diagnostics);
 8587        if diagnostics.is_empty() {
 8588            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8589            {
 8590                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8591                    diagnostics_by_server_id.remove(ix);
 8592                }
 8593                if diagnostics_by_server_id.is_empty() {
 8594                    diagnostics_for_tree.remove(&path_in_worktree);
 8595                }
 8596            }
 8597        } else {
 8598            summaries_by_server_id.insert(server_id, new_summary);
 8599            let diagnostics_by_server_id = diagnostics_for_tree
 8600                .entry(path_in_worktree.clone())
 8601                .or_default();
 8602            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8603                Ok(ix) => {
 8604                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8605                }
 8606                Err(ix) => {
 8607                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8608                }
 8609            }
 8610        }
 8611
 8612        if !old_summary.is_empty() || !new_summary.is_empty() {
 8613            if let Some((_, project_id)) = &self.downstream_client {
 8614                Ok(ControlFlow::Continue(Some((
 8615                    *project_id,
 8616                    proto::DiagnosticSummary {
 8617                        path: path_in_worktree.to_proto(),
 8618                        language_server_id: server_id.0 as u64,
 8619                        error_count: new_summary.error_count as u32,
 8620                        warning_count: new_summary.warning_count as u32,
 8621                    },
 8622                ))))
 8623            } else {
 8624                Ok(ControlFlow::Continue(None))
 8625            }
 8626        } else {
 8627            Ok(ControlFlow::Break(()))
 8628        }
 8629    }
 8630
 8631    pub fn open_buffer_for_symbol(
 8632        &mut self,
 8633        symbol: &Symbol,
 8634        cx: &mut Context<Self>,
 8635    ) -> Task<Result<Entity<Buffer>>> {
 8636        if let Some((client, project_id)) = self.upstream_client() {
 8637            let request = client.request(proto::OpenBufferForSymbol {
 8638                project_id,
 8639                symbol: Some(Self::serialize_symbol(symbol)),
 8640            });
 8641            cx.spawn(async move |this, cx| {
 8642                let response = request.await?;
 8643                let buffer_id = BufferId::new(response.buffer_id)?;
 8644                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8645                    .await
 8646            })
 8647        } else if let Some(local) = self.as_local() {
 8648            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8649                seed.worktree_id == symbol.source_worktree_id
 8650                    && state.id == symbol.source_language_server_id
 8651                    && symbol.language_server_name == seed.name
 8652            });
 8653            if !is_valid {
 8654                return Task::ready(Err(anyhow!(
 8655                    "language server for worktree and language not found"
 8656                )));
 8657            };
 8658
 8659            let symbol_abs_path = match &symbol.path {
 8660                SymbolLocation::InProject(project_path) => self
 8661                    .worktree_store
 8662                    .read(cx)
 8663                    .absolutize(&project_path, cx)
 8664                    .context("no such worktree"),
 8665                SymbolLocation::OutsideProject {
 8666                    abs_path,
 8667                    signature: _,
 8668                } => Ok(abs_path.to_path_buf()),
 8669            };
 8670            let symbol_abs_path = match symbol_abs_path {
 8671                Ok(abs_path) => abs_path,
 8672                Err(err) => return Task::ready(Err(err)),
 8673            };
 8674            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8675                uri
 8676            } else {
 8677                return Task::ready(Err(anyhow!("invalid symbol path")));
 8678            };
 8679
 8680            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8681        } else {
 8682            Task::ready(Err(anyhow!("no upstream client or local store")))
 8683        }
 8684    }
 8685
 8686    pub(crate) fn open_local_buffer_via_lsp(
 8687        &mut self,
 8688        abs_path: lsp::Uri,
 8689        language_server_id: LanguageServerId,
 8690        cx: &mut Context<Self>,
 8691    ) -> Task<Result<Entity<Buffer>>> {
 8692        let path_style = self.worktree_store.read(cx).path_style();
 8693        cx.spawn(async move |lsp_store, cx| {
 8694            // Escape percent-encoded string.
 8695            let current_scheme = abs_path.scheme().to_owned();
 8696            // Uri is immutable, so we can't modify the scheme
 8697
 8698            let abs_path = abs_path
 8699                .to_file_path_ext(path_style)
 8700                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8701            let p = abs_path.clone();
 8702            let yarn_worktree = lsp_store
 8703                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8704                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8705                        cx.spawn(async move |this, cx| {
 8706                            let t = this
 8707                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8708                                .ok()?;
 8709                            t.await
 8710                        })
 8711                    }),
 8712                    None => Task::ready(None),
 8713                })?
 8714                .await;
 8715            let (worktree_root_target, known_relative_path) =
 8716                if let Some((zip_root, relative_path)) = yarn_worktree {
 8717                    (zip_root, Some(relative_path))
 8718                } else {
 8719                    (Arc::<Path>::from(abs_path.as_path()), None)
 8720                };
 8721            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8722                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8723                    worktree_store.find_worktree(&worktree_root_target, cx)
 8724                })
 8725            })?;
 8726            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8727                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8728                (result.0, relative_path, None)
 8729            } else {
 8730                let worktree = lsp_store
 8731                    .update(cx, |lsp_store, cx| {
 8732                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8733                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8734                        })
 8735                    })?
 8736                    .await?;
 8737                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8738                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8739                    lsp_store
 8740                        .update(cx, |lsp_store, cx| {
 8741                            if let Some(local) = lsp_store.as_local_mut() {
 8742                                local.register_language_server_for_invisible_worktree(
 8743                                    &worktree,
 8744                                    language_server_id,
 8745                                    cx,
 8746                                )
 8747                            }
 8748                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8749                                Some(status) => status.worktree,
 8750                                None => None,
 8751                            }
 8752                        })
 8753                        .ok()
 8754                        .flatten()
 8755                        .zip(Some(worktree_root.clone()))
 8756                } else {
 8757                    None
 8758                };
 8759                let relative_path = if let Some(known_path) = known_relative_path {
 8760                    known_path
 8761                } else {
 8762                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8763                        .into_arc()
 8764                };
 8765                (worktree, relative_path, source_ws)
 8766            };
 8767            let project_path = ProjectPath {
 8768                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8769                path: relative_path,
 8770            };
 8771            let buffer = lsp_store
 8772                .update(cx, |lsp_store, cx| {
 8773                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8774                        buffer_store.open_buffer(project_path, cx)
 8775                    })
 8776                })?
 8777                .await?;
 8778            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8779            if let Some((source_ws, worktree_root)) = source_ws {
 8780                buffer.update(cx, |buffer, cx| {
 8781                    let settings = WorktreeSettings::get(
 8782                        Some(
 8783                            (&ProjectPath {
 8784                                worktree_id: source_ws,
 8785                                path: Arc::from(RelPath::empty()),
 8786                            })
 8787                                .into(),
 8788                        ),
 8789                        cx,
 8790                    );
 8791                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8792                    if is_read_only {
 8793                        buffer.set_capability(Capability::ReadOnly, cx);
 8794                    }
 8795                });
 8796            }
 8797            Ok(buffer)
 8798        })
 8799    }
 8800
 8801    fn local_lsp_servers_for_buffer(
 8802        &self,
 8803        buffer: &Entity<Buffer>,
 8804        cx: &mut Context<Self>,
 8805    ) -> Vec<LanguageServerId> {
 8806        let Some(local) = self.as_local() else {
 8807            return Vec::new();
 8808        };
 8809
 8810        let snapshot = buffer.read(cx).snapshot();
 8811
 8812        buffer.update(cx, |buffer, cx| {
 8813            local
 8814                .language_servers_for_buffer(buffer, cx)
 8815                .map(|(_, server)| server.server_id())
 8816                .filter(|server_id| {
 8817                    self.as_local().is_none_or(|local| {
 8818                        local
 8819                            .buffers_opened_in_servers
 8820                            .get(&snapshot.remote_id())
 8821                            .is_some_and(|servers| servers.contains(server_id))
 8822                    })
 8823                })
 8824                .collect()
 8825        })
 8826    }
 8827
 8828    fn request_multiple_lsp_locally<P, R>(
 8829        &mut self,
 8830        buffer: &Entity<Buffer>,
 8831        position: Option<P>,
 8832        request: R,
 8833        cx: &mut Context<Self>,
 8834    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8835    where
 8836        P: ToOffset,
 8837        R: LspCommand + Clone,
 8838        <R::LspRequest as lsp::request::Request>::Result: Send,
 8839        <R::LspRequest as lsp::request::Request>::Params: Send,
 8840    {
 8841        let Some(local) = self.as_local() else {
 8842            return Task::ready(Vec::new());
 8843        };
 8844
 8845        let snapshot = buffer.read(cx).snapshot();
 8846        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8847
 8848        let server_ids = buffer.update(cx, |buffer, cx| {
 8849            local
 8850                .language_servers_for_buffer(buffer, cx)
 8851                .filter(|(adapter, _)| {
 8852                    scope
 8853                        .as_ref()
 8854                        .map(|scope| scope.language_allowed(&adapter.name))
 8855                        .unwrap_or(true)
 8856                })
 8857                .map(|(_, server)| server.server_id())
 8858                .filter(|server_id| {
 8859                    self.as_local().is_none_or(|local| {
 8860                        local
 8861                            .buffers_opened_in_servers
 8862                            .get(&snapshot.remote_id())
 8863                            .is_some_and(|servers| servers.contains(server_id))
 8864                    })
 8865                })
 8866                .collect::<Vec<_>>()
 8867        });
 8868
 8869        let mut response_results = server_ids
 8870            .into_iter()
 8871            .map(|server_id| {
 8872                let task = self.request_lsp(
 8873                    buffer.clone(),
 8874                    LanguageServerToQuery::Other(server_id),
 8875                    request.clone(),
 8876                    cx,
 8877                );
 8878                async move { (server_id, task.await) }
 8879            })
 8880            .collect::<FuturesUnordered<_>>();
 8881
 8882        cx.background_spawn(async move {
 8883            let mut responses = Vec::with_capacity(response_results.len());
 8884            while let Some((server_id, response_result)) = response_results.next().await {
 8885                match response_result {
 8886                    Ok(response) => responses.push((server_id, response)),
 8887                    // rust-analyzer likes to error with this when its still loading up
 8888                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8889                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8890                }
 8891            }
 8892            responses
 8893        })
 8894    }
 8895
 8896    async fn handle_lsp_get_completions(
 8897        this: Entity<Self>,
 8898        envelope: TypedEnvelope<proto::GetCompletions>,
 8899        mut cx: AsyncApp,
 8900    ) -> Result<proto::GetCompletionsResponse> {
 8901        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8902
 8903        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8904        let buffer_handle = this.update(&mut cx, |this, cx| {
 8905            this.buffer_store.read(cx).get_existing(buffer_id)
 8906        })?;
 8907        let request = GetCompletions::from_proto(
 8908            envelope.payload,
 8909            this.clone(),
 8910            buffer_handle.clone(),
 8911            cx.clone(),
 8912        )
 8913        .await?;
 8914
 8915        let server_to_query = match request.server_id {
 8916            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8917            None => LanguageServerToQuery::FirstCapable,
 8918        };
 8919
 8920        let response = this
 8921            .update(&mut cx, |this, cx| {
 8922                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8923            })
 8924            .await?;
 8925        this.update(&mut cx, |this, cx| {
 8926            Ok(GetCompletions::response_to_proto(
 8927                response,
 8928                this,
 8929                sender_id,
 8930                &buffer_handle.read(cx).version(),
 8931                cx,
 8932            ))
 8933        })
 8934    }
 8935
 8936    async fn handle_lsp_command<T: LspCommand>(
 8937        this: Entity<Self>,
 8938        envelope: TypedEnvelope<T::ProtoRequest>,
 8939        mut cx: AsyncApp,
 8940    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8941    where
 8942        <T::LspRequest as lsp::request::Request>::Params: Send,
 8943        <T::LspRequest as lsp::request::Request>::Result: Send,
 8944    {
 8945        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8946        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8947        let buffer_handle = this.update(&mut cx, |this, cx| {
 8948            this.buffer_store.read(cx).get_existing(buffer_id)
 8949        })?;
 8950        let request = T::from_proto(
 8951            envelope.payload,
 8952            this.clone(),
 8953            buffer_handle.clone(),
 8954            cx.clone(),
 8955        )
 8956        .await?;
 8957        let response = this
 8958            .update(&mut cx, |this, cx| {
 8959                this.request_lsp(
 8960                    buffer_handle.clone(),
 8961                    LanguageServerToQuery::FirstCapable,
 8962                    request,
 8963                    cx,
 8964                )
 8965            })
 8966            .await?;
 8967        this.update(&mut cx, |this, cx| {
 8968            Ok(T::response_to_proto(
 8969                response,
 8970                this,
 8971                sender_id,
 8972                &buffer_handle.read(cx).version(),
 8973                cx,
 8974            ))
 8975        })
 8976    }
 8977
 8978    async fn handle_lsp_query(
 8979        lsp_store: Entity<Self>,
 8980        envelope: TypedEnvelope<proto::LspQuery>,
 8981        mut cx: AsyncApp,
 8982    ) -> Result<proto::Ack> {
 8983        use proto::lsp_query::Request;
 8984        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8985        let lsp_query = envelope.payload;
 8986        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8987        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8988        match lsp_query.request.context("invalid LSP query request")? {
 8989            Request::GetReferences(get_references) => {
 8990                let position = get_references.position.clone().and_then(deserialize_anchor);
 8991                Self::query_lsp_locally::<GetReferences>(
 8992                    lsp_store,
 8993                    server_id,
 8994                    sender_id,
 8995                    lsp_request_id,
 8996                    get_references,
 8997                    position,
 8998                    &mut cx,
 8999                )
 9000                .await?;
 9001            }
 9002            Request::GetDocumentColor(get_document_color) => {
 9003                Self::query_lsp_locally::<GetDocumentColor>(
 9004                    lsp_store,
 9005                    server_id,
 9006                    sender_id,
 9007                    lsp_request_id,
 9008                    get_document_color,
 9009                    None,
 9010                    &mut cx,
 9011                )
 9012                .await?;
 9013            }
 9014            Request::GetFoldingRanges(get_folding_ranges) => {
 9015                Self::query_lsp_locally::<GetFoldingRanges>(
 9016                    lsp_store,
 9017                    server_id,
 9018                    sender_id,
 9019                    lsp_request_id,
 9020                    get_folding_ranges,
 9021                    None,
 9022                    &mut cx,
 9023                )
 9024                .await?;
 9025            }
 9026            Request::GetDocumentSymbols(get_document_symbols) => {
 9027                Self::query_lsp_locally::<GetDocumentSymbols>(
 9028                    lsp_store,
 9029                    server_id,
 9030                    sender_id,
 9031                    lsp_request_id,
 9032                    get_document_symbols,
 9033                    None,
 9034                    &mut cx,
 9035                )
 9036                .await?;
 9037            }
 9038            Request::GetHover(get_hover) => {
 9039                let position = get_hover.position.clone().and_then(deserialize_anchor);
 9040                Self::query_lsp_locally::<GetHover>(
 9041                    lsp_store,
 9042                    server_id,
 9043                    sender_id,
 9044                    lsp_request_id,
 9045                    get_hover,
 9046                    position,
 9047                    &mut cx,
 9048                )
 9049                .await?;
 9050            }
 9051            Request::GetCodeActions(get_code_actions) => {
 9052                Self::query_lsp_locally::<GetCodeActions>(
 9053                    lsp_store,
 9054                    server_id,
 9055                    sender_id,
 9056                    lsp_request_id,
 9057                    get_code_actions,
 9058                    None,
 9059                    &mut cx,
 9060                )
 9061                .await?;
 9062            }
 9063            Request::GetSignatureHelp(get_signature_help) => {
 9064                let position = get_signature_help
 9065                    .position
 9066                    .clone()
 9067                    .and_then(deserialize_anchor);
 9068                Self::query_lsp_locally::<GetSignatureHelp>(
 9069                    lsp_store,
 9070                    server_id,
 9071                    sender_id,
 9072                    lsp_request_id,
 9073                    get_signature_help,
 9074                    position,
 9075                    &mut cx,
 9076                )
 9077                .await?;
 9078            }
 9079            Request::GetCodeLens(get_code_lens) => {
 9080                Self::query_lsp_locally::<GetCodeLens>(
 9081                    lsp_store,
 9082                    server_id,
 9083                    sender_id,
 9084                    lsp_request_id,
 9085                    get_code_lens,
 9086                    None,
 9087                    &mut cx,
 9088                )
 9089                .await?;
 9090            }
 9091            Request::GetDefinition(get_definition) => {
 9092                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9093                Self::query_lsp_locally::<GetDefinitions>(
 9094                    lsp_store,
 9095                    server_id,
 9096                    sender_id,
 9097                    lsp_request_id,
 9098                    get_definition,
 9099                    position,
 9100                    &mut cx,
 9101                )
 9102                .await?;
 9103            }
 9104            Request::GetDeclaration(get_declaration) => {
 9105                let position = get_declaration
 9106                    .position
 9107                    .clone()
 9108                    .and_then(deserialize_anchor);
 9109                Self::query_lsp_locally::<GetDeclarations>(
 9110                    lsp_store,
 9111                    server_id,
 9112                    sender_id,
 9113                    lsp_request_id,
 9114                    get_declaration,
 9115                    position,
 9116                    &mut cx,
 9117                )
 9118                .await?;
 9119            }
 9120            Request::GetTypeDefinition(get_type_definition) => {
 9121                let position = get_type_definition
 9122                    .position
 9123                    .clone()
 9124                    .and_then(deserialize_anchor);
 9125                Self::query_lsp_locally::<GetTypeDefinitions>(
 9126                    lsp_store,
 9127                    server_id,
 9128                    sender_id,
 9129                    lsp_request_id,
 9130                    get_type_definition,
 9131                    position,
 9132                    &mut cx,
 9133                )
 9134                .await?;
 9135            }
 9136            Request::GetImplementation(get_implementation) => {
 9137                let position = get_implementation
 9138                    .position
 9139                    .clone()
 9140                    .and_then(deserialize_anchor);
 9141                Self::query_lsp_locally::<GetImplementations>(
 9142                    lsp_store,
 9143                    server_id,
 9144                    sender_id,
 9145                    lsp_request_id,
 9146                    get_implementation,
 9147                    position,
 9148                    &mut cx,
 9149                )
 9150                .await?;
 9151            }
 9152            Request::InlayHints(inlay_hints) => {
 9153                let query_start = inlay_hints
 9154                    .start
 9155                    .clone()
 9156                    .and_then(deserialize_anchor)
 9157                    .context("invalid inlay hints range start")?;
 9158                let query_end = inlay_hints
 9159                    .end
 9160                    .clone()
 9161                    .and_then(deserialize_anchor)
 9162                    .context("invalid inlay hints range end")?;
 9163                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9164                    &lsp_store,
 9165                    server_id,
 9166                    lsp_request_id,
 9167                    &inlay_hints,
 9168                    query_start..query_end,
 9169                    &mut cx,
 9170                )
 9171                .await
 9172                .context("preparing inlay hints request")?;
 9173                Self::query_lsp_locally::<InlayHints>(
 9174                    lsp_store,
 9175                    server_id,
 9176                    sender_id,
 9177                    lsp_request_id,
 9178                    inlay_hints,
 9179                    None,
 9180                    &mut cx,
 9181                )
 9182                .await
 9183                .context("querying for inlay hints")?
 9184            }
 9185            //////////////////////////////
 9186            // Below are LSP queries that need to fetch more data,
 9187            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 9188            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9189                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 9190                    &lsp_store,
 9191                    &get_document_diagnostics,
 9192                    &mut cx,
 9193                )
 9194                .await?;
 9195                lsp_store.update(&mut cx, |lsp_store, cx| {
 9196                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9197                    let key = LspKey {
 9198                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9199                        server_queried: server_id,
 9200                    };
 9201                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9202                    ) {
 9203                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9204                            lsp_requests.clear();
 9205                        };
 9206                    }
 9207
 9208                    lsp_data.lsp_requests.entry(key).or_default().insert(
 9209                        lsp_request_id,
 9210                        cx.spawn(async move |lsp_store, cx| {
 9211                            let diagnostics_pull = lsp_store
 9212                                .update(cx, |lsp_store, cx| {
 9213                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9214                                })
 9215                                .ok();
 9216                            if let Some(diagnostics_pull) = diagnostics_pull {
 9217                                match diagnostics_pull.await {
 9218                                    Ok(()) => {}
 9219                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9220                                };
 9221                            }
 9222                        }),
 9223                    );
 9224                });
 9225            }
 9226            Request::SemanticTokens(semantic_tokens) => {
 9227                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 9228                    &lsp_store,
 9229                    &semantic_tokens,
 9230                    &mut cx,
 9231                )
 9232                .await?;
 9233                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9234                lsp_store.update(&mut cx, |lsp_store, cx| {
 9235                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9236                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9237                        let key = LspKey {
 9238                            request_type: TypeId::of::<SemanticTokensFull>(),
 9239                            server_queried: server_id,
 9240                        };
 9241                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9242                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9243                                lsp_requests.clear();
 9244                            };
 9245                        }
 9246
 9247                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9248                            lsp_request_id,
 9249                            cx.spawn(async move |lsp_store, cx| {
 9250                                let tokens_fetch = lsp_store
 9251                                    .update(cx, |lsp_store, cx| {
 9252                                        lsp_store
 9253                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9254                                    })
 9255                                    .ok();
 9256                                if let Some(tokens_fetch) = tokens_fetch {
 9257                                    let new_tokens = tokens_fetch.await;
 9258                                    if let Some(new_tokens) = new_tokens {
 9259                                        lsp_store
 9260                                            .update(cx, |lsp_store, cx| {
 9261                                                let response = new_tokens
 9262                                                    .into_iter()
 9263                                                    .map(|(server_id, response)| {
 9264                                                        (
 9265                                                            server_id.to_proto(),
 9266                                                            SemanticTokensFull::response_to_proto(
 9267                                                                response,
 9268                                                                lsp_store,
 9269                                                                sender_id,
 9270                                                                &buffer_version,
 9271                                                                cx,
 9272                                                            ),
 9273                                                        )
 9274                                                    })
 9275                                                    .collect::<HashMap<_, _>>();
 9276                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9277                                                    project_id,
 9278                                                    lsp_request_id,
 9279                                                    response,
 9280                                                ) {
 9281                                                    Ok(()) => {}
 9282                                                    Err(e) => {
 9283                                                        log::error!(
 9284                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9285                                                        )
 9286                                                    }
 9287                                                }
 9288                                            })
 9289                                            .ok();
 9290                                    }
 9291                                }
 9292                            }),
 9293                        );
 9294                    }
 9295                });
 9296            }
 9297        }
 9298        Ok(proto::Ack {})
 9299    }
 9300
 9301    async fn handle_lsp_query_response(
 9302        lsp_store: Entity<Self>,
 9303        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9304        cx: AsyncApp,
 9305    ) -> Result<()> {
 9306        lsp_store.read_with(&cx, |lsp_store, _| {
 9307            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9308                upstream_client.handle_lsp_response(envelope.clone());
 9309            }
 9310        });
 9311        Ok(())
 9312    }
 9313
 9314    async fn handle_apply_code_action(
 9315        this: Entity<Self>,
 9316        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9317        mut cx: AsyncApp,
 9318    ) -> Result<proto::ApplyCodeActionResponse> {
 9319        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9320        let action =
 9321            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9322        let apply_code_action = this.update(&mut cx, |this, cx| {
 9323            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9324            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9325            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9326        })?;
 9327
 9328        let project_transaction = apply_code_action.await?;
 9329        let project_transaction = this.update(&mut cx, |this, cx| {
 9330            this.buffer_store.update(cx, |buffer_store, cx| {
 9331                buffer_store.serialize_project_transaction_for_peer(
 9332                    project_transaction,
 9333                    sender_id,
 9334                    cx,
 9335                )
 9336            })
 9337        });
 9338        Ok(proto::ApplyCodeActionResponse {
 9339            transaction: Some(project_transaction),
 9340        })
 9341    }
 9342
 9343    async fn handle_register_buffer_with_language_servers(
 9344        this: Entity<Self>,
 9345        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9346        mut cx: AsyncApp,
 9347    ) -> Result<proto::Ack> {
 9348        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9349        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9350        this.update(&mut cx, |this, cx| {
 9351            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9352                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9353                    project_id: upstream_project_id,
 9354                    buffer_id: buffer_id.to_proto(),
 9355                    only_servers: envelope.payload.only_servers,
 9356                });
 9357            }
 9358
 9359            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9360                anyhow::bail!("buffer is not open");
 9361            };
 9362
 9363            let handle = this.register_buffer_with_language_servers(
 9364                &buffer,
 9365                envelope
 9366                    .payload
 9367                    .only_servers
 9368                    .into_iter()
 9369                    .filter_map(|selector| {
 9370                        Some(match selector.selector? {
 9371                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9372                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9373                            }
 9374                            proto::language_server_selector::Selector::Name(name) => {
 9375                                LanguageServerSelector::Name(LanguageServerName(
 9376                                    SharedString::from(name),
 9377                                ))
 9378                            }
 9379                        })
 9380                    })
 9381                    .collect(),
 9382                false,
 9383                cx,
 9384            );
 9385            // Pull diagnostics for the buffer even if it was already registered.
 9386            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9387            // but it's unclear if we need it.
 9388            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9389                .detach();
 9390            this.buffer_store().update(cx, |buffer_store, _| {
 9391                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9392            });
 9393
 9394            Ok(())
 9395        })?;
 9396        Ok(proto::Ack {})
 9397    }
 9398
 9399    async fn handle_rename_project_entry(
 9400        this: Entity<Self>,
 9401        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9402        mut cx: AsyncApp,
 9403    ) -> Result<proto::ProjectEntryResponse> {
 9404        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9405        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9406        let new_path =
 9407            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9408
 9409        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9410            .update(&mut cx, |this, cx| {
 9411                let (worktree, entry) = this
 9412                    .worktree_store
 9413                    .read(cx)
 9414                    .worktree_and_entry_for_id(entry_id, cx)?;
 9415                let new_worktree = this
 9416                    .worktree_store
 9417                    .read(cx)
 9418                    .worktree_for_id(new_worktree_id, cx)?;
 9419                Some((
 9420                    this.worktree_store.clone(),
 9421                    worktree,
 9422                    new_worktree,
 9423                    entry.clone(),
 9424                ))
 9425            })
 9426            .context("worktree not found")?;
 9427        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9428            (worktree.absolutize(&old_entry.path), worktree.id())
 9429        });
 9430        let new_abs_path =
 9431            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9432
 9433        let _transaction = Self::will_rename_entry(
 9434            this.downgrade(),
 9435            old_worktree_id,
 9436            &old_abs_path,
 9437            &new_abs_path,
 9438            old_entry.is_dir(),
 9439            cx.clone(),
 9440        )
 9441        .await;
 9442        let response = WorktreeStore::handle_rename_project_entry(
 9443            worktree_store,
 9444            envelope.payload,
 9445            cx.clone(),
 9446        )
 9447        .await;
 9448        this.read_with(&cx, |this, _| {
 9449            this.did_rename_entry(
 9450                old_worktree_id,
 9451                &old_abs_path,
 9452                &new_abs_path,
 9453                old_entry.is_dir(),
 9454            );
 9455        });
 9456        response
 9457    }
 9458
 9459    async fn handle_update_diagnostic_summary(
 9460        this: Entity<Self>,
 9461        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9462        mut cx: AsyncApp,
 9463    ) -> Result<()> {
 9464        this.update(&mut cx, |lsp_store, cx| {
 9465            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9466            let mut updated_diagnostics_paths = HashMap::default();
 9467            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9468            for message_summary in envelope
 9469                .payload
 9470                .summary
 9471                .into_iter()
 9472                .chain(envelope.payload.more_summaries)
 9473            {
 9474                let project_path = ProjectPath {
 9475                    worktree_id,
 9476                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9477                };
 9478                let path = project_path.path.clone();
 9479                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9480                let summary = DiagnosticSummary {
 9481                    error_count: message_summary.error_count as usize,
 9482                    warning_count: message_summary.warning_count as usize,
 9483                };
 9484
 9485                if summary.is_empty() {
 9486                    if let Some(worktree_summaries) =
 9487                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9488                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9489                    {
 9490                        summaries.remove(&server_id);
 9491                        if summaries.is_empty() {
 9492                            worktree_summaries.remove(&path);
 9493                        }
 9494                    }
 9495                } else {
 9496                    lsp_store
 9497                        .diagnostic_summaries
 9498                        .entry(worktree_id)
 9499                        .or_default()
 9500                        .entry(path)
 9501                        .or_default()
 9502                        .insert(server_id, summary);
 9503                }
 9504
 9505                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9506                    match &mut diagnostics_summary {
 9507                        Some(diagnostics_summary) => {
 9508                            diagnostics_summary
 9509                                .more_summaries
 9510                                .push(proto::DiagnosticSummary {
 9511                                    path: project_path.path.as_ref().to_proto(),
 9512                                    language_server_id: server_id.0 as u64,
 9513                                    error_count: summary.error_count as u32,
 9514                                    warning_count: summary.warning_count as u32,
 9515                                })
 9516                        }
 9517                        None => {
 9518                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9519                                project_id: *project_id,
 9520                                worktree_id: worktree_id.to_proto(),
 9521                                summary: Some(proto::DiagnosticSummary {
 9522                                    path: project_path.path.as_ref().to_proto(),
 9523                                    language_server_id: server_id.0 as u64,
 9524                                    error_count: summary.error_count as u32,
 9525                                    warning_count: summary.warning_count as u32,
 9526                                }),
 9527                                more_summaries: Vec::new(),
 9528                            })
 9529                        }
 9530                    }
 9531                }
 9532                updated_diagnostics_paths
 9533                    .entry(server_id)
 9534                    .or_insert_with(Vec::new)
 9535                    .push(project_path);
 9536            }
 9537
 9538            if let Some((diagnostics_summary, (downstream_client, _))) =
 9539                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9540            {
 9541                downstream_client.send(diagnostics_summary).log_err();
 9542            }
 9543            for (server_id, paths) in updated_diagnostics_paths {
 9544                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9545            }
 9546            Ok(())
 9547        })
 9548    }
 9549
 9550    async fn handle_start_language_server(
 9551        lsp_store: Entity<Self>,
 9552        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9553        mut cx: AsyncApp,
 9554    ) -> Result<()> {
 9555        let server = envelope.payload.server.context("invalid server")?;
 9556        let server_capabilities =
 9557            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9558                .with_context(|| {
 9559                    format!(
 9560                        "incorrect server capabilities {}",
 9561                        envelope.payload.capabilities
 9562                    )
 9563                })?;
 9564        lsp_store.update(&mut cx, |lsp_store, cx| {
 9565            let server_id = LanguageServerId(server.id as usize);
 9566            let server_name = LanguageServerName::from_proto(server.name.clone());
 9567            lsp_store
 9568                .lsp_server_capabilities
 9569                .insert(server_id, server_capabilities);
 9570            lsp_store.language_server_statuses.insert(
 9571                server_id,
 9572                LanguageServerStatus {
 9573                    name: server_name.clone(),
 9574                    server_version: None,
 9575                    server_readable_version: None,
 9576                    pending_work: Default::default(),
 9577                    has_pending_diagnostic_updates: false,
 9578                    progress_tokens: Default::default(),
 9579                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9580                    binary: None,
 9581                    configuration: None,
 9582                    workspace_folders: BTreeSet::new(),
 9583                    process_id: None,
 9584                },
 9585            );
 9586            cx.emit(LspStoreEvent::LanguageServerAdded(
 9587                server_id,
 9588                server_name,
 9589                server.worktree_id.map(WorktreeId::from_proto),
 9590            ));
 9591            cx.notify();
 9592        });
 9593        Ok(())
 9594    }
 9595
 9596    async fn handle_update_language_server(
 9597        lsp_store: Entity<Self>,
 9598        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9599        mut cx: AsyncApp,
 9600    ) -> Result<()> {
 9601        lsp_store.update(&mut cx, |lsp_store, cx| {
 9602            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9603
 9604            match envelope.payload.variant.context("invalid variant")? {
 9605                proto::update_language_server::Variant::WorkStart(payload) => {
 9606                    lsp_store.on_lsp_work_start(
 9607                        language_server_id,
 9608                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9609                            .context("invalid progress token value")?,
 9610                        LanguageServerProgress {
 9611                            title: payload.title,
 9612                            is_disk_based_diagnostics_progress: false,
 9613                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9614                            message: payload.message,
 9615                            percentage: payload.percentage.map(|p| p as usize),
 9616                            last_update_at: cx.background_executor().now(),
 9617                        },
 9618                        cx,
 9619                    );
 9620                }
 9621                proto::update_language_server::Variant::WorkProgress(payload) => {
 9622                    lsp_store.on_lsp_work_progress(
 9623                        language_server_id,
 9624                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9625                            .context("invalid progress token value")?,
 9626                        LanguageServerProgress {
 9627                            title: None,
 9628                            is_disk_based_diagnostics_progress: false,
 9629                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9630                            message: payload.message,
 9631                            percentage: payload.percentage.map(|p| p as usize),
 9632                            last_update_at: cx.background_executor().now(),
 9633                        },
 9634                        cx,
 9635                    );
 9636                }
 9637
 9638                proto::update_language_server::Variant::WorkEnd(payload) => {
 9639                    lsp_store.on_lsp_work_end(
 9640                        language_server_id,
 9641                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9642                            .context("invalid progress token value")?,
 9643                        cx,
 9644                    );
 9645                }
 9646
 9647                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9648                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9649                }
 9650
 9651                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9652                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9653                }
 9654
 9655                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9656                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9657                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9658                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9659                        language_server_id,
 9660                        name: envelope
 9661                            .payload
 9662                            .server_name
 9663                            .map(SharedString::new)
 9664                            .map(LanguageServerName),
 9665                        message: non_lsp,
 9666                    });
 9667                }
 9668            }
 9669
 9670            Ok(())
 9671        })
 9672    }
 9673
 9674    async fn handle_language_server_log(
 9675        this: Entity<Self>,
 9676        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9677        mut cx: AsyncApp,
 9678    ) -> Result<()> {
 9679        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9680        let log_type = envelope
 9681            .payload
 9682            .log_type
 9683            .map(LanguageServerLogType::from_proto)
 9684            .context("invalid language server log type")?;
 9685
 9686        let message = envelope.payload.message;
 9687
 9688        this.update(&mut cx, |_, cx| {
 9689            cx.emit(LspStoreEvent::LanguageServerLog(
 9690                language_server_id,
 9691                log_type,
 9692                message,
 9693            ));
 9694        });
 9695        Ok(())
 9696    }
 9697
 9698    async fn handle_lsp_ext_cancel_flycheck(
 9699        lsp_store: Entity<Self>,
 9700        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9701        cx: AsyncApp,
 9702    ) -> Result<proto::Ack> {
 9703        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9704        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9705            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9706                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9707            } else {
 9708                None
 9709            }
 9710        });
 9711        if let Some(task) = task {
 9712            task.context("handling lsp ext cancel flycheck")?;
 9713        }
 9714
 9715        Ok(proto::Ack {})
 9716    }
 9717
 9718    async fn handle_lsp_ext_run_flycheck(
 9719        lsp_store: Entity<Self>,
 9720        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9721        mut cx: AsyncApp,
 9722    ) -> Result<proto::Ack> {
 9723        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9724        lsp_store.update(&mut cx, |lsp_store, cx| {
 9725            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9726                let text_document = if envelope.payload.current_file_only {
 9727                    let buffer_id = envelope
 9728                        .payload
 9729                        .buffer_id
 9730                        .map(|id| BufferId::new(id))
 9731                        .transpose()?;
 9732                    buffer_id
 9733                        .and_then(|buffer_id| {
 9734                            lsp_store
 9735                                .buffer_store()
 9736                                .read(cx)
 9737                                .get(buffer_id)
 9738                                .and_then(|buffer| {
 9739                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9740                                })
 9741                                .map(|path| make_text_document_identifier(&path))
 9742                        })
 9743                        .transpose()?
 9744                } else {
 9745                    None
 9746                };
 9747                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9748                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9749                )?;
 9750            }
 9751            anyhow::Ok(())
 9752        })?;
 9753
 9754        Ok(proto::Ack {})
 9755    }
 9756
 9757    async fn handle_lsp_ext_clear_flycheck(
 9758        lsp_store: Entity<Self>,
 9759        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9760        cx: AsyncApp,
 9761    ) -> Result<proto::Ack> {
 9762        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9763        lsp_store.read_with(&cx, |lsp_store, _| {
 9764            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9765                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9766            } else {
 9767                None
 9768            }
 9769        });
 9770
 9771        Ok(proto::Ack {})
 9772    }
 9773
 9774    pub fn disk_based_diagnostics_started(
 9775        &mut self,
 9776        language_server_id: LanguageServerId,
 9777        cx: &mut Context<Self>,
 9778    ) {
 9779        if let Some(language_server_status) =
 9780            self.language_server_statuses.get_mut(&language_server_id)
 9781        {
 9782            language_server_status.has_pending_diagnostic_updates = true;
 9783        }
 9784
 9785        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9786        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9787            language_server_id,
 9788            name: self
 9789                .language_server_adapter_for_id(language_server_id)
 9790                .map(|adapter| adapter.name()),
 9791            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9792                Default::default(),
 9793            ),
 9794        })
 9795    }
 9796
 9797    pub fn disk_based_diagnostics_finished(
 9798        &mut self,
 9799        language_server_id: LanguageServerId,
 9800        cx: &mut Context<Self>,
 9801    ) {
 9802        if let Some(language_server_status) =
 9803            self.language_server_statuses.get_mut(&language_server_id)
 9804        {
 9805            language_server_status.has_pending_diagnostic_updates = false;
 9806        }
 9807
 9808        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9809        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9810            language_server_id,
 9811            name: self
 9812                .language_server_adapter_for_id(language_server_id)
 9813                .map(|adapter| adapter.name()),
 9814            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9815                Default::default(),
 9816            ),
 9817        })
 9818    }
 9819
 9820    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9821    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9822    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9823    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9824    // the language server might take some time to publish diagnostics.
 9825    fn simulate_disk_based_diagnostics_events_if_needed(
 9826        &mut self,
 9827        language_server_id: LanguageServerId,
 9828        cx: &mut Context<Self>,
 9829    ) {
 9830        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9831
 9832        let Some(LanguageServerState::Running {
 9833            simulate_disk_based_diagnostics_completion,
 9834            adapter,
 9835            ..
 9836        }) = self
 9837            .as_local_mut()
 9838            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9839        else {
 9840            return;
 9841        };
 9842
 9843        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9844            return;
 9845        }
 9846
 9847        let prev_task =
 9848            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9849                cx.background_executor()
 9850                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9851                    .await;
 9852
 9853                this.update(cx, |this, cx| {
 9854                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9855
 9856                    if let Some(LanguageServerState::Running {
 9857                        simulate_disk_based_diagnostics_completion,
 9858                        ..
 9859                    }) = this.as_local_mut().and_then(|local_store| {
 9860                        local_store.language_servers.get_mut(&language_server_id)
 9861                    }) {
 9862                        *simulate_disk_based_diagnostics_completion = None;
 9863                    }
 9864                })
 9865                .ok();
 9866            }));
 9867
 9868        if prev_task.is_none() {
 9869            self.disk_based_diagnostics_started(language_server_id, cx);
 9870        }
 9871    }
 9872
 9873    pub fn language_server_statuses(
 9874        &self,
 9875    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9876        self.language_server_statuses
 9877            .iter()
 9878            .map(|(key, value)| (*key, value))
 9879    }
 9880
 9881    pub(super) fn did_rename_entry(
 9882        &self,
 9883        worktree_id: WorktreeId,
 9884        old_path: &Path,
 9885        new_path: &Path,
 9886        is_dir: bool,
 9887    ) {
 9888        maybe!({
 9889            let local_store = self.as_local()?;
 9890
 9891            let old_uri = lsp::Uri::from_file_path(old_path)
 9892                .ok()
 9893                .map(|uri| uri.to_string())?;
 9894            let new_uri = lsp::Uri::from_file_path(new_path)
 9895                .ok()
 9896                .map(|uri| uri.to_string())?;
 9897
 9898            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9899                let Some(filter) = local_store
 9900                    .language_server_paths_watched_for_rename
 9901                    .get(&language_server.server_id())
 9902                else {
 9903                    continue;
 9904                };
 9905
 9906                if filter.should_send_did_rename(&old_uri, is_dir) {
 9907                    language_server
 9908                        .notify::<DidRenameFiles>(RenameFilesParams {
 9909                            files: vec![FileRename {
 9910                                old_uri: old_uri.clone(),
 9911                                new_uri: new_uri.clone(),
 9912                            }],
 9913                        })
 9914                        .ok();
 9915                }
 9916            }
 9917            Some(())
 9918        });
 9919    }
 9920
 9921    pub(super) fn will_rename_entry(
 9922        this: WeakEntity<Self>,
 9923        worktree_id: WorktreeId,
 9924        old_path: &Path,
 9925        new_path: &Path,
 9926        is_dir: bool,
 9927        cx: AsyncApp,
 9928    ) -> Task<ProjectTransaction> {
 9929        let old_uri = lsp::Uri::from_file_path(old_path)
 9930            .ok()
 9931            .map(|uri| uri.to_string());
 9932        let new_uri = lsp::Uri::from_file_path(new_path)
 9933            .ok()
 9934            .map(|uri| uri.to_string());
 9935        cx.spawn(async move |cx| {
 9936            let mut tasks = vec![];
 9937            this.update(cx, |this, cx| {
 9938                let local_store = this.as_local()?;
 9939                let old_uri = old_uri?;
 9940                let new_uri = new_uri?;
 9941                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9942                    let Some(filter) = local_store
 9943                        .language_server_paths_watched_for_rename
 9944                        .get(&language_server.server_id())
 9945                    else {
 9946                        continue;
 9947                    };
 9948
 9949                    if !filter.should_send_will_rename(&old_uri, is_dir) {
 9950                        continue;
 9951                    }
 9952                    let request_timeout = ProjectSettings::get_global(cx)
 9953                        .global_lsp_settings
 9954                        .get_request_timeout();
 9955
 9956                    let apply_edit = cx.spawn({
 9957                        let old_uri = old_uri.clone();
 9958                        let new_uri = new_uri.clone();
 9959                        let language_server = language_server.clone();
 9960                        async move |this, cx| {
 9961                            let edit = language_server
 9962                                .request::<WillRenameFiles>(
 9963                                    RenameFilesParams {
 9964                                        files: vec![FileRename { old_uri, new_uri }],
 9965                                    },
 9966                                    request_timeout,
 9967                                )
 9968                                .await
 9969                                .into_response()
 9970                                .context("will rename files")
 9971                                .log_err()
 9972                                .flatten()?;
 9973
 9974                            LocalLspStore::deserialize_workspace_edit(
 9975                                this.upgrade()?,
 9976                                edit,
 9977                                false,
 9978                                language_server.clone(),
 9979                                cx,
 9980                            )
 9981                            .await
 9982                            .ok()
 9983                        }
 9984                    });
 9985                    tasks.push(apply_edit);
 9986                }
 9987                Some(())
 9988            })
 9989            .ok()
 9990            .flatten();
 9991            let mut merged_transaction = ProjectTransaction::default();
 9992            for task in tasks {
 9993                // Await on tasks sequentially so that the order of application of edits is deterministic
 9994                // (at least with regards to the order of registration of language servers)
 9995                if let Some(transaction) = task.await {
 9996                    for (buffer, buffer_transaction) in transaction.0 {
 9997                        merged_transaction.0.insert(buffer, buffer_transaction);
 9998                    }
 9999                }
10000            }
10001            merged_transaction
10002        })
10003    }
10004
10005    fn lsp_notify_abs_paths_changed(
10006        &mut self,
10007        server_id: LanguageServerId,
10008        changes: Vec<PathEvent>,
10009    ) {
10010        maybe!({
10011            let server = self.language_server_for_id(server_id)?;
10012            let changes = changes
10013                .into_iter()
10014                .filter_map(|event| {
10015                    let typ = match event.kind? {
10016                        PathEventKind::Created => lsp::FileChangeType::CREATED,
10017                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
10018                        PathEventKind::Changed | PathEventKind::Rescan => {
10019                            lsp::FileChangeType::CHANGED
10020                        }
10021                    };
10022                    Some(lsp::FileEvent {
10023                        uri: file_path_to_lsp_url(&event.path).log_err()?,
10024                        typ,
10025                    })
10026                })
10027                .collect::<Vec<_>>();
10028            if !changes.is_empty() {
10029                server
10030                    .notify::<lsp::notification::DidChangeWatchedFiles>(
10031                        lsp::DidChangeWatchedFilesParams { changes },
10032                    )
10033                    .ok();
10034            }
10035            Some(())
10036        });
10037    }
10038
10039    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
10040        self.as_local()?.language_server_for_id(id)
10041    }
10042
10043    fn on_lsp_progress(
10044        &mut self,
10045        progress_params: lsp::ProgressParams,
10046        language_server_id: LanguageServerId,
10047        disk_based_diagnostics_progress_token: Option<String>,
10048        cx: &mut Context<Self>,
10049    ) {
10050        match progress_params.value {
10051            lsp::ProgressParamsValue::WorkDone(progress) => {
10052                self.handle_work_done_progress(
10053                    progress,
10054                    language_server_id,
10055                    disk_based_diagnostics_progress_token,
10056                    ProgressToken::from_lsp(progress_params.token),
10057                    cx,
10058                );
10059            }
10060            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
10061                let registration_id = match progress_params.token {
10062                    lsp::NumberOrString::Number(_) => None,
10063                    lsp::NumberOrString::String(token) => token
10064                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
10065                        .map(|(_, id)| id.to_owned()),
10066                };
10067                if let Some(LanguageServerState::Running {
10068                    workspace_diagnostics_refresh_tasks,
10069                    ..
10070                }) = self
10071                    .as_local_mut()
10072                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
10073                    && let Some(workspace_diagnostics) =
10074                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
10075                {
10076                    workspace_diagnostics.progress_tx.try_send(()).ok();
10077                    self.apply_workspace_diagnostic_report(
10078                        language_server_id,
10079                        report,
10080                        registration_id.map(SharedString::from),
10081                        cx,
10082                    )
10083                }
10084            }
10085        }
10086    }
10087
10088    fn handle_work_done_progress(
10089        &mut self,
10090        progress: lsp::WorkDoneProgress,
10091        language_server_id: LanguageServerId,
10092        disk_based_diagnostics_progress_token: Option<String>,
10093        token: ProgressToken,
10094        cx: &mut Context<Self>,
10095    ) {
10096        let language_server_status =
10097            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10098                status
10099            } else {
10100                return;
10101            };
10102
10103        if !language_server_status.progress_tokens.contains(&token) {
10104            return;
10105        }
10106
10107        let is_disk_based_diagnostics_progress =
10108            if let (Some(disk_based_token), ProgressToken::String(token)) =
10109                (&disk_based_diagnostics_progress_token, &token)
10110            {
10111                token.starts_with(disk_based_token)
10112            } else {
10113                false
10114            };
10115
10116        match progress {
10117            lsp::WorkDoneProgress::Begin(report) => {
10118                if is_disk_based_diagnostics_progress {
10119                    self.disk_based_diagnostics_started(language_server_id, cx);
10120                }
10121                self.on_lsp_work_start(
10122                    language_server_id,
10123                    token.clone(),
10124                    LanguageServerProgress {
10125                        title: Some(report.title),
10126                        is_disk_based_diagnostics_progress,
10127                        is_cancellable: report.cancellable.unwrap_or(false),
10128                        message: report.message.clone(),
10129                        percentage: report.percentage.map(|p| p as usize),
10130                        last_update_at: cx.background_executor().now(),
10131                    },
10132                    cx,
10133                );
10134            }
10135            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10136                language_server_id,
10137                token,
10138                LanguageServerProgress {
10139                    title: None,
10140                    is_disk_based_diagnostics_progress,
10141                    is_cancellable: report.cancellable.unwrap_or(false),
10142                    message: report.message,
10143                    percentage: report.percentage.map(|p| p as usize),
10144                    last_update_at: cx.background_executor().now(),
10145                },
10146                cx,
10147            ),
10148            lsp::WorkDoneProgress::End(_) => {
10149                language_server_status.progress_tokens.remove(&token);
10150                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10151                if is_disk_based_diagnostics_progress {
10152                    self.disk_based_diagnostics_finished(language_server_id, cx);
10153                }
10154            }
10155        }
10156    }
10157
10158    fn on_lsp_work_start(
10159        &mut self,
10160        language_server_id: LanguageServerId,
10161        token: ProgressToken,
10162        progress: LanguageServerProgress,
10163        cx: &mut Context<Self>,
10164    ) {
10165        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10166            status.pending_work.insert(token.clone(), progress.clone());
10167            cx.notify();
10168        }
10169        cx.emit(LspStoreEvent::LanguageServerUpdate {
10170            language_server_id,
10171            name: self
10172                .language_server_adapter_for_id(language_server_id)
10173                .map(|adapter| adapter.name()),
10174            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10175                token: Some(token.to_proto()),
10176                title: progress.title,
10177                message: progress.message,
10178                percentage: progress.percentage.map(|p| p as u32),
10179                is_cancellable: Some(progress.is_cancellable),
10180            }),
10181        })
10182    }
10183
10184    fn on_lsp_work_progress(
10185        &mut self,
10186        language_server_id: LanguageServerId,
10187        token: ProgressToken,
10188        progress: LanguageServerProgress,
10189        cx: &mut Context<Self>,
10190    ) {
10191        let mut did_update = false;
10192        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10193            match status.pending_work.entry(token.clone()) {
10194                btree_map::Entry::Vacant(entry) => {
10195                    entry.insert(progress.clone());
10196                    did_update = true;
10197                }
10198                btree_map::Entry::Occupied(mut entry) => {
10199                    let entry = entry.get_mut();
10200                    if (progress.last_update_at - entry.last_update_at)
10201                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10202                    {
10203                        entry.last_update_at = progress.last_update_at;
10204                        if progress.message.is_some() {
10205                            entry.message = progress.message.clone();
10206                        }
10207                        if progress.percentage.is_some() {
10208                            entry.percentage = progress.percentage;
10209                        }
10210                        if progress.is_cancellable != entry.is_cancellable {
10211                            entry.is_cancellable = progress.is_cancellable;
10212                        }
10213                        did_update = true;
10214                    }
10215                }
10216            }
10217        }
10218
10219        if did_update {
10220            cx.emit(LspStoreEvent::LanguageServerUpdate {
10221                language_server_id,
10222                name: self
10223                    .language_server_adapter_for_id(language_server_id)
10224                    .map(|adapter| adapter.name()),
10225                message: proto::update_language_server::Variant::WorkProgress(
10226                    proto::LspWorkProgress {
10227                        token: Some(token.to_proto()),
10228                        message: progress.message,
10229                        percentage: progress.percentage.map(|p| p as u32),
10230                        is_cancellable: Some(progress.is_cancellable),
10231                    },
10232                ),
10233            })
10234        }
10235    }
10236
10237    fn on_lsp_work_end(
10238        &mut self,
10239        language_server_id: LanguageServerId,
10240        token: ProgressToken,
10241        cx: &mut Context<Self>,
10242    ) {
10243        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10244            if let Some(work) = status.pending_work.remove(&token)
10245                && !work.is_disk_based_diagnostics_progress
10246            {
10247                cx.emit(LspStoreEvent::RefreshInlayHints {
10248                    server_id: language_server_id,
10249                    request_id: None,
10250                });
10251            }
10252            cx.notify();
10253        }
10254
10255        cx.emit(LspStoreEvent::LanguageServerUpdate {
10256            language_server_id,
10257            name: self
10258                .language_server_adapter_for_id(language_server_id)
10259                .map(|adapter| adapter.name()),
10260            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10261                token: Some(token.to_proto()),
10262            }),
10263        })
10264    }
10265
10266    pub async fn handle_resolve_completion_documentation(
10267        this: Entity<Self>,
10268        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10269        mut cx: AsyncApp,
10270    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10271        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10272
10273        let completion = this
10274            .read_with(&cx, |this, cx| {
10275                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10276                let server = this
10277                    .language_server_for_id(id)
10278                    .with_context(|| format!("No language server {id}"))?;
10279
10280                let request_timeout = ProjectSettings::get_global(cx)
10281                    .global_lsp_settings
10282                    .get_request_timeout();
10283
10284                anyhow::Ok(cx.background_spawn(async move {
10285                    let can_resolve = server
10286                        .capabilities()
10287                        .completion_provider
10288                        .as_ref()
10289                        .and_then(|options| options.resolve_provider)
10290                        .unwrap_or(false);
10291                    if can_resolve {
10292                        server
10293                            .request::<lsp::request::ResolveCompletionItem>(
10294                                lsp_completion,
10295                                request_timeout,
10296                            )
10297                            .await
10298                            .into_response()
10299                            .context("resolve completion item")
10300                    } else {
10301                        anyhow::Ok(lsp_completion)
10302                    }
10303                }))
10304            })?
10305            .await?;
10306
10307        let mut documentation_is_markdown = false;
10308        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10309        let documentation = match completion.documentation {
10310            Some(lsp::Documentation::String(text)) => text,
10311
10312            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10313                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10314                value
10315            }
10316
10317            _ => String::new(),
10318        };
10319
10320        // If we have a new buffer_id, that means we're talking to a new client
10321        // and want to check for new text_edits in the completion too.
10322        let mut old_replace_start = None;
10323        let mut old_replace_end = None;
10324        let mut old_insert_start = None;
10325        let mut old_insert_end = None;
10326        let mut new_text = String::default();
10327        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10328            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10329                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10330                anyhow::Ok(buffer.read(cx).snapshot())
10331            })?;
10332
10333            if let Some(text_edit) = completion.text_edit.as_ref() {
10334                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10335
10336                if let Some(mut edit) = edit {
10337                    LineEnding::normalize(&mut edit.new_text);
10338
10339                    new_text = edit.new_text;
10340                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10341                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10342                    if let Some(insert_range) = edit.insert_range {
10343                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10344                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10345                    }
10346                }
10347            }
10348        }
10349
10350        Ok(proto::ResolveCompletionDocumentationResponse {
10351            documentation,
10352            documentation_is_markdown,
10353            old_replace_start,
10354            old_replace_end,
10355            new_text,
10356            lsp_completion,
10357            old_insert_start,
10358            old_insert_end,
10359        })
10360    }
10361
10362    async fn handle_on_type_formatting(
10363        this: Entity<Self>,
10364        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10365        mut cx: AsyncApp,
10366    ) -> Result<proto::OnTypeFormattingResponse> {
10367        let on_type_formatting = this.update(&mut cx, |this, cx| {
10368            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10369            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10370            let position = envelope
10371                .payload
10372                .position
10373                .and_then(deserialize_anchor)
10374                .context("invalid position")?;
10375            anyhow::Ok(this.apply_on_type_formatting(
10376                buffer,
10377                position,
10378                envelope.payload.trigger.clone(),
10379                cx,
10380            ))
10381        })?;
10382
10383        let transaction = on_type_formatting
10384            .await?
10385            .as_ref()
10386            .map(language::proto::serialize_transaction);
10387        Ok(proto::OnTypeFormattingResponse { transaction })
10388    }
10389
10390    async fn handle_pull_workspace_diagnostics(
10391        lsp_store: Entity<Self>,
10392        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10393        mut cx: AsyncApp,
10394    ) -> Result<proto::Ack> {
10395        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10396        lsp_store.update(&mut cx, |lsp_store, _| {
10397            lsp_store.pull_workspace_diagnostics(server_id);
10398        });
10399        Ok(proto::Ack {})
10400    }
10401
10402    async fn handle_open_buffer_for_symbol(
10403        this: Entity<Self>,
10404        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10405        mut cx: AsyncApp,
10406    ) -> Result<proto::OpenBufferForSymbolResponse> {
10407        let peer_id = envelope.original_sender_id().unwrap_or_default();
10408        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10409        let symbol = Self::deserialize_symbol(symbol)?;
10410        this.read_with(&cx, |this, _| {
10411            if let SymbolLocation::OutsideProject {
10412                abs_path,
10413                signature,
10414            } = &symbol.path
10415            {
10416                let new_signature = this.symbol_signature(&abs_path);
10417                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10418            }
10419            Ok(())
10420        })?;
10421        let buffer = this
10422            .update(&mut cx, |this, cx| {
10423                this.open_buffer_for_symbol(
10424                    &Symbol {
10425                        language_server_name: symbol.language_server_name,
10426                        source_worktree_id: symbol.source_worktree_id,
10427                        source_language_server_id: symbol.source_language_server_id,
10428                        path: symbol.path,
10429                        name: symbol.name,
10430                        kind: symbol.kind,
10431                        range: symbol.range,
10432                        label: CodeLabel::default(),
10433                        container_name: symbol.container_name,
10434                    },
10435                    cx,
10436                )
10437            })
10438            .await?;
10439
10440        this.update(&mut cx, |this, cx| {
10441            let is_private = buffer
10442                .read(cx)
10443                .file()
10444                .map(|f| f.is_private())
10445                .unwrap_or_default();
10446            if is_private {
10447                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10448            } else {
10449                this.buffer_store
10450                    .update(cx, |buffer_store, cx| {
10451                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10452                    })
10453                    .detach_and_log_err(cx);
10454                let buffer_id = buffer.read(cx).remote_id().to_proto();
10455                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10456            }
10457        })
10458    }
10459
10460    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10461        let mut hasher = Sha256::new();
10462        hasher.update(abs_path.to_string_lossy().as_bytes());
10463        hasher.update(self.nonce.to_be_bytes());
10464        hasher.finalize().as_slice().try_into().unwrap()
10465    }
10466
10467    pub async fn handle_get_project_symbols(
10468        this: Entity<Self>,
10469        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10470        mut cx: AsyncApp,
10471    ) -> Result<proto::GetProjectSymbolsResponse> {
10472        let symbols = this
10473            .update(&mut cx, |this, cx| {
10474                this.symbols(&envelope.payload.query, cx)
10475            })
10476            .await?;
10477
10478        Ok(proto::GetProjectSymbolsResponse {
10479            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10480        })
10481    }
10482
10483    pub async fn handle_restart_language_servers(
10484        this: Entity<Self>,
10485        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10486        mut cx: AsyncApp,
10487    ) -> Result<proto::Ack> {
10488        this.update(&mut cx, |lsp_store, cx| {
10489            let buffers =
10490                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10491            lsp_store.restart_language_servers_for_buffers(
10492                buffers,
10493                envelope
10494                    .payload
10495                    .only_servers
10496                    .into_iter()
10497                    .filter_map(|selector| {
10498                        Some(match selector.selector? {
10499                            proto::language_server_selector::Selector::ServerId(server_id) => {
10500                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10501                            }
10502                            proto::language_server_selector::Selector::Name(name) => {
10503                                LanguageServerSelector::Name(LanguageServerName(
10504                                    SharedString::from(name),
10505                                ))
10506                            }
10507                        })
10508                    })
10509                    .collect(),
10510                cx,
10511            );
10512        });
10513
10514        Ok(proto::Ack {})
10515    }
10516
10517    pub async fn handle_stop_language_servers(
10518        lsp_store: Entity<Self>,
10519        envelope: TypedEnvelope<proto::StopLanguageServers>,
10520        mut cx: AsyncApp,
10521    ) -> Result<proto::Ack> {
10522        lsp_store.update(&mut cx, |lsp_store, cx| {
10523            if envelope.payload.all
10524                && envelope.payload.also_servers.is_empty()
10525                && envelope.payload.buffer_ids.is_empty()
10526            {
10527                lsp_store.stop_all_language_servers(cx);
10528            } else {
10529                let buffers =
10530                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10531                lsp_store
10532                    .stop_language_servers_for_buffers(
10533                        buffers,
10534                        envelope
10535                            .payload
10536                            .also_servers
10537                            .into_iter()
10538                            .filter_map(|selector| {
10539                                Some(match selector.selector? {
10540                                    proto::language_server_selector::Selector::ServerId(
10541                                        server_id,
10542                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10543                                        server_id,
10544                                    )),
10545                                    proto::language_server_selector::Selector::Name(name) => {
10546                                        LanguageServerSelector::Name(LanguageServerName(
10547                                            SharedString::from(name),
10548                                        ))
10549                                    }
10550                                })
10551                            })
10552                            .collect(),
10553                        cx,
10554                    )
10555                    .detach_and_log_err(cx);
10556            }
10557        });
10558
10559        Ok(proto::Ack {})
10560    }
10561
10562    pub async fn handle_cancel_language_server_work(
10563        lsp_store: Entity<Self>,
10564        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10565        mut cx: AsyncApp,
10566    ) -> Result<proto::Ack> {
10567        lsp_store.update(&mut cx, |lsp_store, cx| {
10568            if let Some(work) = envelope.payload.work {
10569                match work {
10570                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10571                        let buffers =
10572                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10573                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10574                    }
10575                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10576                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10577                        let token = work
10578                            .token
10579                            .map(|token| {
10580                                ProgressToken::from_proto(token)
10581                                    .context("invalid work progress token")
10582                            })
10583                            .transpose()?;
10584                        lsp_store.cancel_language_server_work(server_id, token, cx);
10585                    }
10586                }
10587            }
10588            anyhow::Ok(())
10589        })?;
10590
10591        Ok(proto::Ack {})
10592    }
10593
10594    fn buffer_ids_to_buffers(
10595        &mut self,
10596        buffer_ids: impl Iterator<Item = u64>,
10597        cx: &mut Context<Self>,
10598    ) -> Vec<Entity<Buffer>> {
10599        buffer_ids
10600            .into_iter()
10601            .flat_map(|buffer_id| {
10602                self.buffer_store
10603                    .read(cx)
10604                    .get(BufferId::new(buffer_id).log_err()?)
10605            })
10606            .collect::<Vec<_>>()
10607    }
10608
10609    async fn handle_apply_additional_edits_for_completion(
10610        this: Entity<Self>,
10611        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10612        mut cx: AsyncApp,
10613    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10614        let (buffer, completion, all_commit_ranges) = this.update(&mut cx, |this, cx| {
10615            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10616            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10617            let completion = Self::deserialize_completion(
10618                envelope.payload.completion.context("invalid completion")?,
10619            )?;
10620            let all_commit_ranges = envelope
10621                .payload
10622                .all_commit_ranges
10623                .into_iter()
10624                .map(language::proto::deserialize_anchor_range)
10625                .collect::<Result<Vec<_>, _>>()?;
10626            anyhow::Ok((buffer, completion, all_commit_ranges))
10627        })?;
10628
10629        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10630            this.apply_additional_edits_for_completion(
10631                buffer,
10632                Rc::new(RefCell::new(Box::new([Completion {
10633                    replace_range: completion.replace_range,
10634                    new_text: completion.new_text,
10635                    source: completion.source,
10636                    documentation: None,
10637                    label: CodeLabel::default(),
10638                    match_start: None,
10639                    snippet_deduplication_key: None,
10640                    insert_text_mode: None,
10641                    icon_path: None,
10642                    confirm: None,
10643                }]))),
10644                0,
10645                false,
10646                all_commit_ranges,
10647                cx,
10648            )
10649        });
10650
10651        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10652            transaction: apply_additional_edits
10653                .await?
10654                .as_ref()
10655                .map(language::proto::serialize_transaction),
10656        })
10657    }
10658
10659    pub fn last_formatting_failure(&self) -> Option<&str> {
10660        self.last_formatting_failure.as_deref()
10661    }
10662
10663    pub fn reset_last_formatting_failure(&mut self) {
10664        self.last_formatting_failure = None;
10665    }
10666
10667    pub fn environment_for_buffer(
10668        &self,
10669        buffer: &Entity<Buffer>,
10670        cx: &mut Context<Self>,
10671    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10672        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10673            environment.update(cx, |env, cx| {
10674                env.buffer_environment(buffer, &self.worktree_store, cx)
10675            })
10676        } else {
10677            Task::ready(None).shared()
10678        }
10679    }
10680
10681    pub fn format(
10682        &mut self,
10683        buffers: HashSet<Entity<Buffer>>,
10684        target: LspFormatTarget,
10685        push_to_history: bool,
10686        trigger: FormatTrigger,
10687        cx: &mut Context<Self>,
10688    ) -> Task<anyhow::Result<ProjectTransaction>> {
10689        let logger = zlog::scoped!("format");
10690        if self.as_local().is_some() {
10691            zlog::trace!(logger => "Formatting locally");
10692            let logger = zlog::scoped!(logger => "local");
10693            let buffers = buffers
10694                .into_iter()
10695                .map(|buffer_handle| {
10696                    let buffer = buffer_handle.read(cx);
10697                    let buffer_abs_path = File::from_dyn(buffer.file())
10698                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10699
10700                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10701                })
10702                .collect::<Vec<_>>();
10703
10704            cx.spawn(async move |lsp_store, cx| {
10705                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10706
10707                for (handle, abs_path, id) in buffers {
10708                    let env = lsp_store
10709                        .update(cx, |lsp_store, cx| {
10710                            lsp_store.environment_for_buffer(&handle, cx)
10711                        })?
10712                        .await;
10713
10714                    let ranges = match &target {
10715                        LspFormatTarget::Buffers => None,
10716                        LspFormatTarget::Ranges(ranges) => {
10717                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10718                        }
10719                    };
10720
10721                    formattable_buffers.push(FormattableBuffer {
10722                        handle,
10723                        abs_path,
10724                        env,
10725                        ranges,
10726                    });
10727                }
10728                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10729
10730                let format_timer = zlog::time!(logger => "Formatting buffers");
10731                let result = LocalLspStore::format_locally(
10732                    lsp_store.clone(),
10733                    formattable_buffers,
10734                    push_to_history,
10735                    trigger,
10736                    logger,
10737                    cx,
10738                )
10739                .await;
10740                format_timer.end();
10741
10742                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10743
10744                lsp_store.update(cx, |lsp_store, _| {
10745                    lsp_store.update_last_formatting_failure(&result);
10746                })?;
10747
10748                result
10749            })
10750        } else if let Some((client, project_id)) = self.upstream_client() {
10751            zlog::trace!(logger => "Formatting remotely");
10752            let logger = zlog::scoped!(logger => "remote");
10753
10754            let buffer_ranges = match &target {
10755                LspFormatTarget::Buffers => Vec::new(),
10756                LspFormatTarget::Ranges(ranges) => ranges
10757                    .iter()
10758                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10759                        buffer_id: buffer_id.to_proto(),
10760                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10761                    })
10762                    .collect(),
10763            };
10764
10765            let buffer_store = self.buffer_store();
10766            cx.spawn(async move |lsp_store, cx| {
10767                zlog::trace!(logger => "Sending remote format request");
10768                let request_timer = zlog::time!(logger => "remote format request");
10769                let result = client
10770                    .request(proto::FormatBuffers {
10771                        project_id,
10772                        trigger: trigger as i32,
10773                        buffer_ids: buffers
10774                            .iter()
10775                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10776                            .collect(),
10777                        buffer_ranges,
10778                    })
10779                    .await
10780                    .and_then(|result| result.transaction.context("missing transaction"));
10781                request_timer.end();
10782
10783                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10784
10785                lsp_store.update(cx, |lsp_store, _| {
10786                    lsp_store.update_last_formatting_failure(&result);
10787                })?;
10788
10789                let transaction_response = result?;
10790                let _timer = zlog::time!(logger => "deserializing project transaction");
10791                buffer_store
10792                    .update(cx, |buffer_store, cx| {
10793                        buffer_store.deserialize_project_transaction(
10794                            transaction_response,
10795                            push_to_history,
10796                            cx,
10797                        )
10798                    })
10799                    .await
10800            })
10801        } else {
10802            zlog::trace!(logger => "Not formatting");
10803            Task::ready(Ok(ProjectTransaction::default()))
10804        }
10805    }
10806
10807    async fn handle_format_buffers(
10808        this: Entity<Self>,
10809        envelope: TypedEnvelope<proto::FormatBuffers>,
10810        mut cx: AsyncApp,
10811    ) -> Result<proto::FormatBuffersResponse> {
10812        let sender_id = envelope.original_sender_id().unwrap_or_default();
10813        let format = this.update(&mut cx, |this, cx| {
10814            let mut buffers = HashSet::default();
10815            for buffer_id in &envelope.payload.buffer_ids {
10816                let buffer_id = BufferId::new(*buffer_id)?;
10817                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10818            }
10819
10820            let target = if envelope.payload.buffer_ranges.is_empty() {
10821                LspFormatTarget::Buffers
10822            } else {
10823                let mut ranges_map = BTreeMap::new();
10824                for buffer_range in &envelope.payload.buffer_ranges {
10825                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10826                    let ranges: Result<Vec<_>> = buffer_range
10827                        .ranges
10828                        .iter()
10829                        .map(|range| {
10830                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10831                        })
10832                        .collect();
10833                    ranges_map.insert(buffer_id, ranges?);
10834                }
10835                LspFormatTarget::Ranges(ranges_map)
10836            };
10837
10838            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10839            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10840        })?;
10841
10842        let project_transaction = format.await?;
10843        let project_transaction = this.update(&mut cx, |this, cx| {
10844            this.buffer_store.update(cx, |buffer_store, cx| {
10845                buffer_store.serialize_project_transaction_for_peer(
10846                    project_transaction,
10847                    sender_id,
10848                    cx,
10849                )
10850            })
10851        });
10852        Ok(proto::FormatBuffersResponse {
10853            transaction: Some(project_transaction),
10854        })
10855    }
10856
10857    async fn handle_apply_code_action_kind(
10858        this: Entity<Self>,
10859        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10860        mut cx: AsyncApp,
10861    ) -> Result<proto::ApplyCodeActionKindResponse> {
10862        let sender_id = envelope.original_sender_id().unwrap_or_default();
10863        let format = this.update(&mut cx, |this, cx| {
10864            let mut buffers = HashSet::default();
10865            for buffer_id in &envelope.payload.buffer_ids {
10866                let buffer_id = BufferId::new(*buffer_id)?;
10867                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10868            }
10869            let kind = match envelope.payload.kind.as_str() {
10870                "" => CodeActionKind::EMPTY,
10871                "quickfix" => CodeActionKind::QUICKFIX,
10872                "refactor" => CodeActionKind::REFACTOR,
10873                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10874                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10875                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10876                "source" => CodeActionKind::SOURCE,
10877                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10878                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10879                _ => anyhow::bail!(
10880                    "Invalid code action kind {}",
10881                    envelope.payload.kind.as_str()
10882                ),
10883            };
10884            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10885        })?;
10886
10887        let project_transaction = format.await?;
10888        let project_transaction = this.update(&mut cx, |this, cx| {
10889            this.buffer_store.update(cx, |buffer_store, cx| {
10890                buffer_store.serialize_project_transaction_for_peer(
10891                    project_transaction,
10892                    sender_id,
10893                    cx,
10894                )
10895            })
10896        });
10897        Ok(proto::ApplyCodeActionKindResponse {
10898            transaction: Some(project_transaction),
10899        })
10900    }
10901
10902    async fn shutdown_language_server(
10903        server_state: Option<LanguageServerState>,
10904        name: LanguageServerName,
10905        cx: &mut AsyncApp,
10906    ) {
10907        let server = match server_state {
10908            Some(LanguageServerState::Starting { startup, .. }) => {
10909                let mut timer = cx
10910                    .background_executor()
10911                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10912                    .fuse();
10913
10914                select! {
10915                    server = startup.fuse() => server,
10916                    () = timer => {
10917                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10918                        None
10919                    },
10920                }
10921            }
10922
10923            Some(LanguageServerState::Running { server, .. }) => Some(server),
10924
10925            None => None,
10926        };
10927
10928        let Some(server) = server else { return };
10929        if let Some(shutdown) = server.shutdown() {
10930            shutdown.await;
10931        }
10932    }
10933
10934    // Returns a list of all of the worktrees which no longer have a language server and the root path
10935    // for the stopped server
10936    fn stop_local_language_server(
10937        &mut self,
10938        server_id: LanguageServerId,
10939        cx: &mut Context<Self>,
10940    ) -> Task<()> {
10941        let local = match &mut self.mode {
10942            LspStoreMode::Local(local) => local,
10943            _ => {
10944                return Task::ready(());
10945            }
10946        };
10947
10948        // Remove this server ID from all entries in the given worktree.
10949        local
10950            .language_server_ids
10951            .retain(|_, state| state.id != server_id);
10952        self.buffer_store.update(cx, |buffer_store, cx| {
10953            for buffer in buffer_store.buffers() {
10954                buffer.update(cx, |buffer, cx| {
10955                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10956                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10957                });
10958            }
10959        });
10960
10961        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
10962        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10963            summaries.retain(|path, summaries_by_server_id| {
10964                if summaries_by_server_id.remove(&server_id).is_some() {
10965                    if let Some((client, project_id)) = self.downstream_client.clone() {
10966                        client
10967                            .send(proto::UpdateDiagnosticSummary {
10968                                project_id,
10969                                worktree_id: worktree_id.to_proto(),
10970                                summary: Some(proto::DiagnosticSummary {
10971                                    path: path.as_ref().to_proto(),
10972                                    language_server_id: server_id.0 as u64,
10973                                    error_count: 0,
10974                                    warning_count: 0,
10975                                }),
10976                                more_summaries: Vec::new(),
10977                            })
10978                            .log_err();
10979                    }
10980                    cleared_paths.push(ProjectPath {
10981                        worktree_id: *worktree_id,
10982                        path: path.clone(),
10983                    });
10984                    !summaries_by_server_id.is_empty()
10985                } else {
10986                    true
10987                }
10988            });
10989        }
10990        if !cleared_paths.is_empty() {
10991            cx.emit(LspStoreEvent::DiagnosticsUpdated {
10992                server_id,
10993                paths: cleared_paths,
10994            });
10995        }
10996
10997        let local = self.as_local_mut().unwrap();
10998        for diagnostics in local.diagnostics.values_mut() {
10999            diagnostics.retain(|_, diagnostics_by_server_id| {
11000                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
11001                    diagnostics_by_server_id.remove(ix);
11002                    !diagnostics_by_server_id.is_empty()
11003                } else {
11004                    true
11005                }
11006            });
11007        }
11008        local.language_server_watched_paths.remove(&server_id);
11009
11010        let server_state = local.language_servers.remove(&server_id);
11011        self.cleanup_lsp_data(server_id);
11012        let name = self
11013            .language_server_statuses
11014            .remove(&server_id)
11015            .map(|status| status.name)
11016            .or_else(|| {
11017                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
11018                    Some(adapter.name())
11019                } else {
11020                    None
11021                }
11022            });
11023
11024        if let Some(name) = name {
11025            log::info!("stopping language server {name}");
11026            self.languages
11027                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
11028            cx.notify();
11029
11030            return cx.spawn(async move |lsp_store, cx| {
11031                Self::shutdown_language_server(server_state, name.clone(), cx).await;
11032                lsp_store
11033                    .update(cx, |lsp_store, cx| {
11034                        lsp_store
11035                            .languages
11036                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
11037                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11038                        cx.notify();
11039                    })
11040                    .ok();
11041            });
11042        }
11043
11044        if server_state.is_some() {
11045            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11046        }
11047        Task::ready(())
11048    }
11049
11050    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
11051        self.shutdown_all_language_servers(cx).detach();
11052    }
11053
11054    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
11055        if let Some((client, project_id)) = self.upstream_client() {
11056            let request = client.request(proto::StopLanguageServers {
11057                project_id,
11058                buffer_ids: Vec::new(),
11059                also_servers: Vec::new(),
11060                all: true,
11061            });
11062            cx.background_spawn(async move {
11063                request.await.ok();
11064            })
11065        } else {
11066            let Some(local) = self.as_local_mut() else {
11067                return Task::ready(());
11068            };
11069            let language_servers_to_stop = local
11070                .language_server_ids
11071                .values()
11072                .map(|state| state.id)
11073                .collect();
11074            local.lsp_tree.remove_nodes(&language_servers_to_stop);
11075            let tasks = language_servers_to_stop
11076                .into_iter()
11077                .map(|server| self.stop_local_language_server(server, cx))
11078                .collect::<Vec<_>>();
11079            cx.background_spawn(async move {
11080                futures::future::join_all(tasks).await;
11081            })
11082        }
11083    }
11084
11085    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
11086        let buffers = self.buffer_store.read(cx).buffers().collect();
11087        self.restart_language_servers_for_buffers(buffers, HashSet::default(), cx);
11088    }
11089
11090    pub fn restart_language_servers_for_buffers(
11091        &mut self,
11092        buffers: Vec<Entity<Buffer>>,
11093        only_restart_servers: HashSet<LanguageServerSelector>,
11094        cx: &mut Context<Self>,
11095    ) {
11096        if let Some((client, project_id)) = self.upstream_client() {
11097            let request = client.request(proto::RestartLanguageServers {
11098                project_id,
11099                buffer_ids: buffers
11100                    .into_iter()
11101                    .map(|b| b.read(cx).remote_id().to_proto())
11102                    .collect(),
11103                only_servers: only_restart_servers
11104                    .into_iter()
11105                    .map(|selector| {
11106                        let selector = match selector {
11107                            LanguageServerSelector::Id(language_server_id) => {
11108                                proto::language_server_selector::Selector::ServerId(
11109                                    language_server_id.to_proto(),
11110                                )
11111                            }
11112                            LanguageServerSelector::Name(language_server_name) => {
11113                                proto::language_server_selector::Selector::Name(
11114                                    language_server_name.to_string(),
11115                                )
11116                            }
11117                        };
11118                        proto::LanguageServerSelector {
11119                            selector: Some(selector),
11120                        }
11121                    })
11122                    .collect(),
11123                all: false,
11124            });
11125            cx.background_spawn(request).detach_and_log_err(cx);
11126        } else {
11127            let stop_task = if only_restart_servers.is_empty() {
11128                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11129            } else {
11130                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11131            };
11132            cx.spawn(async move |lsp_store, cx| {
11133                stop_task.await;
11134                lsp_store.update(cx, |lsp_store, cx| {
11135                    for buffer in buffers {
11136                        lsp_store.register_buffer_with_language_servers(
11137                            &buffer,
11138                            only_restart_servers.clone(),
11139                            true,
11140                            cx,
11141                        );
11142                    }
11143                })
11144            })
11145            .detach();
11146        }
11147    }
11148
11149    pub fn stop_language_servers_for_buffers(
11150        &mut self,
11151        buffers: Vec<Entity<Buffer>>,
11152        also_stop_servers: HashSet<LanguageServerSelector>,
11153        cx: &mut Context<Self>,
11154    ) -> Task<Result<()>> {
11155        if let Some((client, project_id)) = self.upstream_client() {
11156            let request = client.request(proto::StopLanguageServers {
11157                project_id,
11158                buffer_ids: buffers
11159                    .into_iter()
11160                    .map(|b| b.read(cx).remote_id().to_proto())
11161                    .collect(),
11162                also_servers: also_stop_servers
11163                    .into_iter()
11164                    .map(|selector| {
11165                        let selector = match selector {
11166                            LanguageServerSelector::Id(language_server_id) => {
11167                                proto::language_server_selector::Selector::ServerId(
11168                                    language_server_id.to_proto(),
11169                                )
11170                            }
11171                            LanguageServerSelector::Name(language_server_name) => {
11172                                proto::language_server_selector::Selector::Name(
11173                                    language_server_name.to_string(),
11174                                )
11175                            }
11176                        };
11177                        proto::LanguageServerSelector {
11178                            selector: Some(selector),
11179                        }
11180                    })
11181                    .collect(),
11182                all: false,
11183            });
11184            cx.background_spawn(async move {
11185                let _ = request.await?;
11186                Ok(())
11187            })
11188        } else {
11189            let task =
11190                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11191            cx.background_spawn(async move {
11192                task.await;
11193                Ok(())
11194            })
11195        }
11196    }
11197
11198    fn stop_local_language_servers_for_buffers(
11199        &mut self,
11200        buffers: &[Entity<Buffer>],
11201        also_stop_servers: HashSet<LanguageServerSelector>,
11202        cx: &mut Context<Self>,
11203    ) -> Task<()> {
11204        let Some(local) = self.as_local_mut() else {
11205            return Task::ready(());
11206        };
11207        let mut language_server_names_to_stop = BTreeSet::default();
11208        let mut language_servers_to_stop = also_stop_servers
11209            .into_iter()
11210            .flat_map(|selector| match selector {
11211                LanguageServerSelector::Id(id) => Some(id),
11212                LanguageServerSelector::Name(name) => {
11213                    language_server_names_to_stop.insert(name);
11214                    None
11215                }
11216            })
11217            .collect::<BTreeSet<_>>();
11218
11219        let mut covered_worktrees = HashSet::default();
11220        for buffer in buffers {
11221            buffer.update(cx, |buffer, cx| {
11222                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11223                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11224                    && covered_worktrees.insert(worktree_id)
11225                {
11226                    language_server_names_to_stop.retain(|name| {
11227                        let old_ids_count = language_servers_to_stop.len();
11228                        let all_language_servers_with_this_name = local
11229                            .language_server_ids
11230                            .iter()
11231                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11232                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11233                        old_ids_count == language_servers_to_stop.len()
11234                    });
11235                }
11236            });
11237        }
11238        for name in language_server_names_to_stop {
11239            language_servers_to_stop.extend(
11240                local
11241                    .language_server_ids
11242                    .iter()
11243                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11244            );
11245        }
11246
11247        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11248        let tasks = language_servers_to_stop
11249            .into_iter()
11250            .map(|server| self.stop_local_language_server(server, cx))
11251            .collect::<Vec<_>>();
11252
11253        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11254    }
11255
11256    #[cfg(any(test, feature = "test-support"))]
11257    pub fn update_diagnostics(
11258        &mut self,
11259        server_id: LanguageServerId,
11260        diagnostics: lsp::PublishDiagnosticsParams,
11261        result_id: Option<SharedString>,
11262        source_kind: DiagnosticSourceKind,
11263        disk_based_sources: &[String],
11264        cx: &mut Context<Self>,
11265    ) -> Result<()> {
11266        self.merge_lsp_diagnostics(
11267            source_kind,
11268            vec![DocumentDiagnosticsUpdate {
11269                diagnostics,
11270                result_id,
11271                server_id,
11272                disk_based_sources: Cow::Borrowed(disk_based_sources),
11273                registration_id: None,
11274            }],
11275            |_, _, _| false,
11276            cx,
11277        )
11278    }
11279
11280    pub fn merge_lsp_diagnostics(
11281        &mut self,
11282        source_kind: DiagnosticSourceKind,
11283        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11284        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11285        cx: &mut Context<Self>,
11286    ) -> Result<()> {
11287        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11288        let updates = lsp_diagnostics
11289            .into_iter()
11290            .filter_map(|update| {
11291                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11292                Some(DocumentDiagnosticsUpdate {
11293                    diagnostics: self.lsp_to_document_diagnostics(
11294                        abs_path,
11295                        source_kind,
11296                        update.server_id,
11297                        update.diagnostics,
11298                        &update.disk_based_sources,
11299                        update.registration_id.clone(),
11300                    ),
11301                    result_id: update.result_id,
11302                    server_id: update.server_id,
11303                    disk_based_sources: update.disk_based_sources,
11304                    registration_id: update.registration_id,
11305                })
11306            })
11307            .collect();
11308        self.merge_diagnostic_entries(updates, merge, cx)?;
11309        Ok(())
11310    }
11311
11312    fn lsp_to_document_diagnostics(
11313        &mut self,
11314        document_abs_path: PathBuf,
11315        source_kind: DiagnosticSourceKind,
11316        server_id: LanguageServerId,
11317        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11318        disk_based_sources: &[String],
11319        registration_id: Option<SharedString>,
11320    ) -> DocumentDiagnostics {
11321        let mut diagnostics = Vec::default();
11322        let mut primary_diagnostic_group_ids = HashMap::default();
11323        let mut sources_by_group_id = HashMap::default();
11324        let mut supporting_diagnostics = HashMap::default();
11325
11326        let adapter = self.language_server_adapter_for_id(server_id);
11327
11328        // Ensure that primary diagnostics are always the most severe
11329        lsp_diagnostics
11330            .diagnostics
11331            .sort_by_key(|item| item.severity);
11332
11333        for diagnostic in &lsp_diagnostics.diagnostics {
11334            let source = diagnostic.source.as_ref();
11335            let range = range_from_lsp(diagnostic.range);
11336            let is_supporting = diagnostic
11337                .related_information
11338                .as_ref()
11339                .is_some_and(|infos| {
11340                    infos.iter().any(|info| {
11341                        primary_diagnostic_group_ids.contains_key(&(
11342                            source,
11343                            diagnostic.code.clone(),
11344                            range_from_lsp(info.location.range),
11345                        ))
11346                    })
11347                });
11348
11349            let is_unnecessary = diagnostic
11350                .tags
11351                .as_ref()
11352                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11353
11354            let underline = self
11355                .language_server_adapter_for_id(server_id)
11356                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11357
11358            if is_supporting {
11359                supporting_diagnostics.insert(
11360                    (source, diagnostic.code.clone(), range),
11361                    (diagnostic.severity, is_unnecessary),
11362                );
11363            } else {
11364                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11365                let is_disk_based =
11366                    source.is_some_and(|source| disk_based_sources.contains(source));
11367
11368                sources_by_group_id.insert(group_id, source);
11369                primary_diagnostic_group_ids
11370                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11371
11372                diagnostics.push(DiagnosticEntry {
11373                    range,
11374                    diagnostic: Diagnostic {
11375                        source: diagnostic.source.clone(),
11376                        source_kind,
11377                        code: diagnostic.code.clone(),
11378                        code_description: diagnostic
11379                            .code_description
11380                            .as_ref()
11381                            .and_then(|d| d.href.clone()),
11382                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11383                        markdown: adapter.as_ref().and_then(|adapter| {
11384                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11385                        }),
11386                        message: diagnostic.message.trim().to_string(),
11387                        group_id,
11388                        is_primary: true,
11389                        is_disk_based,
11390                        is_unnecessary,
11391                        underline,
11392                        data: diagnostic.data.clone(),
11393                        registration_id: registration_id.clone(),
11394                    },
11395                });
11396                if let Some(infos) = &diagnostic.related_information {
11397                    for info in infos {
11398                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11399                            let range = range_from_lsp(info.location.range);
11400                            diagnostics.push(DiagnosticEntry {
11401                                range,
11402                                diagnostic: Diagnostic {
11403                                    source: diagnostic.source.clone(),
11404                                    source_kind,
11405                                    code: diagnostic.code.clone(),
11406                                    code_description: diagnostic
11407                                        .code_description
11408                                        .as_ref()
11409                                        .and_then(|d| d.href.clone()),
11410                                    severity: DiagnosticSeverity::INFORMATION,
11411                                    markdown: adapter.as_ref().and_then(|adapter| {
11412                                        adapter.diagnostic_message_to_markdown(&info.message)
11413                                    }),
11414                                    message: info.message.trim().to_string(),
11415                                    group_id,
11416                                    is_primary: false,
11417                                    is_disk_based,
11418                                    is_unnecessary: false,
11419                                    underline,
11420                                    data: diagnostic.data.clone(),
11421                                    registration_id: registration_id.clone(),
11422                                },
11423                            });
11424                        }
11425                    }
11426                }
11427            }
11428        }
11429
11430        for entry in &mut diagnostics {
11431            let diagnostic = &mut entry.diagnostic;
11432            if !diagnostic.is_primary {
11433                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11434                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11435                    source,
11436                    diagnostic.code.clone(),
11437                    entry.range.clone(),
11438                )) {
11439                    if let Some(severity) = severity {
11440                        diagnostic.severity = severity;
11441                    }
11442                    diagnostic.is_unnecessary = is_unnecessary;
11443                }
11444            }
11445        }
11446
11447        DocumentDiagnostics {
11448            diagnostics,
11449            document_abs_path,
11450            version: lsp_diagnostics.version,
11451        }
11452    }
11453
11454    fn insert_newly_running_language_server(
11455        &mut self,
11456        adapter: Arc<CachedLspAdapter>,
11457        language_server: Arc<LanguageServer>,
11458        server_id: LanguageServerId,
11459        key: LanguageServerSeed,
11460        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11461        cx: &mut Context<Self>,
11462    ) {
11463        let Some(local) = self.as_local_mut() else {
11464            return;
11465        };
11466        // If the language server for this key doesn't match the server id, don't store the
11467        // server. Which will cause it to be dropped, killing the process
11468        if local
11469            .language_server_ids
11470            .get(&key)
11471            .map(|state| state.id != server_id)
11472            .unwrap_or(false)
11473        {
11474            return;
11475        }
11476
11477        // Update language_servers collection with Running variant of LanguageServerState
11478        // indicating that the server is up and running and ready
11479        let workspace_folders = workspace_folders.lock().clone();
11480        language_server.set_workspace_folders(workspace_folders);
11481
11482        let workspace_diagnostics_refresh_tasks = language_server
11483            .capabilities()
11484            .diagnostic_provider
11485            .and_then(|provider| {
11486                local
11487                    .language_server_dynamic_registrations
11488                    .entry(server_id)
11489                    .or_default()
11490                    .diagnostics
11491                    .entry(None)
11492                    .or_insert(provider.clone());
11493                let workspace_refresher =
11494                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11495
11496                Some((None, workspace_refresher))
11497            })
11498            .into_iter()
11499            .collect();
11500        local.language_servers.insert(
11501            server_id,
11502            LanguageServerState::Running {
11503                workspace_diagnostics_refresh_tasks,
11504                adapter: adapter.clone(),
11505                server: language_server.clone(),
11506                simulate_disk_based_diagnostics_completion: None,
11507            },
11508        );
11509        local
11510            .languages
11511            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11512        if let Some(file_ops_caps) = language_server
11513            .capabilities()
11514            .workspace
11515            .as_ref()
11516            .and_then(|ws| ws.file_operations.as_ref())
11517        {
11518            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11519            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11520            if did_rename_caps.or(will_rename_caps).is_some() {
11521                let watcher = RenamePathsWatchedForServer::default()
11522                    .with_did_rename_patterns(did_rename_caps)
11523                    .with_will_rename_patterns(will_rename_caps);
11524                local
11525                    .language_server_paths_watched_for_rename
11526                    .insert(server_id, watcher);
11527            }
11528        }
11529
11530        self.language_server_statuses.insert(
11531            server_id,
11532            LanguageServerStatus {
11533                name: language_server.name(),
11534                server_version: language_server.version(),
11535                server_readable_version: language_server.readable_version(),
11536                pending_work: Default::default(),
11537                has_pending_diagnostic_updates: false,
11538                progress_tokens: Default::default(),
11539                worktree: Some(key.worktree_id),
11540                binary: Some(language_server.binary().clone()),
11541                configuration: Some(language_server.configuration().clone()),
11542                workspace_folders: language_server.workspace_folders(),
11543                process_id: language_server.process_id(),
11544            },
11545        );
11546
11547        cx.emit(LspStoreEvent::LanguageServerAdded(
11548            server_id,
11549            language_server.name(),
11550            Some(key.worktree_id),
11551        ));
11552
11553        let server_capabilities = language_server.capabilities();
11554        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11555            downstream_client
11556                .send(proto::StartLanguageServer {
11557                    project_id: *project_id,
11558                    server: Some(proto::LanguageServer {
11559                        id: server_id.to_proto(),
11560                        name: language_server.name().to_string(),
11561                        worktree_id: Some(key.worktree_id.to_proto()),
11562                    }),
11563                    capabilities: serde_json::to_string(&server_capabilities)
11564                        .expect("serializing server LSP capabilities"),
11565                })
11566                .log_err();
11567        }
11568        self.lsp_server_capabilities
11569            .insert(server_id, server_capabilities);
11570
11571        // Tell the language server about every open buffer in the worktree that matches the language.
11572        // Also check for buffers in worktrees that reused this server
11573        let mut worktrees_using_server = vec![key.worktree_id];
11574        if let Some(local) = self.as_local() {
11575            // Find all worktrees that have this server in their language server tree
11576            for (worktree_id, servers) in &local.lsp_tree.instances {
11577                if *worktree_id != key.worktree_id {
11578                    for server_map in servers.roots.values() {
11579                        if server_map
11580                            .values()
11581                            .any(|(node, _)| node.id() == Some(server_id))
11582                        {
11583                            worktrees_using_server.push(*worktree_id);
11584                        }
11585                    }
11586                }
11587            }
11588        }
11589
11590        let mut buffer_paths_registered = Vec::new();
11591        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11592            let mut lsp_adapters = HashMap::default();
11593            for buffer_handle in buffer_store.buffers() {
11594                let buffer = buffer_handle.read(cx);
11595                let file = match File::from_dyn(buffer.file()) {
11596                    Some(file) => file,
11597                    None => continue,
11598                };
11599                let language = match buffer.language() {
11600                    Some(language) => language,
11601                    None => continue,
11602                };
11603
11604                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11605                    || !lsp_adapters
11606                        .entry(language.name())
11607                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11608                        .iter()
11609                        .any(|a| a.name == key.name)
11610                {
11611                    continue;
11612                }
11613                // didOpen
11614                let file = match file.as_local() {
11615                    Some(file) => file,
11616                    None => continue,
11617                };
11618
11619                let local = self.as_local_mut().unwrap();
11620
11621                let buffer_id = buffer.remote_id();
11622                if local.registered_buffers.contains_key(&buffer_id) {
11623                    let abs_path = file.abs_path(cx);
11624                    let uri = match lsp::Uri::from_file_path(&abs_path) {
11625                        Ok(uri) => uri,
11626                        Err(()) => {
11627                            log::error!("failed to convert path to URI: {:?}", abs_path);
11628                            continue;
11629                        }
11630                    };
11631
11632                    let versions = local
11633                        .buffer_snapshots
11634                        .entry(buffer_id)
11635                        .or_default()
11636                        .entry(server_id)
11637                        .and_modify(|_| {
11638                            assert!(
11639                            false,
11640                            "There should not be an existing snapshot for a newly inserted buffer"
11641                        )
11642                        })
11643                        .or_insert_with(|| {
11644                            vec![LspBufferSnapshot {
11645                                version: 0,
11646                                snapshot: buffer.text_snapshot(),
11647                            }]
11648                        });
11649
11650                    let snapshot = versions.last().unwrap();
11651                    let version = snapshot.version;
11652                    let initial_snapshot = &snapshot.snapshot;
11653                    language_server.register_buffer(
11654                        uri,
11655                        adapter.language_id(&language.name()),
11656                        version,
11657                        initial_snapshot.text(),
11658                    );
11659                    buffer_paths_registered.push((buffer_id, abs_path));
11660                    local
11661                        .buffers_opened_in_servers
11662                        .entry(buffer_id)
11663                        .or_default()
11664                        .insert(server_id);
11665                }
11666                buffer_handle.update(cx, |buffer, cx| {
11667                    buffer.set_completion_triggers(
11668                        server_id,
11669                        language_server
11670                            .capabilities()
11671                            .completion_provider
11672                            .as_ref()
11673                            .and_then(|provider| {
11674                                provider
11675                                    .trigger_characters
11676                                    .as_ref()
11677                                    .map(|characters| characters.iter().cloned().collect())
11678                            })
11679                            .unwrap_or_default(),
11680                        cx,
11681                    )
11682                });
11683            }
11684        });
11685
11686        for (buffer_id, abs_path) in buffer_paths_registered {
11687            cx.emit(LspStoreEvent::LanguageServerUpdate {
11688                language_server_id: server_id,
11689                name: Some(adapter.name()),
11690                message: proto::update_language_server::Variant::RegisteredForBuffer(
11691                    proto::RegisteredForBuffer {
11692                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11693                        buffer_id: buffer_id.to_proto(),
11694                    },
11695                ),
11696            });
11697        }
11698
11699        cx.notify();
11700    }
11701
11702    pub fn language_servers_running_disk_based_diagnostics(
11703        &self,
11704    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11705        self.language_server_statuses
11706            .iter()
11707            .filter_map(|(id, status)| {
11708                if status.has_pending_diagnostic_updates {
11709                    Some(*id)
11710                } else {
11711                    None
11712                }
11713            })
11714    }
11715
11716    pub(crate) fn cancel_language_server_work_for_buffers(
11717        &mut self,
11718        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11719        cx: &mut Context<Self>,
11720    ) {
11721        if let Some((client, project_id)) = self.upstream_client() {
11722            let request = client.request(proto::CancelLanguageServerWork {
11723                project_id,
11724                work: Some(proto::cancel_language_server_work::Work::Buffers(
11725                    proto::cancel_language_server_work::Buffers {
11726                        buffer_ids: buffers
11727                            .into_iter()
11728                            .map(|b| b.read(cx).remote_id().to_proto())
11729                            .collect(),
11730                    },
11731                )),
11732            });
11733            cx.background_spawn(request).detach_and_log_err(cx);
11734        } else if let Some(local) = self.as_local() {
11735            let servers = buffers
11736                .into_iter()
11737                .flat_map(|buffer| {
11738                    buffer.update(cx, |buffer, cx| {
11739                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11740                    })
11741                })
11742                .collect::<HashSet<_>>();
11743            for server_id in servers {
11744                self.cancel_language_server_work(server_id, None, cx);
11745            }
11746        }
11747    }
11748
11749    pub(crate) fn cancel_language_server_work(
11750        &mut self,
11751        server_id: LanguageServerId,
11752        token_to_cancel: Option<ProgressToken>,
11753        cx: &mut Context<Self>,
11754    ) {
11755        if let Some(local) = self.as_local() {
11756            let status = self.language_server_statuses.get(&server_id);
11757            let server = local.language_servers.get(&server_id);
11758            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11759            {
11760                for (token, progress) in &status.pending_work {
11761                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11762                        && token != token_to_cancel
11763                    {
11764                        continue;
11765                    }
11766                    if progress.is_cancellable {
11767                        server
11768                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11769                                WorkDoneProgressCancelParams {
11770                                    token: token.to_lsp(),
11771                                },
11772                            )
11773                            .ok();
11774                    }
11775                }
11776            }
11777        } else if let Some((client, project_id)) = self.upstream_client() {
11778            let request = client.request(proto::CancelLanguageServerWork {
11779                project_id,
11780                work: Some(
11781                    proto::cancel_language_server_work::Work::LanguageServerWork(
11782                        proto::cancel_language_server_work::LanguageServerWork {
11783                            language_server_id: server_id.to_proto(),
11784                            token: token_to_cancel.map(|token| token.to_proto()),
11785                        },
11786                    ),
11787                ),
11788            });
11789            cx.background_spawn(request).detach_and_log_err(cx);
11790        }
11791    }
11792
11793    fn register_supplementary_language_server(
11794        &mut self,
11795        id: LanguageServerId,
11796        name: LanguageServerName,
11797        server: Arc<LanguageServer>,
11798        cx: &mut Context<Self>,
11799    ) {
11800        if let Some(local) = self.as_local_mut() {
11801            local
11802                .supplementary_language_servers
11803                .insert(id, (name.clone(), server));
11804            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11805        }
11806    }
11807
11808    fn unregister_supplementary_language_server(
11809        &mut self,
11810        id: LanguageServerId,
11811        cx: &mut Context<Self>,
11812    ) {
11813        if let Some(local) = self.as_local_mut() {
11814            local.supplementary_language_servers.remove(&id);
11815            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11816        }
11817    }
11818
11819    pub(crate) fn supplementary_language_servers(
11820        &self,
11821    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11822        self.as_local().into_iter().flat_map(|local| {
11823            local
11824                .supplementary_language_servers
11825                .iter()
11826                .map(|(id, (name, _))| (*id, name.clone()))
11827        })
11828    }
11829
11830    pub fn language_server_adapter_for_id(
11831        &self,
11832        id: LanguageServerId,
11833    ) -> Option<Arc<CachedLspAdapter>> {
11834        self.as_local()
11835            .and_then(|local| local.language_servers.get(&id))
11836            .and_then(|language_server_state| match language_server_state {
11837                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11838                _ => None,
11839            })
11840    }
11841
11842    pub(super) fn update_local_worktree_language_servers(
11843        &mut self,
11844        worktree_handle: &Entity<Worktree>,
11845        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11846        cx: &mut Context<Self>,
11847    ) {
11848        if changes.is_empty() {
11849            return;
11850        }
11851
11852        let Some(local) = self.as_local() else { return };
11853
11854        local.prettier_store.update(cx, |prettier_store, cx| {
11855            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11856        });
11857
11858        let worktree_id = worktree_handle.read(cx).id();
11859        let mut language_server_ids = local
11860            .language_server_ids
11861            .iter()
11862            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11863            .collect::<Vec<_>>();
11864        language_server_ids.sort();
11865        language_server_ids.dedup();
11866
11867        // let abs_path = worktree_handle.read(cx).abs_path();
11868        for server_id in &language_server_ids {
11869            if let Some(LanguageServerState::Running { server, .. }) =
11870                local.language_servers.get(server_id)
11871                && let Some(watched_paths) = local
11872                    .language_server_watched_paths
11873                    .get(server_id)
11874                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11875            {
11876                let params = lsp::DidChangeWatchedFilesParams {
11877                    changes: changes
11878                        .iter()
11879                        .filter_map(|(path, _, change)| {
11880                            if !watched_paths.is_match(path.as_std_path()) {
11881                                return None;
11882                            }
11883                            let typ = match change {
11884                                PathChange::Loaded => return None,
11885                                PathChange::Added => lsp::FileChangeType::CREATED,
11886                                PathChange::Removed => lsp::FileChangeType::DELETED,
11887                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11888                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11889                            };
11890                            let uri = lsp::Uri::from_file_path(
11891                                worktree_handle.read(cx).absolutize(&path),
11892                            )
11893                            .ok()?;
11894                            Some(lsp::FileEvent { uri, typ })
11895                        })
11896                        .collect(),
11897                };
11898                if !params.changes.is_empty() {
11899                    server
11900                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11901                        .ok();
11902                }
11903            }
11904        }
11905        for (path, _, _) in changes {
11906            if let Some(file_name) = path.file_name()
11907                && local.watched_manifest_filenames.contains(file_name)
11908            {
11909                self.request_workspace_config_refresh();
11910                break;
11911            }
11912        }
11913    }
11914
11915    pub fn wait_for_remote_buffer(
11916        &mut self,
11917        id: BufferId,
11918        cx: &mut Context<Self>,
11919    ) -> Task<Result<Entity<Buffer>>> {
11920        self.buffer_store.update(cx, |buffer_store, cx| {
11921            buffer_store.wait_for_remote_buffer(id, cx)
11922        })
11923    }
11924
11925    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11926        let mut result = proto::Symbol {
11927            language_server_name: symbol.language_server_name.0.to_string(),
11928            source_worktree_id: symbol.source_worktree_id.to_proto(),
11929            language_server_id: symbol.source_language_server_id.to_proto(),
11930            name: symbol.name.clone(),
11931            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11932            start: Some(proto::PointUtf16 {
11933                row: symbol.range.start.0.row,
11934                column: symbol.range.start.0.column,
11935            }),
11936            end: Some(proto::PointUtf16 {
11937                row: symbol.range.end.0.row,
11938                column: symbol.range.end.0.column,
11939            }),
11940            worktree_id: Default::default(),
11941            path: Default::default(),
11942            signature: Default::default(),
11943            container_name: symbol.container_name.clone(),
11944        };
11945        match &symbol.path {
11946            SymbolLocation::InProject(path) => {
11947                result.worktree_id = path.worktree_id.to_proto();
11948                result.path = path.path.to_proto();
11949            }
11950            SymbolLocation::OutsideProject {
11951                abs_path,
11952                signature,
11953            } => {
11954                result.path = abs_path.to_string_lossy().into_owned();
11955                result.signature = signature.to_vec();
11956            }
11957        }
11958        result
11959    }
11960
11961    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11962        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11963        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11964        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11965
11966        let path = if serialized_symbol.signature.is_empty() {
11967            SymbolLocation::InProject(ProjectPath {
11968                worktree_id,
11969                path: RelPath::from_proto(&serialized_symbol.path)
11970                    .context("invalid symbol path")?,
11971            })
11972        } else {
11973            SymbolLocation::OutsideProject {
11974                abs_path: Path::new(&serialized_symbol.path).into(),
11975                signature: serialized_symbol
11976                    .signature
11977                    .try_into()
11978                    .map_err(|_| anyhow!("invalid signature"))?,
11979            }
11980        };
11981
11982        let start = serialized_symbol.start.context("invalid start")?;
11983        let end = serialized_symbol.end.context("invalid end")?;
11984        Ok(CoreSymbol {
11985            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11986            source_worktree_id,
11987            source_language_server_id: LanguageServerId::from_proto(
11988                serialized_symbol.language_server_id,
11989            ),
11990            path,
11991            name: serialized_symbol.name,
11992            range: Unclipped(PointUtf16::new(start.row, start.column))
11993                ..Unclipped(PointUtf16::new(end.row, end.column)),
11994            kind,
11995            container_name: serialized_symbol.container_name,
11996        })
11997    }
11998
11999    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
12000        let mut serialized_completion = proto::Completion {
12001            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
12002            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
12003            new_text: completion.new_text.clone(),
12004            ..proto::Completion::default()
12005        };
12006        match &completion.source {
12007            CompletionSource::Lsp {
12008                insert_range,
12009                server_id,
12010                lsp_completion,
12011                lsp_defaults,
12012                resolved,
12013            } => {
12014                let (old_insert_start, old_insert_end) = insert_range
12015                    .as_ref()
12016                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
12017                    .unzip();
12018
12019                serialized_completion.old_insert_start = old_insert_start;
12020                serialized_completion.old_insert_end = old_insert_end;
12021                serialized_completion.source = proto::completion::Source::Lsp as i32;
12022                serialized_completion.server_id = server_id.0 as u64;
12023                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
12024                serialized_completion.lsp_defaults = lsp_defaults
12025                    .as_deref()
12026                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
12027                serialized_completion.resolved = *resolved;
12028            }
12029            CompletionSource::BufferWord {
12030                word_range,
12031                resolved,
12032            } => {
12033                serialized_completion.source = proto::completion::Source::BufferWord as i32;
12034                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
12035                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
12036                serialized_completion.resolved = *resolved;
12037            }
12038            CompletionSource::Custom => {
12039                serialized_completion.source = proto::completion::Source::Custom as i32;
12040                serialized_completion.resolved = true;
12041            }
12042            CompletionSource::Dap { sort_text } => {
12043                serialized_completion.source = proto::completion::Source::Dap as i32;
12044                serialized_completion.sort_text = Some(sort_text.clone());
12045            }
12046        }
12047
12048        serialized_completion
12049    }
12050
12051    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
12052        let old_replace_start = completion
12053            .old_replace_start
12054            .and_then(deserialize_anchor)
12055            .context("invalid old start")?;
12056        let old_replace_end = completion
12057            .old_replace_end
12058            .and_then(deserialize_anchor)
12059            .context("invalid old end")?;
12060        let insert_range = {
12061            match completion.old_insert_start.zip(completion.old_insert_end) {
12062                Some((start, end)) => {
12063                    let start = deserialize_anchor(start).context("invalid insert old start")?;
12064                    let end = deserialize_anchor(end).context("invalid insert old end")?;
12065                    Some(start..end)
12066                }
12067                None => None,
12068            }
12069        };
12070        Ok(CoreCompletion {
12071            replace_range: old_replace_start..old_replace_end,
12072            new_text: completion.new_text,
12073            source: match proto::completion::Source::from_i32(completion.source) {
12074                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
12075                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
12076                    insert_range,
12077                    server_id: LanguageServerId::from_proto(completion.server_id),
12078                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
12079                    lsp_defaults: completion
12080                        .lsp_defaults
12081                        .as_deref()
12082                        .map(serde_json::from_slice)
12083                        .transpose()?,
12084                    resolved: completion.resolved,
12085                },
12086                Some(proto::completion::Source::BufferWord) => {
12087                    let word_range = completion
12088                        .buffer_word_start
12089                        .and_then(deserialize_anchor)
12090                        .context("invalid buffer word start")?
12091                        ..completion
12092                            .buffer_word_end
12093                            .and_then(deserialize_anchor)
12094                            .context("invalid buffer word end")?;
12095                    CompletionSource::BufferWord {
12096                        word_range,
12097                        resolved: completion.resolved,
12098                    }
12099                }
12100                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12101                    sort_text: completion
12102                        .sort_text
12103                        .context("expected sort text to exist")?,
12104                },
12105                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12106            },
12107        })
12108    }
12109
12110    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12111        let (kind, lsp_action) = match &action.lsp_action {
12112            LspAction::Action(code_action) => (
12113                proto::code_action::Kind::Action as i32,
12114                serde_json::to_vec(code_action).unwrap(),
12115            ),
12116            LspAction::Command(command) => (
12117                proto::code_action::Kind::Command as i32,
12118                serde_json::to_vec(command).unwrap(),
12119            ),
12120            LspAction::CodeLens(code_lens) => (
12121                proto::code_action::Kind::CodeLens as i32,
12122                serde_json::to_vec(code_lens).unwrap(),
12123            ),
12124        };
12125
12126        proto::CodeAction {
12127            server_id: action.server_id.0 as u64,
12128            start: Some(serialize_anchor(&action.range.start)),
12129            end: Some(serialize_anchor(&action.range.end)),
12130            lsp_action,
12131            kind,
12132            resolved: action.resolved,
12133        }
12134    }
12135
12136    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12137        let start = action
12138            .start
12139            .and_then(deserialize_anchor)
12140            .context("invalid start")?;
12141        let end = action
12142            .end
12143            .and_then(deserialize_anchor)
12144            .context("invalid end")?;
12145        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12146            Some(proto::code_action::Kind::Action) => {
12147                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12148            }
12149            Some(proto::code_action::Kind::Command) => {
12150                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12151            }
12152            Some(proto::code_action::Kind::CodeLens) => {
12153                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12154            }
12155            None => anyhow::bail!("Unknown action kind {}", action.kind),
12156        };
12157        Ok(CodeAction {
12158            server_id: LanguageServerId(action.server_id as usize),
12159            range: start..end,
12160            resolved: action.resolved,
12161            lsp_action,
12162        })
12163    }
12164
12165    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12166        match &formatting_result {
12167            Ok(_) => self.last_formatting_failure = None,
12168            Err(error) => {
12169                let error_string = format!("{error:#}");
12170                log::error!("Formatting failed: {error_string}");
12171                self.last_formatting_failure
12172                    .replace(error_string.lines().join(" "));
12173            }
12174        }
12175    }
12176
12177    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12178        self.lsp_server_capabilities.remove(&for_server);
12179        self.semantic_token_config.remove_server_data(for_server);
12180        for lsp_data in self.lsp_data.values_mut() {
12181            lsp_data.remove_server_data(for_server);
12182        }
12183        if let Some(local) = self.as_local_mut() {
12184            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12185            local
12186                .workspace_pull_diagnostics_result_ids
12187                .remove(&for_server);
12188            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12189                buffer_servers.remove(&for_server);
12190            }
12191        }
12192    }
12193
12194    pub fn result_id_for_buffer_pull(
12195        &self,
12196        server_id: LanguageServerId,
12197        buffer_id: BufferId,
12198        registration_id: &Option<SharedString>,
12199        cx: &App,
12200    ) -> Option<SharedString> {
12201        let abs_path = self
12202            .buffer_store
12203            .read(cx)
12204            .get(buffer_id)
12205            .and_then(|b| File::from_dyn(b.read(cx).file()))
12206            .map(|f| f.abs_path(cx))?;
12207        self.as_local()?
12208            .buffer_pull_diagnostics_result_ids
12209            .get(&server_id)?
12210            .get(registration_id)?
12211            .get(&abs_path)?
12212            .clone()
12213    }
12214
12215    /// Gets all result_ids for a workspace diagnostics pull request.
12216    /// 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.
12217    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12218    pub fn result_ids_for_workspace_refresh(
12219        &self,
12220        server_id: LanguageServerId,
12221        registration_id: &Option<SharedString>,
12222    ) -> HashMap<PathBuf, SharedString> {
12223        let Some(local) = self.as_local() else {
12224            return HashMap::default();
12225        };
12226        local
12227            .workspace_pull_diagnostics_result_ids
12228            .get(&server_id)
12229            .into_iter()
12230            .filter_map(|diagnostics| diagnostics.get(registration_id))
12231            .flatten()
12232            .filter_map(|(abs_path, result_id)| {
12233                let result_id = local
12234                    .buffer_pull_diagnostics_result_ids
12235                    .get(&server_id)
12236                    .and_then(|buffer_ids_result_ids| {
12237                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12238                    })
12239                    .cloned()
12240                    .flatten()
12241                    .or_else(|| result_id.clone())?;
12242                Some((abs_path.clone(), result_id))
12243            })
12244            .collect()
12245    }
12246
12247    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12248        if let Some(LanguageServerState::Running {
12249            workspace_diagnostics_refresh_tasks,
12250            ..
12251        }) = self
12252            .as_local_mut()
12253            .and_then(|local| local.language_servers.get_mut(&server_id))
12254        {
12255            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12256                diagnostics.refresh_tx.try_send(()).ok();
12257            }
12258        }
12259    }
12260
12261    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12262    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12263    /// which requires refreshing both workspace and document diagnostics.
12264    pub fn pull_document_diagnostics_for_server(
12265        &mut self,
12266        server_id: LanguageServerId,
12267        source_buffer_id: Option<BufferId>,
12268        cx: &mut Context<Self>,
12269    ) -> Shared<Task<()>> {
12270        let Some(local) = self.as_local_mut() else {
12271            return Task::ready(()).shared();
12272        };
12273        let mut buffers_to_refresh = HashSet::default();
12274        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12275            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12276                buffers_to_refresh.insert(*buffer_id);
12277            }
12278        }
12279
12280        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12281    }
12282
12283    pub fn pull_document_diagnostics_for_buffer_edit(
12284        &mut self,
12285        buffer_id: BufferId,
12286        cx: &mut Context<Self>,
12287    ) {
12288        let Some(local) = self.as_local_mut() else {
12289            return;
12290        };
12291        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12292        else {
12293            return;
12294        };
12295        for server_id in languages_servers {
12296            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12297        }
12298    }
12299
12300    fn apply_workspace_diagnostic_report(
12301        &mut self,
12302        server_id: LanguageServerId,
12303        report: lsp::WorkspaceDiagnosticReportResult,
12304        registration_id: Option<SharedString>,
12305        cx: &mut Context<Self>,
12306    ) {
12307        let mut workspace_diagnostics =
12308            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12309                report,
12310                server_id,
12311                registration_id,
12312            );
12313        workspace_diagnostics.retain(|d| match &d.diagnostics {
12314            LspPullDiagnostics::Response {
12315                server_id,
12316                registration_id,
12317                ..
12318            } => self.diagnostic_registration_exists(*server_id, registration_id),
12319            LspPullDiagnostics::Default => false,
12320        });
12321        let mut unchanged_buffers = HashMap::default();
12322        let workspace_diagnostics_updates = workspace_diagnostics
12323            .into_iter()
12324            .filter_map(
12325                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12326                    LspPullDiagnostics::Response {
12327                        server_id,
12328                        uri,
12329                        diagnostics,
12330                        registration_id,
12331                    } => Some((
12332                        server_id,
12333                        uri,
12334                        diagnostics,
12335                        workspace_diagnostics.version,
12336                        registration_id,
12337                    )),
12338                    LspPullDiagnostics::Default => None,
12339                },
12340            )
12341            .fold(
12342                HashMap::default(),
12343                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12344                    let (result_id, diagnostics) = match diagnostics {
12345                        PulledDiagnostics::Unchanged { result_id } => {
12346                            unchanged_buffers
12347                                .entry(new_registration_id.clone())
12348                                .or_insert_with(HashSet::default)
12349                                .insert(uri.clone());
12350                            (Some(result_id), Vec::new())
12351                        }
12352                        PulledDiagnostics::Changed {
12353                            result_id,
12354                            diagnostics,
12355                        } => (result_id, diagnostics),
12356                    };
12357                    let disk_based_sources = Cow::Owned(
12358                        self.language_server_adapter_for_id(server_id)
12359                            .as_ref()
12360                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12361                            .unwrap_or(&[])
12362                            .to_vec(),
12363                    );
12364
12365                    let Some(abs_path) = uri.to_file_path().ok() else {
12366                        return acc;
12367                    };
12368                    let Some((worktree, relative_path)) =
12369                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12370                    else {
12371                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12372                        return acc;
12373                    };
12374                    let worktree_id = worktree.read(cx).id();
12375                    let project_path = ProjectPath {
12376                        worktree_id,
12377                        path: relative_path,
12378                    };
12379                    if let Some(local_lsp_store) = self.as_local_mut() {
12380                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12381                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12382                    }
12383                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12384                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12385                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12386                        acc.entry(server_id)
12387                            .or_insert_with(HashMap::default)
12388                            .entry(new_registration_id.clone())
12389                            .or_insert_with(Vec::new)
12390                            .push(DocumentDiagnosticsUpdate {
12391                                server_id,
12392                                diagnostics: lsp::PublishDiagnosticsParams {
12393                                    uri,
12394                                    diagnostics,
12395                                    version,
12396                                },
12397                                result_id: result_id.map(SharedString::new),
12398                                disk_based_sources,
12399                                registration_id: new_registration_id,
12400                            });
12401                    }
12402                    acc
12403                },
12404            );
12405
12406        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12407            for (registration_id, diagnostic_updates) in diagnostic_updates {
12408                self.merge_lsp_diagnostics(
12409                    DiagnosticSourceKind::Pulled,
12410                    diagnostic_updates,
12411                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12412                        DiagnosticSourceKind::Pulled => {
12413                            old_diagnostic.registration_id != registration_id
12414                                || unchanged_buffers
12415                                    .get(&old_diagnostic.registration_id)
12416                                    .is_some_and(|unchanged_buffers| {
12417                                        unchanged_buffers.contains(&document_uri)
12418                                    })
12419                        }
12420                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12421                    },
12422                    cx,
12423                )
12424                .log_err();
12425            }
12426        }
12427    }
12428
12429    fn register_server_capabilities(
12430        &mut self,
12431        server_id: LanguageServerId,
12432        params: lsp::RegistrationParams,
12433        cx: &mut Context<Self>,
12434    ) -> anyhow::Result<()> {
12435        let server = self
12436            .language_server_for_id(server_id)
12437            .with_context(|| format!("no server {server_id} found"))?;
12438        for reg in params.registrations {
12439            match reg.method.as_str() {
12440                "workspace/didChangeWatchedFiles" => {
12441                    if let Some(options) = reg.register_options {
12442                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12443                            let caps = serde_json::from_value(options)?;
12444                            local_lsp_store
12445                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12446                            true
12447                        } else {
12448                            false
12449                        };
12450                        if notify {
12451                            notify_server_capabilities_updated(&server, cx);
12452                        }
12453                    }
12454                }
12455                "workspace/didChangeConfiguration" => {
12456                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12457                }
12458                "workspace/didChangeWorkspaceFolders" => {
12459                    // In this case register options is an empty object, we can ignore it
12460                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12461                        supported: Some(true),
12462                        change_notifications: Some(OneOf::Right(reg.id)),
12463                    };
12464                    server.update_capabilities(|capabilities| {
12465                        capabilities
12466                            .workspace
12467                            .get_or_insert_default()
12468                            .workspace_folders = Some(caps);
12469                    });
12470                    notify_server_capabilities_updated(&server, cx);
12471                }
12472                "workspace/symbol" => {
12473                    let options = parse_register_capabilities(reg)?;
12474                    server.update_capabilities(|capabilities| {
12475                        capabilities.workspace_symbol_provider = Some(options);
12476                    });
12477                    notify_server_capabilities_updated(&server, cx);
12478                }
12479                "workspace/fileOperations" => {
12480                    if let Some(options) = reg.register_options {
12481                        let caps = serde_json::from_value(options)?;
12482                        server.update_capabilities(|capabilities| {
12483                            capabilities
12484                                .workspace
12485                                .get_or_insert_default()
12486                                .file_operations = Some(caps);
12487                        });
12488                        notify_server_capabilities_updated(&server, cx);
12489                    }
12490                }
12491                "workspace/executeCommand" => {
12492                    if let Some(options) = reg.register_options {
12493                        let options = serde_json::from_value(options)?;
12494                        server.update_capabilities(|capabilities| {
12495                            capabilities.execute_command_provider = Some(options);
12496                        });
12497                        notify_server_capabilities_updated(&server, cx);
12498                    }
12499                }
12500                "textDocument/rangeFormatting" => {
12501                    let options = parse_register_capabilities(reg)?;
12502                    server.update_capabilities(|capabilities| {
12503                        capabilities.document_range_formatting_provider = Some(options);
12504                    });
12505                    notify_server_capabilities_updated(&server, cx);
12506                }
12507                "textDocument/onTypeFormatting" => {
12508                    if let Some(options) = reg
12509                        .register_options
12510                        .map(serde_json::from_value)
12511                        .transpose()?
12512                    {
12513                        server.update_capabilities(|capabilities| {
12514                            capabilities.document_on_type_formatting_provider = Some(options);
12515                        });
12516                        notify_server_capabilities_updated(&server, cx);
12517                    }
12518                }
12519                "textDocument/formatting" => {
12520                    let options = parse_register_capabilities(reg)?;
12521                    server.update_capabilities(|capabilities| {
12522                        capabilities.document_formatting_provider = Some(options);
12523                    });
12524                    notify_server_capabilities_updated(&server, cx);
12525                }
12526                "textDocument/rename" => {
12527                    let options = parse_register_capabilities(reg)?;
12528                    server.update_capabilities(|capabilities| {
12529                        capabilities.rename_provider = Some(options);
12530                    });
12531                    notify_server_capabilities_updated(&server, cx);
12532                }
12533                "textDocument/inlayHint" => {
12534                    let options = parse_register_capabilities(reg)?;
12535                    server.update_capabilities(|capabilities| {
12536                        capabilities.inlay_hint_provider = Some(options);
12537                    });
12538                    notify_server_capabilities_updated(&server, cx);
12539                }
12540                "textDocument/documentSymbol" => {
12541                    let options = parse_register_capabilities(reg)?;
12542                    server.update_capabilities(|capabilities| {
12543                        capabilities.document_symbol_provider = Some(options);
12544                    });
12545                    notify_server_capabilities_updated(&server, cx);
12546                }
12547                "textDocument/codeAction" => {
12548                    let options = parse_register_capabilities(reg)?;
12549                    let provider = match options {
12550                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12551                        OneOf::Right(caps) => caps,
12552                    };
12553                    server.update_capabilities(|capabilities| {
12554                        capabilities.code_action_provider = Some(provider);
12555                    });
12556                    notify_server_capabilities_updated(&server, cx);
12557                }
12558                "textDocument/definition" => {
12559                    let options = parse_register_capabilities(reg)?;
12560                    server.update_capabilities(|capabilities| {
12561                        capabilities.definition_provider = Some(options);
12562                    });
12563                    notify_server_capabilities_updated(&server, cx);
12564                }
12565                "textDocument/completion" => {
12566                    if let Some(caps) = reg
12567                        .register_options
12568                        .map(serde_json::from_value::<CompletionOptions>)
12569                        .transpose()?
12570                    {
12571                        server.update_capabilities(|capabilities| {
12572                            capabilities.completion_provider = Some(caps.clone());
12573                        });
12574
12575                        if let Some(local) = self.as_local() {
12576                            let mut buffers_with_language_server = Vec::new();
12577                            for handle in self.buffer_store.read(cx).buffers() {
12578                                let buffer_id = handle.read(cx).remote_id();
12579                                if local
12580                                    .buffers_opened_in_servers
12581                                    .get(&buffer_id)
12582                                    .filter(|s| s.contains(&server_id))
12583                                    .is_some()
12584                                {
12585                                    buffers_with_language_server.push(handle);
12586                                }
12587                            }
12588                            let triggers = caps
12589                                .trigger_characters
12590                                .unwrap_or_default()
12591                                .into_iter()
12592                                .collect::<BTreeSet<_>>();
12593                            for handle in buffers_with_language_server {
12594                                let triggers = triggers.clone();
12595                                let _ = handle.update(cx, move |buffer, cx| {
12596                                    buffer.set_completion_triggers(server_id, triggers, cx);
12597                                });
12598                            }
12599                        }
12600                        notify_server_capabilities_updated(&server, cx);
12601                    }
12602                }
12603                "textDocument/hover" => {
12604                    let options = parse_register_capabilities(reg)?;
12605                    let provider = match options {
12606                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12607                        OneOf::Right(caps) => caps,
12608                    };
12609                    server.update_capabilities(|capabilities| {
12610                        capabilities.hover_provider = Some(provider);
12611                    });
12612                    notify_server_capabilities_updated(&server, cx);
12613                }
12614                "textDocument/signatureHelp" => {
12615                    if let Some(caps) = reg
12616                        .register_options
12617                        .map(serde_json::from_value)
12618                        .transpose()?
12619                    {
12620                        server.update_capabilities(|capabilities| {
12621                            capabilities.signature_help_provider = Some(caps);
12622                        });
12623                        notify_server_capabilities_updated(&server, cx);
12624                    }
12625                }
12626                "textDocument/didChange" => {
12627                    if let Some(sync_kind) = reg
12628                        .register_options
12629                        .and_then(|opts| opts.get("syncKind").cloned())
12630                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12631                        .transpose()?
12632                    {
12633                        server.update_capabilities(|capabilities| {
12634                            let mut sync_options =
12635                                Self::take_text_document_sync_options(capabilities);
12636                            sync_options.change = Some(sync_kind);
12637                            capabilities.text_document_sync =
12638                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12639                        });
12640                        notify_server_capabilities_updated(&server, cx);
12641                    }
12642                }
12643                "textDocument/didSave" => {
12644                    if let Some(include_text) = reg
12645                        .register_options
12646                        .map(|opts| {
12647                            let transpose = opts
12648                                .get("includeText")
12649                                .cloned()
12650                                .map(serde_json::from_value::<Option<bool>>)
12651                                .transpose();
12652                            match transpose {
12653                                Ok(value) => Ok(value.flatten()),
12654                                Err(e) => Err(e),
12655                            }
12656                        })
12657                        .transpose()?
12658                    {
12659                        server.update_capabilities(|capabilities| {
12660                            let mut sync_options =
12661                                Self::take_text_document_sync_options(capabilities);
12662                            sync_options.save =
12663                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12664                                    include_text,
12665                                }));
12666                            capabilities.text_document_sync =
12667                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12668                        });
12669                        notify_server_capabilities_updated(&server, cx);
12670                    }
12671                }
12672                "textDocument/codeLens" => {
12673                    if let Some(caps) = reg
12674                        .register_options
12675                        .map(serde_json::from_value)
12676                        .transpose()?
12677                    {
12678                        server.update_capabilities(|capabilities| {
12679                            capabilities.code_lens_provider = Some(caps);
12680                        });
12681                        notify_server_capabilities_updated(&server, cx);
12682                    }
12683                }
12684                "textDocument/diagnostic" => {
12685                    if let Some(caps) = reg
12686                        .register_options
12687                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12688                        .transpose()?
12689                    {
12690                        let local = self
12691                            .as_local_mut()
12692                            .context("Expected LSP Store to be local")?;
12693                        let state = local
12694                            .language_servers
12695                            .get_mut(&server_id)
12696                            .context("Could not obtain Language Servers state")?;
12697                        local
12698                            .language_server_dynamic_registrations
12699                            .entry(server_id)
12700                            .or_default()
12701                            .diagnostics
12702                            .insert(Some(reg.id.clone()), caps.clone());
12703
12704                        let supports_workspace_diagnostics =
12705                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12706                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12707                                    diagnostic_options.workspace_diagnostics
12708                                }
12709                                DiagnosticServerCapabilities::RegistrationOptions(
12710                                    diagnostic_registration_options,
12711                                ) => {
12712                                    diagnostic_registration_options
12713                                        .diagnostic_options
12714                                        .workspace_diagnostics
12715                                }
12716                            };
12717
12718                        if supports_workspace_diagnostics(&caps) {
12719                            if let LanguageServerState::Running {
12720                                workspace_diagnostics_refresh_tasks,
12721                                ..
12722                            } = state
12723                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12724                                    Some(reg.id.clone()),
12725                                    caps.clone(),
12726                                    server.clone(),
12727                                    cx,
12728                                )
12729                            {
12730                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12731                            }
12732                        }
12733
12734                        server.update_capabilities(|capabilities| {
12735                            capabilities.diagnostic_provider = Some(caps);
12736                        });
12737
12738                        notify_server_capabilities_updated(&server, cx);
12739
12740                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12741                    }
12742                }
12743                "textDocument/documentColor" => {
12744                    let options = parse_register_capabilities(reg)?;
12745                    let provider = match options {
12746                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12747                        OneOf::Right(caps) => caps,
12748                    };
12749                    server.update_capabilities(|capabilities| {
12750                        capabilities.color_provider = Some(provider);
12751                    });
12752                    notify_server_capabilities_updated(&server, cx);
12753                }
12754                "textDocument/foldingRange" => {
12755                    let options = parse_register_capabilities(reg)?;
12756                    let provider = match options {
12757                        OneOf::Left(value) => lsp::FoldingRangeProviderCapability::Simple(value),
12758                        OneOf::Right(caps) => caps,
12759                    };
12760                    server.update_capabilities(|capabilities| {
12761                        capabilities.folding_range_provider = Some(provider);
12762                    });
12763                    notify_server_capabilities_updated(&server, cx);
12764                }
12765                _ => log::warn!("unhandled capability registration: {reg:?}"),
12766            }
12767        }
12768
12769        Ok(())
12770    }
12771
12772    fn unregister_server_capabilities(
12773        &mut self,
12774        server_id: LanguageServerId,
12775        params: lsp::UnregistrationParams,
12776        cx: &mut Context<Self>,
12777    ) -> anyhow::Result<()> {
12778        let server = self
12779            .language_server_for_id(server_id)
12780            .with_context(|| format!("no server {server_id} found"))?;
12781        for unreg in params.unregisterations.iter() {
12782            match unreg.method.as_str() {
12783                "workspace/didChangeWatchedFiles" => {
12784                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12785                        local_lsp_store
12786                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12787                        true
12788                    } else {
12789                        false
12790                    };
12791                    if notify {
12792                        notify_server_capabilities_updated(&server, cx);
12793                    }
12794                }
12795                "workspace/didChangeConfiguration" => {
12796                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12797                }
12798                "workspace/didChangeWorkspaceFolders" => {
12799                    server.update_capabilities(|capabilities| {
12800                        capabilities
12801                            .workspace
12802                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12803                                workspace_folders: None,
12804                                file_operations: None,
12805                            })
12806                            .workspace_folders = None;
12807                    });
12808                    notify_server_capabilities_updated(&server, cx);
12809                }
12810                "workspace/symbol" => {
12811                    server.update_capabilities(|capabilities| {
12812                        capabilities.workspace_symbol_provider = None
12813                    });
12814                    notify_server_capabilities_updated(&server, cx);
12815                }
12816                "workspace/fileOperations" => {
12817                    server.update_capabilities(|capabilities| {
12818                        capabilities
12819                            .workspace
12820                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12821                                workspace_folders: None,
12822                                file_operations: None,
12823                            })
12824                            .file_operations = None;
12825                    });
12826                    notify_server_capabilities_updated(&server, cx);
12827                }
12828                "workspace/executeCommand" => {
12829                    server.update_capabilities(|capabilities| {
12830                        capabilities.execute_command_provider = None;
12831                    });
12832                    notify_server_capabilities_updated(&server, cx);
12833                }
12834                "textDocument/rangeFormatting" => {
12835                    server.update_capabilities(|capabilities| {
12836                        capabilities.document_range_formatting_provider = None
12837                    });
12838                    notify_server_capabilities_updated(&server, cx);
12839                }
12840                "textDocument/onTypeFormatting" => {
12841                    server.update_capabilities(|capabilities| {
12842                        capabilities.document_on_type_formatting_provider = None;
12843                    });
12844                    notify_server_capabilities_updated(&server, cx);
12845                }
12846                "textDocument/formatting" => {
12847                    server.update_capabilities(|capabilities| {
12848                        capabilities.document_formatting_provider = None;
12849                    });
12850                    notify_server_capabilities_updated(&server, cx);
12851                }
12852                "textDocument/rename" => {
12853                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12854                    notify_server_capabilities_updated(&server, cx);
12855                }
12856                "textDocument/codeAction" => {
12857                    server.update_capabilities(|capabilities| {
12858                        capabilities.code_action_provider = None;
12859                    });
12860                    notify_server_capabilities_updated(&server, cx);
12861                }
12862                "textDocument/definition" => {
12863                    server.update_capabilities(|capabilities| {
12864                        capabilities.definition_provider = None;
12865                    });
12866                    notify_server_capabilities_updated(&server, cx);
12867                }
12868                "textDocument/completion" => {
12869                    server.update_capabilities(|capabilities| {
12870                        capabilities.completion_provider = None;
12871                    });
12872                    notify_server_capabilities_updated(&server, cx);
12873                }
12874                "textDocument/hover" => {
12875                    server.update_capabilities(|capabilities| {
12876                        capabilities.hover_provider = None;
12877                    });
12878                    notify_server_capabilities_updated(&server, cx);
12879                }
12880                "textDocument/signatureHelp" => {
12881                    server.update_capabilities(|capabilities| {
12882                        capabilities.signature_help_provider = None;
12883                    });
12884                    notify_server_capabilities_updated(&server, cx);
12885                }
12886                "textDocument/didChange" => {
12887                    server.update_capabilities(|capabilities| {
12888                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12889                        sync_options.change = None;
12890                        capabilities.text_document_sync =
12891                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12892                    });
12893                    notify_server_capabilities_updated(&server, cx);
12894                }
12895                "textDocument/didSave" => {
12896                    server.update_capabilities(|capabilities| {
12897                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12898                        sync_options.save = None;
12899                        capabilities.text_document_sync =
12900                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12901                    });
12902                    notify_server_capabilities_updated(&server, cx);
12903                }
12904                "textDocument/codeLens" => {
12905                    server.update_capabilities(|capabilities| {
12906                        capabilities.code_lens_provider = None;
12907                    });
12908                    notify_server_capabilities_updated(&server, cx);
12909                }
12910                "textDocument/diagnostic" => {
12911                    let local = self
12912                        .as_local_mut()
12913                        .context("Expected LSP Store to be local")?;
12914
12915                    let state = local
12916                        .language_servers
12917                        .get_mut(&server_id)
12918                        .context("Could not obtain Language Servers state")?;
12919                    let registrations = local
12920                        .language_server_dynamic_registrations
12921                        .get_mut(&server_id)
12922                        .with_context(|| {
12923                            format!("Expected dynamic registration to exist for server {server_id}")
12924                        })?;
12925                    registrations.diagnostics
12926                        .remove(&Some(unreg.id.clone()))
12927                        .with_context(|| format!(
12928                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12929                            unreg.id)
12930                        )?;
12931                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12932
12933                    if let LanguageServerState::Running {
12934                        workspace_diagnostics_refresh_tasks,
12935                        ..
12936                    } = state
12937                    {
12938                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12939                    }
12940
12941                    self.clear_unregistered_diagnostics(
12942                        server_id,
12943                        SharedString::from(unreg.id.clone()),
12944                        cx,
12945                    )?;
12946
12947                    if removed_last_diagnostic_provider {
12948                        server.update_capabilities(|capabilities| {
12949                            debug_assert!(capabilities.diagnostic_provider.is_some());
12950                            capabilities.diagnostic_provider = None;
12951                        });
12952                    }
12953
12954                    notify_server_capabilities_updated(&server, cx);
12955                }
12956                "textDocument/documentColor" => {
12957                    server.update_capabilities(|capabilities| {
12958                        capabilities.color_provider = None;
12959                    });
12960                    notify_server_capabilities_updated(&server, cx);
12961                }
12962                "textDocument/foldingRange" => {
12963                    server.update_capabilities(|capabilities| {
12964                        capabilities.folding_range_provider = None;
12965                    });
12966                    notify_server_capabilities_updated(&server, cx);
12967                }
12968                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12969            }
12970        }
12971
12972        Ok(())
12973    }
12974
12975    fn clear_unregistered_diagnostics(
12976        &mut self,
12977        server_id: LanguageServerId,
12978        cleared_registration_id: SharedString,
12979        cx: &mut Context<Self>,
12980    ) -> anyhow::Result<()> {
12981        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12982
12983        self.buffer_store.update(cx, |buffer_store, cx| {
12984            for buffer_handle in buffer_store.buffers() {
12985                let buffer = buffer_handle.read(cx);
12986                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12987                let Some(abs_path) = abs_path else {
12988                    continue;
12989                };
12990                affected_abs_paths.insert(abs_path);
12991            }
12992        });
12993
12994        let local = self.as_local().context("Expected LSP Store to be local")?;
12995        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12996            let Some(worktree) = self
12997                .worktree_store
12998                .read(cx)
12999                .worktree_for_id(*worktree_id, cx)
13000            else {
13001                continue;
13002            };
13003
13004            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
13005                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
13006                    let has_matching_registration =
13007                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
13008                            entry.diagnostic.registration_id.as_ref()
13009                                == Some(&cleared_registration_id)
13010                        });
13011                    if has_matching_registration {
13012                        let abs_path = worktree.read(cx).absolutize(rel_path);
13013                        affected_abs_paths.insert(abs_path);
13014                    }
13015                }
13016            }
13017        }
13018
13019        if affected_abs_paths.is_empty() {
13020            return Ok(());
13021        }
13022
13023        // Send a fake diagnostic update which clears the state for the registration ID
13024        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
13025            affected_abs_paths
13026                .into_iter()
13027                .map(|abs_path| DocumentDiagnosticsUpdate {
13028                    diagnostics: DocumentDiagnostics {
13029                        diagnostics: Vec::new(),
13030                        document_abs_path: abs_path,
13031                        version: None,
13032                    },
13033                    result_id: None,
13034                    registration_id: Some(cleared_registration_id.clone()),
13035                    server_id,
13036                    disk_based_sources: Cow::Borrowed(&[]),
13037                })
13038                .collect();
13039
13040        let merge_registration_id = cleared_registration_id.clone();
13041        self.merge_diagnostic_entries(
13042            clears,
13043            move |_, diagnostic, _| {
13044                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
13045                    diagnostic.registration_id != Some(merge_registration_id.clone())
13046                } else {
13047                    true
13048                }
13049            },
13050            cx,
13051        )?;
13052
13053        Ok(())
13054    }
13055
13056    async fn deduplicate_range_based_lsp_requests<T>(
13057        lsp_store: &Entity<Self>,
13058        server_id: Option<LanguageServerId>,
13059        lsp_request_id: LspRequestId,
13060        proto_request: &T::ProtoRequest,
13061        range: Range<Anchor>,
13062        cx: &mut AsyncApp,
13063    ) -> Result<()>
13064    where
13065        T: LspCommand,
13066        T::ProtoRequest: proto::LspRequestMessage,
13067    {
13068        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13069        let version = deserialize_version(proto_request.buffer_version());
13070        let buffer = lsp_store.update(cx, |this, cx| {
13071            this.buffer_store.read(cx).get_existing(buffer_id)
13072        })?;
13073        buffer
13074            .update(cx, |buffer, _| buffer.wait_for_version(version))
13075            .await?;
13076        lsp_store.update(cx, |lsp_store, cx| {
13077            let buffer_snapshot = buffer.read(cx).snapshot();
13078            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13079            let chunks_queried_for = lsp_data
13080                .inlay_hints
13081                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
13082                .collect::<Vec<_>>();
13083            match chunks_queried_for.as_slice() {
13084                &[chunk] => {
13085                    let key = LspKey {
13086                        request_type: TypeId::of::<T>(),
13087                        server_queried: server_id,
13088                    };
13089                    let previous_request = lsp_data
13090                        .chunk_lsp_requests
13091                        .entry(key)
13092                        .or_default()
13093                        .insert(chunk, lsp_request_id);
13094                    if let Some((previous_request, running_requests)) =
13095                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13096                    {
13097                        running_requests.remove(&previous_request);
13098                    }
13099                }
13100                _ambiguous_chunks => {
13101                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13102                    // there, a buffer version-based check will be performed and outdated requests discarded.
13103                }
13104            }
13105            anyhow::Ok(())
13106        })?;
13107
13108        Ok(())
13109    }
13110
13111    async fn query_lsp_locally<T>(
13112        lsp_store: Entity<Self>,
13113        for_server_id: Option<LanguageServerId>,
13114        sender_id: proto::PeerId,
13115        lsp_request_id: LspRequestId,
13116        proto_request: T::ProtoRequest,
13117        position: Option<Anchor>,
13118        cx: &mut AsyncApp,
13119    ) -> Result<()>
13120    where
13121        T: LspCommand + Clone,
13122        T::ProtoRequest: proto::LspRequestMessage,
13123        <T::ProtoRequest as proto::RequestMessage>::Response:
13124            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13125    {
13126        let (buffer_version, buffer) =
13127            Self::wait_for_buffer_version::<T>(&lsp_store, &proto_request, cx).await?;
13128        let request =
13129            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13130        let key = LspKey {
13131            request_type: TypeId::of::<T>(),
13132            server_queried: for_server_id,
13133        };
13134        lsp_store.update(cx, |lsp_store, cx| {
13135            let request_task = match for_server_id {
13136                Some(server_id) => {
13137                    let server_task = lsp_store.request_lsp(
13138                        buffer.clone(),
13139                        LanguageServerToQuery::Other(server_id),
13140                        request.clone(),
13141                        cx,
13142                    );
13143                    cx.background_spawn(async move {
13144                        let mut responses = Vec::new();
13145                        match server_task.await {
13146                            Ok(response) => responses.push((server_id, response)),
13147                            // rust-analyzer likes to error with this when its still loading up
13148                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13149                            Err(e) => log::error!(
13150                                "Error handling response for request {request:?}: {e:#}"
13151                            ),
13152                        }
13153                        responses
13154                    })
13155                }
13156                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13157            };
13158            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13159            if T::ProtoRequest::stop_previous_requests() {
13160                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13161                    lsp_requests.clear();
13162                }
13163            }
13164            lsp_data.lsp_requests.entry(key).or_default().insert(
13165                lsp_request_id,
13166                cx.spawn(async move |lsp_store, cx| {
13167                    let response = request_task.await;
13168                    lsp_store
13169                        .update(cx, |lsp_store, cx| {
13170                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13171                            {
13172                                let response = response
13173                                    .into_iter()
13174                                    .map(|(server_id, response)| {
13175                                        (
13176                                            server_id.to_proto(),
13177                                            T::response_to_proto(
13178                                                response,
13179                                                lsp_store,
13180                                                sender_id,
13181                                                &buffer_version,
13182                                                cx,
13183                                            )
13184                                            .into(),
13185                                        )
13186                                    })
13187                                    .collect::<HashMap<_, _>>();
13188                                match client.send_lsp_response::<T::ProtoRequest>(
13189                                    project_id,
13190                                    lsp_request_id,
13191                                    response,
13192                                ) {
13193                                    Ok(()) => {}
13194                                    Err(e) => {
13195                                        log::error!("Failed to send LSP response: {e:#}",)
13196                                    }
13197                                }
13198                            }
13199                        })
13200                        .ok();
13201                }),
13202            );
13203        });
13204        Ok(())
13205    }
13206
13207    async fn wait_for_buffer_version<T>(
13208        lsp_store: &Entity<Self>,
13209        proto_request: &T::ProtoRequest,
13210        cx: &mut AsyncApp,
13211    ) -> Result<(Global, Entity<Buffer>)>
13212    where
13213        T: LspCommand,
13214        T::ProtoRequest: proto::LspRequestMessage,
13215    {
13216        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13217        let version = deserialize_version(proto_request.buffer_version());
13218        let buffer = lsp_store.update(cx, |this, cx| {
13219            this.buffer_store.read(cx).get_existing(buffer_id)
13220        })?;
13221        buffer
13222            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13223            .await?;
13224        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13225        Ok((buffer_version, buffer))
13226    }
13227
13228    fn take_text_document_sync_options(
13229        capabilities: &mut lsp::ServerCapabilities,
13230    ) -> lsp::TextDocumentSyncOptions {
13231        match capabilities.text_document_sync.take() {
13232            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13233            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13234                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13235                sync_options.change = Some(sync_kind);
13236                sync_options
13237            }
13238            None => lsp::TextDocumentSyncOptions::default(),
13239        }
13240    }
13241
13242    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13243        self.downstream_client.clone()
13244    }
13245
13246    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13247        self.worktree_store.clone()
13248    }
13249
13250    /// Gets what's stored in the LSP data for the given buffer.
13251    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13252        self.lsp_data.get_mut(&buffer_id)
13253    }
13254
13255    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13256    /// new [`BufferLspData`] will be created to replace the previous state.
13257    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13258        let (buffer_id, buffer_version) =
13259            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13260        let lsp_data = self
13261            .lsp_data
13262            .entry(buffer_id)
13263            .or_insert_with(|| BufferLspData::new(buffer, cx));
13264        if buffer_version.changed_since(&lsp_data.buffer_version) {
13265            // To send delta requests for semantic tokens, the previous tokens
13266            // need to be kept between buffer changes.
13267            let semantic_tokens = lsp_data.semantic_tokens.take();
13268            *lsp_data = BufferLspData::new(buffer, cx);
13269            lsp_data.semantic_tokens = semantic_tokens;
13270        }
13271        lsp_data
13272    }
13273}
13274
13275// Registration with registerOptions as null, should fallback to true.
13276// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13277fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13278    reg: lsp::Registration,
13279) -> Result<OneOf<bool, T>> {
13280    Ok(match reg.register_options {
13281        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13282        None => OneOf::Left(true),
13283    })
13284}
13285
13286fn subscribe_to_binary_statuses(
13287    languages: &Arc<LanguageRegistry>,
13288    cx: &mut Context<'_, LspStore>,
13289) -> Task<()> {
13290    let mut server_statuses = languages.language_server_binary_statuses();
13291    cx.spawn(async move |lsp_store, cx| {
13292        while let Some((server_name, binary_status)) = server_statuses.next().await {
13293            if lsp_store
13294                .update(cx, |_, cx| {
13295                    let mut message = None;
13296                    let binary_status = match binary_status {
13297                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13298                        BinaryStatus::CheckingForUpdate => {
13299                            proto::ServerBinaryStatus::CheckingForUpdate
13300                        }
13301                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13302                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13303                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13304                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13305                        BinaryStatus::Failed { error } => {
13306                            message = Some(error);
13307                            proto::ServerBinaryStatus::Failed
13308                        }
13309                    };
13310                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13311                        // Binary updates are about the binary that might not have any language server id at that point.
13312                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13313                        language_server_id: LanguageServerId(0),
13314                        name: Some(server_name),
13315                        message: proto::update_language_server::Variant::StatusUpdate(
13316                            proto::StatusUpdate {
13317                                message,
13318                                status: Some(proto::status_update::Status::Binary(
13319                                    binary_status as i32,
13320                                )),
13321                            },
13322                        ),
13323                    });
13324                })
13325                .is_err()
13326            {
13327                break;
13328            }
13329        }
13330    })
13331}
13332
13333fn lsp_workspace_diagnostics_refresh(
13334    registration_id: Option<String>,
13335    options: DiagnosticServerCapabilities,
13336    server: Arc<LanguageServer>,
13337    cx: &mut Context<'_, LspStore>,
13338) -> Option<WorkspaceRefreshTask> {
13339    let identifier = workspace_diagnostic_identifier(&options)?;
13340    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13341
13342    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13343    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13344    refresh_tx.try_send(()).ok();
13345
13346    let request_timeout = ProjectSettings::get_global(cx)
13347        .global_lsp_settings
13348        .get_request_timeout();
13349
13350    // 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.
13351    // This allows users to increase the duration if need be
13352    let timeout = if request_timeout != Duration::ZERO {
13353        request_timeout.max(DEFAULT_LSP_REQUEST_TIMEOUT)
13354    } else {
13355        request_timeout
13356    };
13357
13358    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13359        let mut attempts = 0;
13360        let max_attempts = 50;
13361        let mut requests = 0;
13362
13363        loop {
13364            let Some(()) = refresh_rx.recv().await else {
13365                return;
13366            };
13367
13368            'request: loop {
13369                requests += 1;
13370                if attempts > max_attempts {
13371                    log::error!(
13372                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13373                    );
13374                    return;
13375                }
13376                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13377                cx.background_executor()
13378                    .timer(Duration::from_millis(backoff_millis))
13379                    .await;
13380                attempts += 1;
13381
13382                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13383                    lsp_store
13384                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13385                        .into_iter()
13386                        .filter_map(|(abs_path, result_id)| {
13387                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13388                            Some(lsp::PreviousResultId {
13389                                uri,
13390                                value: result_id.to_string(),
13391                            })
13392                        })
13393                        .collect()
13394                }) else {
13395                    return;
13396                };
13397
13398                let token = if let Some(registration_id) = &registration_id {
13399                    format!(
13400                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13401                        server.server_id(),
13402                    )
13403                } else {
13404                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13405                };
13406
13407                progress_rx.try_recv().ok();
13408                let timer = server.request_timer(timeout).fuse();
13409                let progress = pin!(progress_rx.recv().fuse());
13410                let response_result = server
13411                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13412                        lsp::WorkspaceDiagnosticParams {
13413                            previous_result_ids,
13414                            identifier: identifier.clone(),
13415                            work_done_progress_params: Default::default(),
13416                            partial_result_params: lsp::PartialResultParams {
13417                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13418                            },
13419                        },
13420                        select(timer, progress).then(|either| match either {
13421                            Either::Left((message, ..)) => ready(message).left_future(),
13422                            Either::Right(..) => pending::<String>().right_future(),
13423                        }),
13424                    )
13425                    .await;
13426
13427                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13428                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13429                match response_result {
13430                    ConnectionResult::Timeout => {
13431                        log::error!("Timeout during workspace diagnostics pull");
13432                        continue 'request;
13433                    }
13434                    ConnectionResult::ConnectionReset => {
13435                        log::error!("Server closed a workspace diagnostics pull request");
13436                        continue 'request;
13437                    }
13438                    ConnectionResult::Result(Err(e)) => {
13439                        log::error!("Error during workspace diagnostics pull: {e:#}");
13440                        break 'request;
13441                    }
13442                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13443                        attempts = 0;
13444                        if lsp_store
13445                            .update(cx, |lsp_store, cx| {
13446                                lsp_store.apply_workspace_diagnostic_report(
13447                                    server.server_id(),
13448                                    pulled_diagnostics,
13449                                    registration_id_shared.clone(),
13450                                    cx,
13451                                )
13452                            })
13453                            .is_err()
13454                        {
13455                            return;
13456                        }
13457                        break 'request;
13458                    }
13459                }
13460            }
13461        }
13462    });
13463
13464    Some(WorkspaceRefreshTask {
13465        refresh_tx,
13466        progress_tx,
13467        task: workspace_query_language_server,
13468    })
13469}
13470
13471fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<SharedString> {
13472    match &options {
13473        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => diagnostic_options
13474            .identifier
13475            .as_deref()
13476            .map(SharedString::new),
13477        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13478            let diagnostic_options = &registration_options.diagnostic_options;
13479            diagnostic_options
13480                .identifier
13481                .as_deref()
13482                .map(SharedString::new)
13483        }
13484    }
13485}
13486
13487fn workspace_diagnostic_identifier(
13488    options: &DiagnosticServerCapabilities,
13489) -> Option<Option<String>> {
13490    match &options {
13491        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13492            if !diagnostic_options.workspace_diagnostics {
13493                return None;
13494            }
13495            Some(diagnostic_options.identifier.clone())
13496        }
13497        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13498            let diagnostic_options = &registration_options.diagnostic_options;
13499            if !diagnostic_options.workspace_diagnostics {
13500                return None;
13501            }
13502            Some(diagnostic_options.identifier.clone())
13503        }
13504    }
13505}
13506
13507fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13508    let CompletionSource::BufferWord {
13509        word_range,
13510        resolved,
13511    } = &mut completion.source
13512    else {
13513        return;
13514    };
13515    if *resolved {
13516        return;
13517    }
13518
13519    if completion.new_text
13520        != snapshot
13521            .text_for_range(word_range.clone())
13522            .collect::<String>()
13523    {
13524        return;
13525    }
13526
13527    let mut offset = 0;
13528    for chunk in snapshot.chunks(word_range.clone(), true) {
13529        let end_offset = offset + chunk.text.len();
13530        if let Some(highlight_id) = chunk.syntax_highlight_id {
13531            completion
13532                .label
13533                .runs
13534                .push((offset..end_offset, highlight_id));
13535        }
13536        offset = end_offset;
13537    }
13538    *resolved = true;
13539}
13540
13541impl EventEmitter<LspStoreEvent> for LspStore {}
13542
13543fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13544    hover
13545        .contents
13546        .retain(|hover_block| !hover_block.text.trim().is_empty());
13547    if hover.contents.is_empty() {
13548        None
13549    } else {
13550        Some(hover)
13551    }
13552}
13553
13554async fn populate_labels_for_completions(
13555    new_completions: Vec<CoreCompletion>,
13556    language: Option<Arc<Language>>,
13557    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13558) -> Vec<Completion> {
13559    let lsp_completions = new_completions
13560        .iter()
13561        .filter_map(|new_completion| {
13562            new_completion
13563                .source
13564                .lsp_completion(true)
13565                .map(|lsp_completion| lsp_completion.into_owned())
13566        })
13567        .collect::<Vec<_>>();
13568
13569    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13570        lsp_adapter
13571            .labels_for_completions(&lsp_completions, language)
13572            .await
13573            .log_err()
13574            .unwrap_or_default()
13575    } else {
13576        Vec::new()
13577    }
13578    .into_iter()
13579    .fuse();
13580
13581    let mut completions = Vec::new();
13582    for completion in new_completions {
13583        match completion.source.lsp_completion(true) {
13584            Some(lsp_completion) => {
13585                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13586
13587                let mut label = labels.next().flatten().unwrap_or_else(|| {
13588                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13589                });
13590                ensure_uniform_list_compatible_label(&mut label);
13591                completions.push(Completion {
13592                    label,
13593                    documentation,
13594                    replace_range: completion.replace_range,
13595                    new_text: completion.new_text,
13596                    insert_text_mode: lsp_completion.insert_text_mode,
13597                    source: completion.source,
13598                    icon_path: None,
13599                    confirm: None,
13600                    match_start: None,
13601                    snippet_deduplication_key: None,
13602                });
13603            }
13604            None => {
13605                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13606                ensure_uniform_list_compatible_label(&mut label);
13607                completions.push(Completion {
13608                    label,
13609                    documentation: None,
13610                    replace_range: completion.replace_range,
13611                    new_text: completion.new_text,
13612                    source: completion.source,
13613                    insert_text_mode: None,
13614                    icon_path: None,
13615                    confirm: None,
13616                    match_start: None,
13617                    snippet_deduplication_key: None,
13618                });
13619            }
13620        }
13621    }
13622    completions
13623}
13624
13625#[derive(Debug)]
13626pub enum LanguageServerToQuery {
13627    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13628    FirstCapable,
13629    /// Query a specific language server.
13630    Other(LanguageServerId),
13631}
13632
13633#[derive(Default)]
13634struct RenamePathsWatchedForServer {
13635    did_rename: Vec<RenameActionPredicate>,
13636    will_rename: Vec<RenameActionPredicate>,
13637}
13638
13639impl RenamePathsWatchedForServer {
13640    fn with_did_rename_patterns(
13641        mut self,
13642        did_rename: Option<&FileOperationRegistrationOptions>,
13643    ) -> Self {
13644        if let Some(did_rename) = did_rename {
13645            self.did_rename = did_rename
13646                .filters
13647                .iter()
13648                .filter_map(|filter| filter.try_into().log_err())
13649                .collect();
13650        }
13651        self
13652    }
13653    fn with_will_rename_patterns(
13654        mut self,
13655        will_rename: Option<&FileOperationRegistrationOptions>,
13656    ) -> Self {
13657        if let Some(will_rename) = will_rename {
13658            self.will_rename = will_rename
13659                .filters
13660                .iter()
13661                .filter_map(|filter| filter.try_into().log_err())
13662                .collect();
13663        }
13664        self
13665    }
13666
13667    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13668        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13669    }
13670    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13671        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13672    }
13673}
13674
13675impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13676    type Error = globset::Error;
13677    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13678        Ok(Self {
13679            kind: ops.pattern.matches.clone(),
13680            glob: GlobBuilder::new(&ops.pattern.glob)
13681                .case_insensitive(
13682                    ops.pattern
13683                        .options
13684                        .as_ref()
13685                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13686                )
13687                .build()?
13688                .compile_matcher(),
13689        })
13690    }
13691}
13692struct RenameActionPredicate {
13693    glob: GlobMatcher,
13694    kind: Option<FileOperationPatternKind>,
13695}
13696
13697impl RenameActionPredicate {
13698    // Returns true if language server should be notified
13699    fn eval(&self, path: &str, is_dir: bool) -> bool {
13700        self.kind.as_ref().is_none_or(|kind| {
13701            let expected_kind = if is_dir {
13702                FileOperationPatternKind::Folder
13703            } else {
13704                FileOperationPatternKind::File
13705            };
13706            kind == &expected_kind
13707        }) && self.glob.is_match(path)
13708    }
13709}
13710
13711#[derive(Default)]
13712struct LanguageServerWatchedPaths {
13713    worktree_paths: HashMap<WorktreeId, GlobSet>,
13714    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13715}
13716
13717#[derive(Default)]
13718struct LanguageServerWatchedPathsBuilder {
13719    worktree_paths: HashMap<WorktreeId, GlobSet>,
13720    abs_paths: HashMap<Arc<Path>, GlobSet>,
13721}
13722
13723impl LanguageServerWatchedPathsBuilder {
13724    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13725        self.worktree_paths.insert(worktree_id, glob_set);
13726    }
13727    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13728        self.abs_paths.insert(path, glob_set);
13729    }
13730    fn build(
13731        self,
13732        fs: Arc<dyn Fs>,
13733        language_server_id: LanguageServerId,
13734        cx: &mut Context<LspStore>,
13735    ) -> LanguageServerWatchedPaths {
13736        let lsp_store = cx.weak_entity();
13737
13738        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13739        let abs_paths = self
13740            .abs_paths
13741            .into_iter()
13742            .map(|(abs_path, globset)| {
13743                let task = cx.spawn({
13744                    let abs_path = abs_path.clone();
13745                    let fs = fs.clone();
13746
13747                    let lsp_store = lsp_store.clone();
13748                    async move |_, cx| {
13749                        maybe!(async move {
13750                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13751                            while let Some(update) = push_updates.0.next().await {
13752                                let action = lsp_store
13753                                    .update(cx, |this, _| {
13754                                        let Some(local) = this.as_local() else {
13755                                            return ControlFlow::Break(());
13756                                        };
13757                                        let Some(watcher) = local
13758                                            .language_server_watched_paths
13759                                            .get(&language_server_id)
13760                                        else {
13761                                            return ControlFlow::Break(());
13762                                        };
13763                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13764                                            "Watched abs path is not registered with a watcher",
13765                                        );
13766                                        let matching_entries = update
13767                                            .into_iter()
13768                                            .filter(|event| globs.is_match(&event.path))
13769                                            .collect::<Vec<_>>();
13770                                        this.lsp_notify_abs_paths_changed(
13771                                            language_server_id,
13772                                            matching_entries,
13773                                        );
13774                                        ControlFlow::Continue(())
13775                                    })
13776                                    .ok()?;
13777
13778                                if action.is_break() {
13779                                    break;
13780                                }
13781                            }
13782                            Some(())
13783                        })
13784                        .await;
13785                    }
13786                });
13787                (abs_path, (globset, task))
13788            })
13789            .collect();
13790        LanguageServerWatchedPaths {
13791            worktree_paths: self.worktree_paths,
13792            abs_paths,
13793        }
13794    }
13795}
13796
13797struct LspBufferSnapshot {
13798    version: i32,
13799    snapshot: TextBufferSnapshot,
13800}
13801
13802/// A prompt requested by LSP server.
13803#[derive(Clone, Debug)]
13804pub struct LanguageServerPromptRequest {
13805    pub id: usize,
13806    pub level: PromptLevel,
13807    pub message: String,
13808    pub actions: Vec<MessageActionItem>,
13809    pub lsp_name: String,
13810    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13811}
13812
13813impl LanguageServerPromptRequest {
13814    pub fn new(
13815        level: PromptLevel,
13816        message: String,
13817        actions: Vec<MessageActionItem>,
13818        lsp_name: String,
13819        response_channel: smol::channel::Sender<MessageActionItem>,
13820    ) -> Self {
13821        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13822        LanguageServerPromptRequest {
13823            id,
13824            level,
13825            message,
13826            actions,
13827            lsp_name,
13828            response_channel,
13829        }
13830    }
13831    pub async fn respond(self, index: usize) -> Option<()> {
13832        if let Some(response) = self.actions.into_iter().nth(index) {
13833            self.response_channel.send(response).await.ok()
13834        } else {
13835            None
13836        }
13837    }
13838
13839    #[cfg(any(test, feature = "test-support"))]
13840    pub fn test(
13841        level: PromptLevel,
13842        message: String,
13843        actions: Vec<MessageActionItem>,
13844        lsp_name: String,
13845    ) -> Self {
13846        let (tx, _rx) = smol::channel::unbounded();
13847        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13848    }
13849}
13850impl PartialEq for LanguageServerPromptRequest {
13851    fn eq(&self, other: &Self) -> bool {
13852        self.message == other.message && self.actions == other.actions
13853    }
13854}
13855
13856#[derive(Clone, Debug, PartialEq)]
13857pub enum LanguageServerLogType {
13858    Log(MessageType),
13859    Trace { verbose_info: Option<String> },
13860    Rpc { received: bool },
13861}
13862
13863impl LanguageServerLogType {
13864    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13865        match self {
13866            Self::Log(log_type) => {
13867                use proto::log_message::LogLevel;
13868                let level = match *log_type {
13869                    MessageType::ERROR => LogLevel::Error,
13870                    MessageType::WARNING => LogLevel::Warning,
13871                    MessageType::INFO => LogLevel::Info,
13872                    MessageType::LOG => LogLevel::Log,
13873                    other => {
13874                        log::warn!("Unknown lsp log message type: {other:?}");
13875                        LogLevel::Log
13876                    }
13877                };
13878                proto::language_server_log::LogType::Log(proto::LogMessage {
13879                    level: level as i32,
13880                })
13881            }
13882            Self::Trace { verbose_info } => {
13883                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13884                    verbose_info: verbose_info.to_owned(),
13885                })
13886            }
13887            Self::Rpc { received } => {
13888                let kind = if *received {
13889                    proto::rpc_message::Kind::Received
13890                } else {
13891                    proto::rpc_message::Kind::Sent
13892                };
13893                let kind = kind as i32;
13894                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13895            }
13896        }
13897    }
13898
13899    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13900        use proto::log_message::LogLevel;
13901        use proto::rpc_message;
13902        match log_type {
13903            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13904                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13905                    LogLevel::Error => MessageType::ERROR,
13906                    LogLevel::Warning => MessageType::WARNING,
13907                    LogLevel::Info => MessageType::INFO,
13908                    LogLevel::Log => MessageType::LOG,
13909                },
13910            ),
13911            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13912                verbose_info: trace_message.verbose_info,
13913            },
13914            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13915                received: match rpc_message::Kind::from_i32(message.kind)
13916                    .unwrap_or(rpc_message::Kind::Received)
13917                {
13918                    rpc_message::Kind::Received => true,
13919                    rpc_message::Kind::Sent => false,
13920                },
13921            },
13922        }
13923    }
13924}
13925
13926pub struct WorkspaceRefreshTask {
13927    refresh_tx: mpsc::Sender<()>,
13928    progress_tx: mpsc::Sender<()>,
13929    #[allow(dead_code)]
13930    task: Task<()>,
13931}
13932
13933pub enum LanguageServerState {
13934    Starting {
13935        startup: Task<Option<Arc<LanguageServer>>>,
13936        /// List of language servers that will be added to the workspace once it's initialization completes.
13937        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13938    },
13939
13940    Running {
13941        adapter: Arc<CachedLspAdapter>,
13942        server: Arc<LanguageServer>,
13943        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13944        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13945    },
13946}
13947
13948impl LanguageServerState {
13949    fn add_workspace_folder(&self, uri: Uri) {
13950        match self {
13951            LanguageServerState::Starting {
13952                pending_workspace_folders,
13953                ..
13954            } => {
13955                pending_workspace_folders.lock().insert(uri);
13956            }
13957            LanguageServerState::Running { server, .. } => {
13958                server.add_workspace_folder(uri);
13959            }
13960        }
13961    }
13962    fn _remove_workspace_folder(&self, uri: Uri) {
13963        match self {
13964            LanguageServerState::Starting {
13965                pending_workspace_folders,
13966                ..
13967            } => {
13968                pending_workspace_folders.lock().remove(&uri);
13969            }
13970            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13971        }
13972    }
13973}
13974
13975impl std::fmt::Debug for LanguageServerState {
13976    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13977        match self {
13978            LanguageServerState::Starting { .. } => {
13979                f.debug_struct("LanguageServerState::Starting").finish()
13980            }
13981            LanguageServerState::Running { .. } => {
13982                f.debug_struct("LanguageServerState::Running").finish()
13983            }
13984        }
13985    }
13986}
13987
13988#[derive(Clone, Debug, Serialize)]
13989pub struct LanguageServerProgress {
13990    pub is_disk_based_diagnostics_progress: bool,
13991    pub is_cancellable: bool,
13992    pub title: Option<String>,
13993    pub message: Option<String>,
13994    pub percentage: Option<usize>,
13995    #[serde(skip_serializing)]
13996    pub last_update_at: Instant,
13997}
13998
13999#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
14000pub struct DiagnosticSummary {
14001    pub error_count: usize,
14002    pub warning_count: usize,
14003}
14004
14005impl DiagnosticSummary {
14006    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
14007        let mut this = Self {
14008            error_count: 0,
14009            warning_count: 0,
14010        };
14011
14012        for entry in diagnostics {
14013            if entry.diagnostic.is_primary {
14014                match entry.diagnostic.severity {
14015                    DiagnosticSeverity::ERROR => this.error_count += 1,
14016                    DiagnosticSeverity::WARNING => this.warning_count += 1,
14017                    _ => {}
14018                }
14019            }
14020        }
14021
14022        this
14023    }
14024
14025    pub fn is_empty(&self) -> bool {
14026        self.error_count == 0 && self.warning_count == 0
14027    }
14028
14029    pub fn to_proto(
14030        self,
14031        language_server_id: LanguageServerId,
14032        path: &RelPath,
14033    ) -> proto::DiagnosticSummary {
14034        proto::DiagnosticSummary {
14035            path: path.to_proto(),
14036            language_server_id: language_server_id.0 as u64,
14037            error_count: self.error_count as u32,
14038            warning_count: self.warning_count as u32,
14039        }
14040    }
14041}
14042
14043#[derive(Clone, Debug)]
14044pub enum CompletionDocumentation {
14045    /// There is no documentation for this completion.
14046    Undocumented,
14047    /// A single line of documentation.
14048    SingleLine(SharedString),
14049    /// Multiple lines of plain text documentation.
14050    MultiLinePlainText(SharedString),
14051    /// Markdown documentation.
14052    MultiLineMarkdown(SharedString),
14053    /// Both single line and multiple lines of plain text documentation.
14054    SingleLineAndMultiLinePlainText {
14055        single_line: SharedString,
14056        plain_text: Option<SharedString>,
14057    },
14058}
14059
14060impl CompletionDocumentation {
14061    #[cfg(any(test, feature = "test-support"))]
14062    pub fn text(&self) -> SharedString {
14063        match self {
14064            CompletionDocumentation::Undocumented => "".into(),
14065            CompletionDocumentation::SingleLine(s) => s.clone(),
14066            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
14067            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
14068            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
14069                single_line.clone()
14070            }
14071        }
14072    }
14073}
14074
14075impl From<lsp::Documentation> for CompletionDocumentation {
14076    fn from(docs: lsp::Documentation) -> Self {
14077        match docs {
14078            lsp::Documentation::String(text) => {
14079                if text.lines().count() <= 1 {
14080                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
14081                } else {
14082                    CompletionDocumentation::MultiLinePlainText(text.into())
14083                }
14084            }
14085
14086            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
14087                lsp::MarkupKind::PlainText => {
14088                    if value.lines().count() <= 1 {
14089                        CompletionDocumentation::SingleLine(value.into())
14090                    } else {
14091                        CompletionDocumentation::MultiLinePlainText(value.into())
14092                    }
14093                }
14094
14095                lsp::MarkupKind::Markdown => {
14096                    CompletionDocumentation::MultiLineMarkdown(value.into())
14097                }
14098            },
14099        }
14100    }
14101}
14102
14103pub enum ResolvedHint {
14104    Resolved(InlayHint),
14105    Resolving(Shared<Task<()>>),
14106}
14107
14108pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
14109    glob.components()
14110        .take_while(|component| match component {
14111            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
14112            _ => true,
14113        })
14114        .collect()
14115}
14116
14117pub struct SshLspAdapter {
14118    name: LanguageServerName,
14119    binary: LanguageServerBinary,
14120    initialization_options: Option<String>,
14121    code_action_kinds: Option<Vec<CodeActionKind>>,
14122}
14123
14124impl SshLspAdapter {
14125    pub fn new(
14126        name: LanguageServerName,
14127        binary: LanguageServerBinary,
14128        initialization_options: Option<String>,
14129        code_action_kinds: Option<String>,
14130    ) -> Self {
14131        Self {
14132            name,
14133            binary,
14134            initialization_options,
14135            code_action_kinds: code_action_kinds
14136                .as_ref()
14137                .and_then(|c| serde_json::from_str(c).ok()),
14138        }
14139    }
14140}
14141
14142impl LspInstaller for SshLspAdapter {
14143    type BinaryVersion = ();
14144    async fn check_if_user_installed(
14145        &self,
14146        _: &dyn LspAdapterDelegate,
14147        _: Option<Toolchain>,
14148        _: &AsyncApp,
14149    ) -> Option<LanguageServerBinary> {
14150        Some(self.binary.clone())
14151    }
14152
14153    async fn cached_server_binary(
14154        &self,
14155        _: PathBuf,
14156        _: &dyn LspAdapterDelegate,
14157    ) -> Option<LanguageServerBinary> {
14158        None
14159    }
14160
14161    async fn fetch_latest_server_version(
14162        &self,
14163        _: &dyn LspAdapterDelegate,
14164        _: bool,
14165        _: &mut AsyncApp,
14166    ) -> Result<()> {
14167        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14168    }
14169
14170    async fn fetch_server_binary(
14171        &self,
14172        _: (),
14173        _: PathBuf,
14174        _: &dyn LspAdapterDelegate,
14175    ) -> Result<LanguageServerBinary> {
14176        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14177    }
14178}
14179
14180#[async_trait(?Send)]
14181impl LspAdapter for SshLspAdapter {
14182    fn name(&self) -> LanguageServerName {
14183        self.name.clone()
14184    }
14185
14186    async fn initialization_options(
14187        self: Arc<Self>,
14188        _: &Arc<dyn LspAdapterDelegate>,
14189        _: &mut AsyncApp,
14190    ) -> Result<Option<serde_json::Value>> {
14191        let Some(options) = &self.initialization_options else {
14192            return Ok(None);
14193        };
14194        let result = serde_json::from_str(options)?;
14195        Ok(result)
14196    }
14197
14198    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14199        self.code_action_kinds.clone()
14200    }
14201}
14202
14203pub fn language_server_settings<'a>(
14204    delegate: &'a dyn LspAdapterDelegate,
14205    language: &LanguageServerName,
14206    cx: &'a App,
14207) -> Option<&'a LspSettings> {
14208    language_server_settings_for(
14209        SettingsLocation {
14210            worktree_id: delegate.worktree_id(),
14211            path: RelPath::empty(),
14212        },
14213        language,
14214        cx,
14215    )
14216}
14217
14218pub fn language_server_settings_for<'a>(
14219    location: SettingsLocation<'a>,
14220    language: &LanguageServerName,
14221    cx: &'a App,
14222) -> Option<&'a LspSettings> {
14223    ProjectSettings::get(Some(location), cx).lsp.get(language)
14224}
14225
14226pub struct LocalLspAdapterDelegate {
14227    lsp_store: WeakEntity<LspStore>,
14228    worktree: worktree::Snapshot,
14229    fs: Arc<dyn Fs>,
14230    http_client: Arc<dyn HttpClient>,
14231    language_registry: Arc<LanguageRegistry>,
14232    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14233}
14234
14235impl LocalLspAdapterDelegate {
14236    pub fn new(
14237        language_registry: Arc<LanguageRegistry>,
14238        environment: &Entity<ProjectEnvironment>,
14239        lsp_store: WeakEntity<LspStore>,
14240        worktree: &Entity<Worktree>,
14241        http_client: Arc<dyn HttpClient>,
14242        fs: Arc<dyn Fs>,
14243        cx: &mut App,
14244    ) -> Arc<Self> {
14245        let load_shell_env_task =
14246            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14247
14248        Arc::new(Self {
14249            lsp_store,
14250            worktree: worktree.read(cx).snapshot(),
14251            fs,
14252            http_client,
14253            language_registry,
14254            load_shell_env_task,
14255        })
14256    }
14257
14258    pub fn from_local_lsp(
14259        local: &LocalLspStore,
14260        worktree: &Entity<Worktree>,
14261        cx: &mut App,
14262    ) -> Arc<Self> {
14263        Self::new(
14264            local.languages.clone(),
14265            &local.environment,
14266            local.weak.clone(),
14267            worktree,
14268            local.http_client.clone(),
14269            local.fs.clone(),
14270            cx,
14271        )
14272    }
14273}
14274
14275#[async_trait]
14276impl LspAdapterDelegate for LocalLspAdapterDelegate {
14277    fn show_notification(&self, message: &str, cx: &mut App) {
14278        self.lsp_store
14279            .update(cx, |_, cx| {
14280                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14281            })
14282            .ok();
14283    }
14284
14285    fn http_client(&self) -> Arc<dyn HttpClient> {
14286        self.http_client.clone()
14287    }
14288
14289    fn worktree_id(&self) -> WorktreeId {
14290        self.worktree.id()
14291    }
14292
14293    fn worktree_root_path(&self) -> &Path {
14294        self.worktree.abs_path().as_ref()
14295    }
14296
14297    fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
14298        self.worktree.resolve_relative_path(path)
14299    }
14300
14301    async fn shell_env(&self) -> HashMap<String, String> {
14302        let task = self.load_shell_env_task.clone();
14303        task.await.unwrap_or_default()
14304    }
14305
14306    async fn npm_package_installed_version(
14307        &self,
14308        package_name: &str,
14309    ) -> Result<Option<(PathBuf, Version)>> {
14310        let local_package_directory = self.worktree_root_path();
14311        let node_modules_directory = local_package_directory.join("node_modules");
14312
14313        if let Some(version) =
14314            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14315        {
14316            return Ok(Some((node_modules_directory, version)));
14317        }
14318        let Some(npm) = self.which("npm".as_ref()).await else {
14319            log::warn!(
14320                "Failed to find npm executable for {:?}",
14321                local_package_directory
14322            );
14323            return Ok(None);
14324        };
14325
14326        let env = self.shell_env().await;
14327        let output = util::command::new_command(&npm)
14328            .args(["root", "-g"])
14329            .envs(env)
14330            .current_dir(local_package_directory)
14331            .output()
14332            .await?;
14333        let global_node_modules =
14334            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14335
14336        if let Some(version) =
14337            read_package_installed_version(global_node_modules.clone(), package_name).await?
14338        {
14339            return Ok(Some((global_node_modules, version)));
14340        }
14341        return Ok(None);
14342    }
14343
14344    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14345        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14346        if self.fs.is_file(&worktree_abs_path).await {
14347            worktree_abs_path.pop();
14348        }
14349
14350        let env = self.shell_env().await;
14351
14352        let shell_path = env.get("PATH").cloned();
14353
14354        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14355    }
14356
14357    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14358        let mut working_dir = self.worktree_root_path().to_path_buf();
14359        if self.fs.is_file(&working_dir).await {
14360            working_dir.pop();
14361        }
14362        let output = util::command::new_command(&command.path)
14363            .args(command.arguments)
14364            .envs(command.env.clone().unwrap_or_default())
14365            .current_dir(working_dir)
14366            .output()
14367            .await?;
14368
14369        anyhow::ensure!(
14370            output.status.success(),
14371            "{}, stdout: {:?}, stderr: {:?}",
14372            output.status,
14373            String::from_utf8_lossy(&output.stdout),
14374            String::from_utf8_lossy(&output.stderr)
14375        );
14376        Ok(())
14377    }
14378
14379    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14380        self.language_registry
14381            .update_lsp_binary_status(server_name, status);
14382    }
14383
14384    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14385        self.language_registry
14386            .all_lsp_adapters()
14387            .into_iter()
14388            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14389            .collect()
14390    }
14391
14392    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14393        let dir = self.language_registry.language_server_download_dir(name)?;
14394
14395        if !dir.exists() {
14396            smol::fs::create_dir_all(&dir)
14397                .await
14398                .context("failed to create container directory")
14399                .log_err()?;
14400        }
14401
14402        Some(dir)
14403    }
14404
14405    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14406        let entry = self
14407            .worktree
14408            .entry_for_path(path)
14409            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14410        let abs_path = self.worktree.absolutize(&entry.path);
14411        self.fs.load(&abs_path).await
14412    }
14413}
14414
14415async fn populate_labels_for_symbols(
14416    symbols: Vec<CoreSymbol>,
14417    language_registry: &Arc<LanguageRegistry>,
14418    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14419    output: &mut Vec<Symbol>,
14420) {
14421    #[allow(clippy::mutable_key_type)]
14422    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14423
14424    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14425    for symbol in symbols {
14426        let Some(file_name) = symbol.path.file_name() else {
14427            continue;
14428        };
14429        let language = language_registry
14430            .load_language_for_file_path(Path::new(file_name))
14431            .await
14432            .ok()
14433            .or_else(|| {
14434                unknown_paths.insert(file_name.into());
14435                None
14436            });
14437        symbols_by_language
14438            .entry(language)
14439            .or_default()
14440            .push(symbol);
14441    }
14442
14443    for unknown_path in unknown_paths {
14444        log::info!("no language found for symbol in file {unknown_path:?}");
14445    }
14446
14447    let mut label_params = Vec::new();
14448    for (language, mut symbols) in symbols_by_language {
14449        label_params.clear();
14450        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14451            name: mem::take(&mut symbol.name),
14452            kind: symbol.kind,
14453            container_name: symbol.container_name.take(),
14454        }));
14455
14456        let mut labels = Vec::new();
14457        if let Some(language) = language {
14458            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14459                language_registry
14460                    .lsp_adapters(&language.name())
14461                    .first()
14462                    .cloned()
14463            });
14464            if let Some(lsp_adapter) = lsp_adapter {
14465                labels = lsp_adapter
14466                    .labels_for_symbols(&label_params, &language)
14467                    .await
14468                    .log_err()
14469                    .unwrap_or_default();
14470            }
14471        }
14472
14473        for (
14474            (
14475                symbol,
14476                language::Symbol {
14477                    name,
14478                    container_name,
14479                    ..
14480                },
14481            ),
14482            label,
14483        ) in symbols
14484            .into_iter()
14485            .zip(label_params.drain(..))
14486            .zip(labels.into_iter().chain(iter::repeat(None)))
14487        {
14488            output.push(Symbol {
14489                language_server_name: symbol.language_server_name,
14490                source_worktree_id: symbol.source_worktree_id,
14491                source_language_server_id: symbol.source_language_server_id,
14492                path: symbol.path,
14493                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14494                name,
14495                kind: symbol.kind,
14496                range: symbol.range,
14497                container_name,
14498            });
14499        }
14500    }
14501}
14502
14503pub(crate) fn collapse_newlines(text: &str, separator: &str) -> String {
14504    text.lines()
14505        .map(|line| line.trim())
14506        .filter(|line| !line.is_empty())
14507        .join(separator)
14508}
14509
14510fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14511    match server.capabilities().text_document_sync.as_ref()? {
14512        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14513            // Server wants didSave but didn't specify includeText.
14514            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14515            // Server doesn't want didSave at all.
14516            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14517            // Server provided SaveOptions.
14518            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14519                Some(save_options.include_text.unwrap_or(false))
14520            }
14521        },
14522        // We do not have any save info. Kind affects didChange only.
14523        lsp::TextDocumentSyncCapability::Kind(_) => None,
14524    }
14525}
14526
14527/// Completion items are displayed in a `UniformList`.
14528/// Usually, those items are single-line strings, but in LSP responses,
14529/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14530/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14531/// 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,
14532/// breaking the completions menu presentation.
14533///
14534/// 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.
14535pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14536    let mut new_text = String::with_capacity(label.text.len());
14537    let mut offset_map = vec![0; label.text.len() + 1];
14538    let mut last_char_was_space = false;
14539    let mut new_idx = 0;
14540    let chars = label.text.char_indices().fuse();
14541    let mut newlines_removed = false;
14542
14543    for (idx, c) in chars {
14544        offset_map[idx] = new_idx;
14545
14546        match c {
14547            '\n' if last_char_was_space => {
14548                newlines_removed = true;
14549            }
14550            '\t' | ' ' if last_char_was_space => {}
14551            '\n' if !last_char_was_space => {
14552                new_text.push(' ');
14553                new_idx += 1;
14554                last_char_was_space = true;
14555                newlines_removed = true;
14556            }
14557            ' ' | '\t' => {
14558                new_text.push(' ');
14559                new_idx += 1;
14560                last_char_was_space = true;
14561            }
14562            _ => {
14563                new_text.push(c);
14564                new_idx += c.len_utf8();
14565                last_char_was_space = false;
14566            }
14567        }
14568    }
14569    offset_map[label.text.len()] = new_idx;
14570
14571    // Only modify the label if newlines were removed.
14572    if !newlines_removed {
14573        return;
14574    }
14575
14576    let last_index = new_idx;
14577    let mut run_ranges_errors = Vec::new();
14578    label.runs.retain_mut(|(range, _)| {
14579        match offset_map.get(range.start) {
14580            Some(&start) => range.start = start,
14581            None => {
14582                run_ranges_errors.push(range.clone());
14583                return false;
14584            }
14585        }
14586
14587        match offset_map.get(range.end) {
14588            Some(&end) => range.end = end,
14589            None => {
14590                run_ranges_errors.push(range.clone());
14591                range.end = last_index;
14592            }
14593        }
14594        true
14595    });
14596    if !run_ranges_errors.is_empty() {
14597        log::error!(
14598            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14599            label.text
14600        );
14601    }
14602
14603    let mut wrong_filter_range = None;
14604    if label.filter_range == (0..label.text.len()) {
14605        label.filter_range = 0..new_text.len();
14606    } else {
14607        let mut original_filter_range = Some(label.filter_range.clone());
14608        match offset_map.get(label.filter_range.start) {
14609            Some(&start) => label.filter_range.start = start,
14610            None => {
14611                wrong_filter_range = original_filter_range.take();
14612                label.filter_range.start = last_index;
14613            }
14614        }
14615
14616        match offset_map.get(label.filter_range.end) {
14617            Some(&end) => label.filter_range.end = end,
14618            None => {
14619                wrong_filter_range = original_filter_range.take();
14620                label.filter_range.end = last_index;
14621            }
14622        }
14623    }
14624    if let Some(wrong_filter_range) = wrong_filter_range {
14625        log::error!(
14626            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14627            label.text
14628        );
14629    }
14630
14631    label.text = new_text;
14632}
14633
14634/// Apply edits to the buffer that will become part of the formatting transaction.
14635/// Fails if the buffer has been edited since the start of that transaction.
14636fn extend_formatting_transaction(
14637    buffer: &FormattableBuffer,
14638    formatting_transaction_id: text::TransactionId,
14639    cx: &mut AsyncApp,
14640    operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
14641) -> anyhow::Result<()> {
14642    buffer.handle.update(cx, |buffer, cx| {
14643        let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
14644        if last_transaction_id != Some(formatting_transaction_id) {
14645            anyhow::bail!("Buffer edited while formatting. Aborting")
14646        }
14647        buffer.start_transaction();
14648        operation(buffer, cx);
14649        if let Some(transaction_id) = buffer.end_transaction(cx) {
14650            buffer.merge_transactions(transaction_id, formatting_transaction_id);
14651        }
14652        Ok(())
14653    })
14654}