lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13mod code_lens;
   14mod document_colors;
   15mod document_symbols;
   16mod folding_ranges;
   17mod inlay_hints;
   18pub mod json_language_server_ext;
   19pub mod log_store;
   20pub mod lsp_ext_command;
   21pub mod rust_analyzer_ext;
   22mod semantic_tokens;
   23pub mod vue_language_server_ext;
   24
   25use self::code_lens::CodeLensData;
   26use self::document_colors::DocumentColorData;
   27use self::document_symbols::DocumentSymbolsData;
   28use self::inlay_hints::BufferInlayHints;
   29use crate::{
   30    CodeAction, Completion, CompletionDisplayOptions, CompletionResponse, CompletionSource,
   31    CoreCompletion, Hover, InlayHint, InlayId, LocationLink, LspAction, LspPullDiagnostics,
   32    ManifestProvidersStore, Project, ProjectItem, ProjectPath, ProjectTransaction,
   33    PulledDiagnostics, ResolveState, Symbol,
   34    buffer_store::{BufferStore, BufferStoreEvent},
   35    environment::ProjectEnvironment,
   36    lsp_command::{self, *},
   37    lsp_store::{
   38        self,
   39        folding_ranges::FoldingRangeData,
   40        log_store::{GlobalLogStore, LanguageServerKind},
   41        semantic_tokens::{SemanticTokenConfig, SemanticTokensData},
   42    },
   43    manifest_tree::{
   44        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   45        ManifestTree,
   46    },
   47    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   48    project_settings::{BinarySettings, LspSettings, ProjectSettings},
   49    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   50    trusted_worktrees::{PathTrust, TrustedWorktrees, TrustedWorktreesEvent},
   51    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   52    yarn::YarnPathStore,
   53};
   54use anyhow::{Context as _, Result, anyhow};
   55use async_trait::async_trait;
   56use client::{TypedEnvelope, proto};
   57use clock::Global;
   58use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   59use futures::{
   60    AsyncWriteExt, Future, FutureExt, StreamExt,
   61    future::{Either, Shared, join_all, pending, select},
   62    select, select_biased,
   63    stream::FuturesUnordered,
   64};
   65use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   66use gpui::{
   67    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString,
   68    Subscription, Task, WeakEntity,
   69};
   70use http_client::HttpClient;
   71use itertools::Itertools as _;
   72use language::{
   73    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, Capability, CodeLabel,
   74    CodeLabelExt, Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff,
   75    File as _, Language, LanguageAwareStyling, LanguageName, LanguageRegistry, LocalFile,
   76    LspAdapter, LspAdapterDelegate, LspInstaller, ManifestDelegate, ManifestName, ModelineSettings,
   77    OffsetUtf16, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToOffsetUtf16, ToPointUtf16,
   78    Toolchain, Transaction, Unclipped,
   79    language_settings::{
   80        AllLanguageSettings, FormatOnSave, Formatter, LanguageSettings, all_language_settings,
   81    },
   82    modeline, point_to_lsp,
   83    proto::{
   84        deserialize_anchor, deserialize_anchor_range, deserialize_version, serialize_anchor,
   85        serialize_anchor_range, serialize_version,
   86    },
   87    range_from_lsp, range_to_lsp,
   88    row_chunk::RowChunk,
   89};
   90use lsp::{
   91    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   92    DEFAULT_LSP_REQUEST_TIMEOUT, DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   93    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   94    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LanguageServer,
   95    LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId, LanguageServerName,
   96    LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType, OneOf,
   97    RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles,
   98    WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   99};
  100use node_runtime::read_package_installed_version;
  101use parking_lot::Mutex;
  102use postage::{mpsc, sink::Sink, stream::Stream, watch};
  103use rand::prelude::*;
  104use rpc::{
  105    AnyProtoClient, ErrorCode, ErrorExt as _,
  106    proto::{LspRequestId, LspRequestMessage as _},
  107};
  108use semver::Version;
  109use serde::Serialize;
  110use serde_json::Value;
  111use settings::{Settings, SettingsLocation, SettingsStore};
  112use sha2::{Digest, Sha256};
  113use snippet::Snippet;
  114use std::{
  115    any::TypeId,
  116    borrow::Cow,
  117    cell::RefCell,
  118    cmp::{Ordering, Reverse},
  119    collections::{VecDeque, hash_map},
  120    convert::TryInto,
  121    ffi::OsStr,
  122    future::ready,
  123    iter, mem,
  124    ops::{ControlFlow, Range},
  125    path::{self, Path, PathBuf},
  126    pin::pin,
  127    rc::Rc,
  128    sync::{
  129        Arc,
  130        atomic::{self, AtomicUsize},
  131    },
  132    time::{Duration, Instant},
  133    vec,
  134};
  135use sum_tree::Dimensions;
  136use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  137
  138use util::{
  139    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  140    paths::{PathStyle, SanitizedPath, UrlExt},
  141    post_inc,
  142    redact::redact_command,
  143    rel_path::RelPath,
  144};
  145
  146pub use document_colors::DocumentColors;
  147pub use folding_ranges::LspFoldingRange;
  148pub use fs::*;
  149pub use language::Location;
  150pub use lsp_store::inlay_hints::{CacheInlayHints, InvalidationStrategy};
  151#[cfg(any(test, feature = "test-support"))]
  152pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  153#[cfg(any(test, feature = "test-support"))]
  154pub use prettier::RANGE_FORMAT_SUFFIX as TEST_PRETTIER_RANGE_FORMAT_SUFFIX;
  155pub use semantic_tokens::{
  156    BufferSemanticToken, BufferSemanticTokens, RefreshForServer, SemanticTokenStylizer, TokenType,
  157};
  158
  159pub use worktree::{
  160    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  161    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  162};
  163
  164const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  165pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  166const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  167const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  168static NEXT_PROMPT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
  169
  170#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  171pub enum ProgressToken {
  172    Number(i32),
  173    String(SharedString),
  174}
  175
  176impl std::fmt::Display for ProgressToken {
  177    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  178        match self {
  179            Self::Number(number) => write!(f, "{number}"),
  180            Self::String(string) => write!(f, "{string}"),
  181        }
  182    }
  183}
  184
  185impl ProgressToken {
  186    fn from_lsp(value: lsp::NumberOrString) -> Self {
  187        match value {
  188            lsp::NumberOrString::Number(number) => Self::Number(number),
  189            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  190        }
  191    }
  192
  193    fn to_lsp(&self) -> lsp::NumberOrString {
  194        match self {
  195            Self::Number(number) => lsp::NumberOrString::Number(*number),
  196            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  197        }
  198    }
  199
  200    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  201        Some(match value.value? {
  202            proto::progress_token::Value::Number(number) => Self::Number(number),
  203            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  204        })
  205    }
  206
  207    fn to_proto(&self) -> proto::ProgressToken {
  208        proto::ProgressToken {
  209            value: Some(match self {
  210                Self::Number(number) => proto::progress_token::Value::Number(*number),
  211                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  212            }),
  213        }
  214    }
  215}
  216
  217#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  218pub enum FormatTrigger {
  219    Save,
  220    Manual,
  221}
  222
  223pub enum LspFormatTarget {
  224    Buffers,
  225    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  226}
  227
  228#[derive(Debug, Clone, PartialEq, Eq, Hash)]
  229pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  230
  231struct OpenLspBuffer(Entity<Buffer>);
  232
  233impl FormatTrigger {
  234    fn from_proto(value: i32) -> FormatTrigger {
  235        match value {
  236            0 => FormatTrigger::Save,
  237            1 => FormatTrigger::Manual,
  238            _ => FormatTrigger::Save,
  239        }
  240    }
  241}
  242
  243#[derive(Clone)]
  244struct UnifiedLanguageServer {
  245    id: LanguageServerId,
  246    project_roots: HashSet<Arc<RelPath>>,
  247}
  248
  249/// Settings that affect language server identity.
  250///
  251/// Dynamic settings (`LspSettings::settings`) are excluded because they can be
  252/// updated via `workspace/didChangeConfiguration` without restarting the server.
  253#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  254struct LanguageServerSeedSettings {
  255    binary: Option<BinarySettings>,
  256    initialization_options: Option<serde_json::Value>,
  257}
  258
  259#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  260struct LanguageServerSeed {
  261    worktree_id: WorktreeId,
  262    name: LanguageServerName,
  263    toolchain: Option<Toolchain>,
  264    settings: LanguageServerSeedSettings,
  265}
  266
  267#[derive(Debug)]
  268pub struct DocumentDiagnosticsUpdate<'a, D> {
  269    pub diagnostics: D,
  270    pub result_id: Option<SharedString>,
  271    pub registration_id: Option<SharedString>,
  272    pub server_id: LanguageServerId,
  273    pub disk_based_sources: Cow<'a, [String]>,
  274}
  275
  276pub struct DocumentDiagnostics {
  277    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  278    document_abs_path: PathBuf,
  279    version: Option<i32>,
  280}
  281
  282#[derive(Default, Debug)]
  283struct DynamicRegistrations {
  284    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  285    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  286}
  287
  288pub struct LocalLspStore {
  289    weak: WeakEntity<LspStore>,
  290    pub worktree_store: Entity<WorktreeStore>,
  291    toolchain_store: Entity<LocalToolchainStore>,
  292    http_client: Arc<dyn HttpClient>,
  293    environment: Entity<ProjectEnvironment>,
  294    fs: Arc<dyn Fs>,
  295    languages: Arc<LanguageRegistry>,
  296    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  297    yarn: Entity<YarnPathStore>,
  298    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  299    buffers_being_formatted: HashSet<BufferId>,
  300    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  301    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  302    watched_manifest_filenames: HashSet<ManifestName>,
  303    language_server_paths_watched_for_rename:
  304        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  305    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  306    supplementary_language_servers:
  307        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  308    prettier_store: Entity<PrettierStore>,
  309    next_diagnostic_group_id: usize,
  310    diagnostics: HashMap<
  311        WorktreeId,
  312        HashMap<
  313            Arc<RelPath>,
  314            Vec<(
  315                LanguageServerId,
  316                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  317            )>,
  318        >,
  319    >,
  320    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  321    _subscription: gpui::Subscription,
  322    lsp_tree: LanguageServerTree,
  323    registered_buffers: HashMap<BufferId, usize>,
  324    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  325    buffer_pull_diagnostics_result_ids: HashMap<
  326        LanguageServerId,
  327        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  328    >,
  329    workspace_pull_diagnostics_result_ids: HashMap<
  330        LanguageServerId,
  331        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  332    >,
  333    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  334
  335    buffers_to_refresh_hash_set: HashSet<BufferId>,
  336    buffers_to_refresh_queue: VecDeque<BufferId>,
  337    _background_diagnostics_worker: Shared<Task<()>>,
  338}
  339
  340impl LocalLspStore {
  341    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  342    pub fn running_language_server_for_id(
  343        &self,
  344        id: LanguageServerId,
  345    ) -> Option<&Arc<LanguageServer>> {
  346        let language_server_state = self.language_servers.get(&id)?;
  347
  348        match language_server_state {
  349            LanguageServerState::Running { server, .. } => Some(server),
  350            LanguageServerState::Starting { .. } => None,
  351        }
  352    }
  353
  354    fn get_or_insert_language_server(
  355        &mut self,
  356        worktree_handle: &Entity<Worktree>,
  357        delegate: Arc<LocalLspAdapterDelegate>,
  358        disposition: &Arc<LaunchDisposition>,
  359        language_name: &LanguageName,
  360        cx: &mut App,
  361    ) -> LanguageServerId {
  362        let key = LanguageServerSeed {
  363            worktree_id: worktree_handle.read(cx).id(),
  364            name: disposition.server_name.clone(),
  365            settings: LanguageServerSeedSettings {
  366                binary: disposition.settings.binary.clone(),
  367                initialization_options: disposition.settings.initialization_options.clone(),
  368            },
  369            toolchain: disposition.toolchain.clone(),
  370        };
  371        if let Some(state) = self.language_server_ids.get_mut(&key) {
  372            state.project_roots.insert(disposition.path.path.clone());
  373            state.id
  374        } else {
  375            let adapter = self
  376                .languages
  377                .lsp_adapters(language_name)
  378                .into_iter()
  379                .find(|adapter| adapter.name() == disposition.server_name)
  380                .expect("To find LSP adapter");
  381            let new_language_server_id = self.start_language_server(
  382                worktree_handle,
  383                delegate,
  384                adapter,
  385                disposition.settings.clone(),
  386                key.clone(),
  387                language_name.clone(),
  388                cx,
  389            );
  390            if let Some(state) = self.language_server_ids.get_mut(&key) {
  391                state.project_roots.insert(disposition.path.path.clone());
  392            } else {
  393                debug_assert!(
  394                    false,
  395                    "Expected `start_language_server` to ensure that `key` exists in a map"
  396                );
  397            }
  398            new_language_server_id
  399        }
  400    }
  401
  402    fn start_language_server(
  403        &mut self,
  404        worktree_handle: &Entity<Worktree>,
  405        delegate: Arc<LocalLspAdapterDelegate>,
  406        adapter: Arc<CachedLspAdapter>,
  407        settings: Arc<LspSettings>,
  408        key: LanguageServerSeed,
  409        language_name: LanguageName,
  410        cx: &mut App,
  411    ) -> LanguageServerId {
  412        let worktree = worktree_handle.read(cx);
  413
  414        let worktree_id = worktree.id();
  415        let worktree_abs_path = worktree.abs_path();
  416        let toolchain = key.toolchain.clone();
  417        let override_options = settings.initialization_options.clone();
  418
  419        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  420
  421        let server_id = self.languages.next_language_server_id();
  422        log::trace!(
  423            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  424            adapter.name.0
  425        );
  426
  427        let wait_until_worktree_trust =
  428            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  429                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  430                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  431                });
  432                if can_trust {
  433                    self.restricted_worktrees_tasks.remove(&worktree_id);
  434                    None
  435                } else {
  436                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  437                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  438                        hash_map::Entry::Vacant(v) => {
  439                            let (mut tx, rx) = watch::channel::<bool>();
  440                            let lsp_store = self.weak.clone();
  441                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  442                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  443                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  444                                        tx.blocking_send(true).ok();
  445                                        lsp_store
  446                                            .update(cx, |lsp_store, _| {
  447                                                if let Some(local_lsp_store) =
  448                                                    lsp_store.as_local_mut()
  449                                                {
  450                                                    local_lsp_store
  451                                                        .restricted_worktrees_tasks
  452                                                        .remove(&worktree_id);
  453                                                }
  454                                            })
  455                                            .ok();
  456                                    }
  457                                }
  458                            });
  459                            v.insert((subscription, rx.clone()));
  460                            Some(rx)
  461                        }
  462                    }
  463                }
  464            });
  465        let update_binary_status = wait_until_worktree_trust.is_none();
  466
  467        let binary = self.get_language_server_binary(
  468            worktree_abs_path.clone(),
  469            adapter.clone(),
  470            settings,
  471            toolchain.clone(),
  472            delegate.clone(),
  473            true,
  474            wait_until_worktree_trust,
  475            cx,
  476        );
  477        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  478
  479        let pending_server = cx.spawn({
  480            let adapter = adapter.clone();
  481            let server_name = adapter.name.clone();
  482            let stderr_capture = stderr_capture.clone();
  483            #[cfg(any(test, feature = "test-support"))]
  484            let lsp_store = self.weak.clone();
  485            let pending_workspace_folders = pending_workspace_folders.clone();
  486            async move |cx| {
  487                let binary = binary.await?;
  488                #[cfg(any(test, feature = "test-support"))]
  489                if let Some(server) = lsp_store
  490                    .update(&mut cx.clone(), |this, cx| {
  491                        this.languages.create_fake_language_server(
  492                            server_id,
  493                            &server_name,
  494                            binary.clone(),
  495                            &mut cx.to_async(),
  496                        )
  497                    })
  498                    .ok()
  499                    .flatten()
  500                {
  501                    return Ok(server);
  502                }
  503
  504                let code_action_kinds = adapter.code_action_kinds();
  505                lsp::LanguageServer::new(
  506                    stderr_capture,
  507                    server_id,
  508                    server_name,
  509                    binary,
  510                    &worktree_abs_path,
  511                    code_action_kinds,
  512                    Some(pending_workspace_folders),
  513                    cx,
  514                )
  515            }
  516        });
  517
  518        let startup = {
  519            let server_name = adapter.name.0.clone();
  520            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  521            let key = key.clone();
  522            let adapter = adapter.clone();
  523            let lsp_store = self.weak.clone();
  524            let pending_workspace_folders = pending_workspace_folders.clone();
  525            let pull_diagnostics = ProjectSettings::get_global(cx)
  526                .diagnostics
  527                .lsp_pull_diagnostics
  528                .enabled;
  529            let settings_location = SettingsLocation {
  530                worktree_id,
  531                path: RelPath::empty(),
  532            };
  533            let augments_syntax_tokens = AllLanguageSettings::get(Some(settings_location), cx)
  534                .language(Some(settings_location), Some(&language_name), cx)
  535                .semantic_tokens
  536                .use_tree_sitter();
  537            cx.spawn(async move |cx| {
  538                let result = async {
  539                    let language_server = pending_server.await?;
  540
  541                    let workspace_config = Self::workspace_configuration_for_adapter(
  542                        adapter.adapter.clone(),
  543                        &delegate,
  544                        toolchain,
  545                        None,
  546                        cx,
  547                    )
  548                    .await?;
  549
  550                    let mut initialization_options = Self::initialization_options_for_adapter(
  551                        adapter.adapter.clone(),
  552                        &delegate,
  553                        cx,
  554                    )
  555                    .await?;
  556
  557                    match (&mut initialization_options, override_options) {
  558                        (Some(initialization_options), Some(override_options)) => {
  559                            merge_json_value_into(override_options, initialization_options);
  560                        }
  561                        (None, override_options) => initialization_options = override_options,
  562                        _ => {}
  563                    }
  564
  565                    let initialization_params = cx.update(|cx| {
  566                        let mut params = language_server.default_initialize_params(
  567                            pull_diagnostics,
  568                            augments_syntax_tokens,
  569                            cx,
  570                        );
  571                        params.initialization_options = initialization_options;
  572                        adapter.adapter.prepare_initialize_params(params, cx)
  573                    })?;
  574
  575                    Self::setup_lsp_messages(
  576                        lsp_store.clone(),
  577                        &language_server,
  578                        delegate.clone(),
  579                        adapter.clone(),
  580                    );
  581
  582                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  583                        settings: workspace_config,
  584                    };
  585                    let language_server = cx
  586                        .update(|cx| {
  587                            let request_timeout = ProjectSettings::get_global(cx)
  588                                .global_lsp_settings
  589                                .get_request_timeout();
  590
  591                            language_server.initialize(
  592                                initialization_params,
  593                                Arc::new(did_change_configuration_params.clone()),
  594                                request_timeout,
  595                                cx,
  596                            )
  597                        })
  598                        .await
  599                        .inspect_err(|_| {
  600                            if let Some(lsp_store) = lsp_store.upgrade() {
  601                                lsp_store.update(cx, |lsp_store, cx| {
  602                                    lsp_store.cleanup_lsp_data(server_id);
  603                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  604                                });
  605                            }
  606                        })?;
  607
  608                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  609                        did_change_configuration_params,
  610                    )?;
  611
  612                    anyhow::Ok(language_server)
  613                }
  614                .await;
  615
  616                match result {
  617                    Ok(server) => {
  618                        lsp_store
  619                            .update(cx, |lsp_store, cx| {
  620                                lsp_store.insert_newly_running_language_server(
  621                                    adapter,
  622                                    server.clone(),
  623                                    server_id,
  624                                    key,
  625                                    pending_workspace_folders,
  626                                    cx,
  627                                );
  628                            })
  629                            .ok();
  630                        stderr_capture.lock().take();
  631                        Some(server)
  632                    }
  633
  634                    Err(err) => {
  635                        let log = stderr_capture.lock().take().unwrap_or_default();
  636                        delegate.update_status(
  637                            adapter.name(),
  638                            BinaryStatus::Failed {
  639                                error: if log.is_empty() {
  640                                    format!("{err:#}")
  641                                } else {
  642                                    format!("{err:#}\n-- stderr --\n{log}")
  643                                },
  644                            },
  645                        );
  646                        log::error!(
  647                            "Failed to start language server {server_name:?}: {}",
  648                            redact_command(&format!("{err:?}"))
  649                        );
  650                        if !log.is_empty() {
  651                            log::error!("server stderr: {}", redact_command(&log));
  652                        }
  653                        None
  654                    }
  655                }
  656            })
  657        };
  658        let state = LanguageServerState::Starting {
  659            startup,
  660            pending_workspace_folders,
  661        };
  662
  663        if update_binary_status {
  664            self.languages
  665                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  666        }
  667
  668        self.language_servers.insert(server_id, state);
  669        self.language_server_ids
  670            .entry(key)
  671            .or_insert(UnifiedLanguageServer {
  672                id: server_id,
  673                project_roots: Default::default(),
  674            });
  675        server_id
  676    }
  677
  678    fn get_language_server_binary(
  679        &self,
  680        worktree_abs_path: Arc<Path>,
  681        adapter: Arc<CachedLspAdapter>,
  682        settings: Arc<LspSettings>,
  683        toolchain: Option<Toolchain>,
  684        delegate: Arc<dyn LspAdapterDelegate>,
  685        allow_binary_download: bool,
  686        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  687        cx: &mut App,
  688    ) -> Task<Result<LanguageServerBinary>> {
  689        if let Some(settings) = &settings.binary
  690            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  691        {
  692            let settings = settings.clone();
  693            let languages = self.languages.clone();
  694            return cx.background_spawn(async move {
  695                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  696                    let already_trusted =  *wait_until_worktree_trust.borrow();
  697                    if !already_trusted {
  698                        log::info!(
  699                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  700                            adapter.name(),
  701                        );
  702                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  703                            if worktree_trusted {
  704                                break;
  705                            }
  706                        }
  707                        log::info!(
  708                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  709                            adapter.name(),
  710                        );
  711                    }
  712                    languages
  713                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  714                }
  715                let mut env = delegate.shell_env().await;
  716                env.extend(settings.env.unwrap_or_default());
  717
  718                Ok(LanguageServerBinary {
  719                    path: delegate.resolve_relative_path(path),
  720                    env: Some(env),
  721                    arguments: settings
  722                        .arguments
  723                        .unwrap_or_default()
  724                        .iter()
  725                        .map(Into::into)
  726                        .collect(),
  727                })
  728            });
  729        }
  730        let lsp_binary_options = LanguageServerBinaryOptions {
  731            allow_path_lookup: !settings
  732                .binary
  733                .as_ref()
  734                .and_then(|b| b.ignore_system_version)
  735                .unwrap_or_default(),
  736            allow_binary_download,
  737            pre_release: settings
  738                .fetch
  739                .as_ref()
  740                .and_then(|f| f.pre_release)
  741                .unwrap_or(false),
  742        };
  743
  744        cx.spawn(async move |cx| {
  745            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  746                let already_trusted =  *wait_until_worktree_trust.borrow();
  747                if !already_trusted {
  748                    log::info!(
  749                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  750                        adapter.name(),
  751                    );
  752                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  753                        if worktree_trusted {
  754                            break;
  755                        }
  756                    }
  757                    log::info!(
  758                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  759                            adapter.name(),
  760                    );
  761                }
  762            }
  763
  764            let (existing_binary, maybe_download_binary) = adapter
  765                .clone()
  766                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  767                .await
  768                .await;
  769
  770            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  771
  772            let mut binary = match (existing_binary, maybe_download_binary) {
  773                (binary, None) => binary?,
  774                (Err(_), Some(downloader)) => downloader.await?,
  775                (Ok(existing_binary), Some(downloader)) => {
  776                    let mut download_timeout = cx
  777                        .background_executor()
  778                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  779                        .fuse();
  780                    let mut downloader = downloader.fuse();
  781                    futures::select! {
  782                        _ = download_timeout => {
  783                            // Return existing binary and kick the existing work to the background.
  784                            cx.spawn(async move |_| downloader.await).detach();
  785                            Ok(existing_binary)
  786                        },
  787                        downloaded_or_existing_binary = downloader => {
  788                            // If download fails, this results in the existing binary.
  789                            downloaded_or_existing_binary
  790                        }
  791                    }?
  792                }
  793            };
  794            let mut shell_env = delegate.shell_env().await;
  795
  796            shell_env.extend(binary.env.unwrap_or_default());
  797
  798            if let Some(settings) = settings.binary.as_ref() {
  799                if let Some(arguments) = &settings.arguments {
  800                    binary.arguments = arguments.iter().map(Into::into).collect();
  801                }
  802                if let Some(env) = &settings.env {
  803                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  804                }
  805            }
  806
  807            binary.env = Some(shell_env);
  808            Ok(binary)
  809        })
  810    }
  811
  812    fn setup_lsp_messages(
  813        lsp_store: WeakEntity<LspStore>,
  814        language_server: &LanguageServer,
  815        delegate: Arc<dyn LspAdapterDelegate>,
  816        adapter: Arc<CachedLspAdapter>,
  817    ) {
  818        let name = language_server.name();
  819        let server_id = language_server.server_id();
  820        language_server
  821            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  822                let adapter = adapter.clone();
  823                let this = lsp_store.clone();
  824                move |mut params, cx| {
  825                    let adapter = adapter.clone();
  826                    if let Some(this) = this.upgrade() {
  827                        this.update(cx, |this, cx| {
  828                            adapter.process_diagnostics(&mut params, server_id);
  829
  830                            this.merge_lsp_diagnostics(
  831                                DiagnosticSourceKind::Pushed,
  832                                vec![DocumentDiagnosticsUpdate {
  833                                    server_id,
  834                                    diagnostics: params,
  835                                    result_id: None,
  836                                    disk_based_sources: Cow::Borrowed(
  837                                        &adapter.disk_based_diagnostic_sources,
  838                                    ),
  839                                    registration_id: None,
  840                                }],
  841                                |_, diagnostic, _cx| match diagnostic.source_kind {
  842                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  843                                        adapter.retain_old_diagnostic(diagnostic)
  844                                    }
  845                                    DiagnosticSourceKind::Pulled => true,
  846                                },
  847                                cx,
  848                            )
  849                            .log_err();
  850                        });
  851                    }
  852                }
  853            })
  854            .detach();
  855        language_server
  856            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  857                let adapter = adapter.adapter.clone();
  858                let delegate = delegate.clone();
  859                let this = lsp_store.clone();
  860                move |params, cx| {
  861                    let adapter = adapter.clone();
  862                    let delegate = delegate.clone();
  863                    let this = this.clone();
  864                    let mut cx = cx.clone();
  865                    async move {
  866                        let toolchain_for_id = this
  867                            .update(&mut cx, |this, _| {
  868                                this.as_local()?.language_server_ids.iter().find_map(
  869                                    |(seed, value)| {
  870                                        (value.id == server_id).then(|| seed.toolchain.clone())
  871                                    },
  872                                )
  873                            })?
  874                            .context("Expected the LSP store to be in a local mode")?;
  875
  876                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  877                        for item in &params.items {
  878                            let scope_uri = item.scope_uri.clone();
  879                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  880                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  881                            else {
  882                                // We've already queried workspace configuration of this URI.
  883                                continue;
  884                            };
  885                            let workspace_config = Self::workspace_configuration_for_adapter(
  886                                adapter.clone(),
  887                                &delegate,
  888                                toolchain_for_id.clone(),
  889                                scope_uri,
  890                                &mut cx,
  891                            )
  892                            .await?;
  893                            new_scope_uri.insert(workspace_config);
  894                        }
  895
  896                        Ok(params
  897                            .items
  898                            .into_iter()
  899                            .filter_map(|item| {
  900                                let workspace_config =
  901                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  902                                if let Some(section) = &item.section {
  903                                    Some(
  904                                        workspace_config
  905                                            .get(section)
  906                                            .cloned()
  907                                            .unwrap_or(serde_json::Value::Null),
  908                                    )
  909                                } else {
  910                                    Some(workspace_config.clone())
  911                                }
  912                            })
  913                            .collect())
  914                    }
  915                }
  916            })
  917            .detach();
  918
  919        language_server
  920            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  921                let this = lsp_store.clone();
  922                move |_, cx| {
  923                    let this = this.clone();
  924                    let cx = cx.clone();
  925                    async move {
  926                        let Some(server) =
  927                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  928                        else {
  929                            return Ok(None);
  930                        };
  931                        let root = server.workspace_folders();
  932                        Ok(Some(
  933                            root.into_iter()
  934                                .map(|uri| WorkspaceFolder {
  935                                    uri,
  936                                    name: Default::default(),
  937                                })
  938                                .collect(),
  939                        ))
  940                    }
  941                }
  942            })
  943            .detach();
  944        // Even though we don't have handling for these requests, respond to them to
  945        // avoid stalling any language server like `gopls` which waits for a response
  946        // to these requests when initializing.
  947        language_server
  948            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  949                let this = lsp_store.clone();
  950                move |params, cx| {
  951                    let this = this.clone();
  952                    let mut cx = cx.clone();
  953                    async move {
  954                        this.update(&mut cx, |this, _| {
  955                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  956                            {
  957                                status
  958                                    .progress_tokens
  959                                    .insert(ProgressToken::from_lsp(params.token));
  960                            }
  961                        })?;
  962
  963                        Ok(())
  964                    }
  965                }
  966            })
  967            .detach();
  968
  969        language_server
  970            .on_request::<lsp::request::RegisterCapability, _, _>({
  971                let lsp_store = lsp_store.clone();
  972                move |params, cx| {
  973                    let lsp_store = lsp_store.clone();
  974                    let mut cx = cx.clone();
  975                    async move {
  976                        lsp_store
  977                            .update(&mut cx, |lsp_store, cx| {
  978                                if lsp_store.as_local().is_some() {
  979                                    match lsp_store
  980                                        .register_server_capabilities(server_id, params, cx)
  981                                    {
  982                                        Ok(()) => {}
  983                                        Err(e) => {
  984                                            log::error!(
  985                                                "Failed to register server capabilities: {e:#}"
  986                                            );
  987                                        }
  988                                    };
  989                                }
  990                            })
  991                            .ok();
  992                        Ok(())
  993                    }
  994                }
  995            })
  996            .detach();
  997
  998        language_server
  999            .on_request::<lsp::request::UnregisterCapability, _, _>({
 1000                let lsp_store = lsp_store.clone();
 1001                move |params, cx| {
 1002                    let lsp_store = lsp_store.clone();
 1003                    let mut cx = cx.clone();
 1004                    async move {
 1005                        lsp_store
 1006                            .update(&mut cx, |lsp_store, cx| {
 1007                                if lsp_store.as_local().is_some() {
 1008                                    match lsp_store
 1009                                        .unregister_server_capabilities(server_id, params, cx)
 1010                                    {
 1011                                        Ok(()) => {}
 1012                                        Err(e) => {
 1013                                            log::error!(
 1014                                                "Failed to unregister server capabilities: {e:#}"
 1015                                            );
 1016                                        }
 1017                                    }
 1018                                }
 1019                            })
 1020                            .ok();
 1021                        Ok(())
 1022                    }
 1023                }
 1024            })
 1025            .detach();
 1026
 1027        language_server
 1028            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
 1029                let this = lsp_store.clone();
 1030                move |params, cx| {
 1031                    let mut cx = cx.clone();
 1032                    let this = this.clone();
 1033                    async move {
 1034                        LocalLspStore::on_lsp_workspace_edit(
 1035                            this.clone(),
 1036                            params,
 1037                            server_id,
 1038                            &mut cx,
 1039                        )
 1040                        .await
 1041                    }
 1042                }
 1043            })
 1044            .detach();
 1045
 1046        language_server
 1047            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1048                let lsp_store = lsp_store.clone();
 1049                let request_id = Arc::new(AtomicUsize::new(0));
 1050                move |(), cx| {
 1051                    let lsp_store = lsp_store.clone();
 1052                    let request_id = request_id.clone();
 1053                    let mut cx = cx.clone();
 1054                    async move {
 1055                        lsp_store
 1056                            .update(&mut cx, |lsp_store, cx| {
 1057                                let request_id =
 1058                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1059                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1060                                    server_id,
 1061                                    request_id,
 1062                                });
 1063                                lsp_store
 1064                                    .downstream_client
 1065                                    .as_ref()
 1066                                    .map(|(client, project_id)| {
 1067                                        client.send(proto::RefreshInlayHints {
 1068                                            project_id: *project_id,
 1069                                            server_id: server_id.to_proto(),
 1070                                            request_id: request_id.map(|id| id as u64),
 1071                                        })
 1072                                    })
 1073                            })?
 1074                            .transpose()?;
 1075                        Ok(())
 1076                    }
 1077                }
 1078            })
 1079            .detach();
 1080
 1081        language_server
 1082            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1083                let this = lsp_store.clone();
 1084                move |(), cx| {
 1085                    let this = this.clone();
 1086                    let mut cx = cx.clone();
 1087                    async move {
 1088                        this.update(&mut cx, |this, cx| {
 1089                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1090                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1091                                client.send(proto::RefreshCodeLens {
 1092                                    project_id: *project_id,
 1093                                })
 1094                            })
 1095                        })?
 1096                        .transpose()?;
 1097                        Ok(())
 1098                    }
 1099                }
 1100            })
 1101            .detach();
 1102
 1103        language_server
 1104            .on_request::<lsp::request::SemanticTokensRefresh, _, _>({
 1105                let lsp_store = lsp_store.clone();
 1106                let request_id = Arc::new(AtomicUsize::new(0));
 1107                move |(), cx| {
 1108                    let lsp_store = lsp_store.clone();
 1109                    let request_id = request_id.clone();
 1110                    let mut cx = cx.clone();
 1111                    async move {
 1112                        lsp_store
 1113                            .update(&mut cx, |lsp_store, cx| {
 1114                                let request_id =
 1115                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1116                                cx.emit(LspStoreEvent::RefreshSemanticTokens {
 1117                                    server_id,
 1118                                    request_id,
 1119                                });
 1120                                lsp_store
 1121                                    .downstream_client
 1122                                    .as_ref()
 1123                                    .map(|(client, project_id)| {
 1124                                        client.send(proto::RefreshSemanticTokens {
 1125                                            project_id: *project_id,
 1126                                            server_id: server_id.to_proto(),
 1127                                            request_id: request_id.map(|id| id as u64),
 1128                                        })
 1129                                    })
 1130                            })?
 1131                            .transpose()?;
 1132                        Ok(())
 1133                    }
 1134                }
 1135            })
 1136            .detach();
 1137
 1138        language_server
 1139            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1140                let this = lsp_store.clone();
 1141                move |(), cx| {
 1142                    let this = this.clone();
 1143                    let mut cx = cx.clone();
 1144                    async move {
 1145                        this.update(&mut cx, |lsp_store, cx| {
 1146                            lsp_store.pull_workspace_diagnostics(server_id);
 1147                            lsp_store
 1148                                .downstream_client
 1149                                .as_ref()
 1150                                .map(|(client, project_id)| {
 1151                                    client.send(proto::PullWorkspaceDiagnostics {
 1152                                        project_id: *project_id,
 1153                                        server_id: server_id.to_proto(),
 1154                                    })
 1155                                })
 1156                                .transpose()?;
 1157                            anyhow::Ok(
 1158                                lsp_store.pull_document_diagnostics_for_server(server_id, None, cx),
 1159                            )
 1160                        })??
 1161                        .await;
 1162                        Ok(())
 1163                    }
 1164                }
 1165            })
 1166            .detach();
 1167
 1168        language_server
 1169            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1170                let this = lsp_store.clone();
 1171                let name = name.to_string();
 1172                let adapter = adapter.clone();
 1173                move |params, cx| {
 1174                    let this = this.clone();
 1175                    let name = name.to_string();
 1176                    let adapter = adapter.clone();
 1177                    let mut cx = cx.clone();
 1178                    async move {
 1179                        let actions = params.actions.unwrap_or_default();
 1180                        let message = params.message.clone();
 1181                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1182                        let level = match params.typ {
 1183                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1184                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1185                            _ => PromptLevel::Info,
 1186                        };
 1187                        let request = LanguageServerPromptRequest::new(
 1188                            level,
 1189                            params.message,
 1190                            actions,
 1191                            name.clone(),
 1192                            tx,
 1193                        );
 1194
 1195                        let did_update = this
 1196                            .update(&mut cx, |_, cx| {
 1197                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1198                            })
 1199                            .is_ok();
 1200                        if did_update {
 1201                            let response = rx.recv().await.ok();
 1202                            if let Some(ref selected_action) = response {
 1203                                let context = language::PromptResponseContext {
 1204                                    message,
 1205                                    selected_action: selected_action.clone(),
 1206                                };
 1207                                adapter.process_prompt_response(&context, &mut cx)
 1208                            }
 1209
 1210                            Ok(response)
 1211                        } else {
 1212                            Ok(None)
 1213                        }
 1214                    }
 1215                }
 1216            })
 1217            .detach();
 1218        language_server
 1219            .on_notification::<lsp::notification::ShowMessage, _>({
 1220                let this = lsp_store.clone();
 1221                let name = name.to_string();
 1222                move |params, cx| {
 1223                    let this = this.clone();
 1224                    let name = name.to_string();
 1225                    let mut cx = cx.clone();
 1226
 1227                    let (tx, _) = smol::channel::bounded(1);
 1228                    let level = match params.typ {
 1229                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1230                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1231                        _ => PromptLevel::Info,
 1232                    };
 1233                    let request =
 1234                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1235
 1236                    let _ = this.update(&mut cx, |_, cx| {
 1237                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1238                    });
 1239                }
 1240            })
 1241            .detach();
 1242
 1243        let disk_based_diagnostics_progress_token =
 1244            adapter.disk_based_diagnostics_progress_token.clone();
 1245
 1246        language_server
 1247            .on_notification::<lsp::notification::Progress, _>({
 1248                let this = lsp_store.clone();
 1249                move |params, cx| {
 1250                    if let Some(this) = this.upgrade() {
 1251                        this.update(cx, |this, cx| {
 1252                            this.on_lsp_progress(
 1253                                params,
 1254                                server_id,
 1255                                disk_based_diagnostics_progress_token.clone(),
 1256                                cx,
 1257                            );
 1258                        });
 1259                    }
 1260                }
 1261            })
 1262            .detach();
 1263
 1264        language_server
 1265            .on_notification::<lsp::notification::LogMessage, _>({
 1266                let this = lsp_store.clone();
 1267                move |params, cx| {
 1268                    if let Some(this) = this.upgrade() {
 1269                        this.update(cx, |_, cx| {
 1270                            cx.emit(LspStoreEvent::LanguageServerLog(
 1271                                server_id,
 1272                                LanguageServerLogType::Log(params.typ),
 1273                                params.message,
 1274                            ));
 1275                        });
 1276                    }
 1277                }
 1278            })
 1279            .detach();
 1280
 1281        language_server
 1282            .on_notification::<lsp::notification::LogTrace, _>({
 1283                let this = lsp_store.clone();
 1284                move |params, cx| {
 1285                    let mut cx = cx.clone();
 1286                    if let Some(this) = this.upgrade() {
 1287                        this.update(&mut cx, |_, cx| {
 1288                            cx.emit(LspStoreEvent::LanguageServerLog(
 1289                                server_id,
 1290                                LanguageServerLogType::Trace {
 1291                                    verbose_info: params.verbose,
 1292                                },
 1293                                params.message,
 1294                            ));
 1295                        });
 1296                    }
 1297                }
 1298            })
 1299            .detach();
 1300
 1301        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1302        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1303        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1304        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1305    }
 1306
 1307    fn shutdown_language_servers_on_quit(&mut self) -> impl Future<Output = ()> + use<> {
 1308        let shutdown_futures = self
 1309            .language_servers
 1310            .drain()
 1311            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1312            .collect::<Vec<_>>();
 1313
 1314        async move {
 1315            join_all(shutdown_futures).await;
 1316        }
 1317    }
 1318
 1319    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1320        match server_state {
 1321            LanguageServerState::Running { server, .. } => {
 1322                if let Some(shutdown) = server.shutdown() {
 1323                    shutdown.await;
 1324                }
 1325            }
 1326            LanguageServerState::Starting { startup, .. } => {
 1327                if let Some(server) = startup.await
 1328                    && let Some(shutdown) = server.shutdown()
 1329                {
 1330                    shutdown.await;
 1331                }
 1332            }
 1333        }
 1334        Ok(())
 1335    }
 1336
 1337    fn language_servers_for_worktree(
 1338        &self,
 1339        worktree_id: WorktreeId,
 1340    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1341        self.language_server_ids
 1342            .iter()
 1343            .filter_map(move |(seed, state)| {
 1344                if seed.worktree_id != worktree_id {
 1345                    return None;
 1346                }
 1347
 1348                if let Some(LanguageServerState::Running { server, .. }) =
 1349                    self.language_servers.get(&state.id)
 1350                {
 1351                    Some(server)
 1352                } else {
 1353                    None
 1354                }
 1355            })
 1356    }
 1357
 1358    fn language_server_ids_for_project_path(
 1359        &self,
 1360        project_path: ProjectPath,
 1361        language: &Language,
 1362        cx: &mut App,
 1363    ) -> Vec<LanguageServerId> {
 1364        let Some(worktree) = self
 1365            .worktree_store
 1366            .read(cx)
 1367            .worktree_for_id(project_path.worktree_id, cx)
 1368        else {
 1369            return Vec::new();
 1370        };
 1371        let delegate: Arc<dyn ManifestDelegate> =
 1372            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1373
 1374        self.lsp_tree
 1375            .get(
 1376                project_path,
 1377                language.name(),
 1378                language.manifest(),
 1379                &delegate,
 1380                cx,
 1381            )
 1382            .collect::<Vec<_>>()
 1383    }
 1384
 1385    fn language_server_ids_for_buffer(
 1386        &self,
 1387        buffer: &Buffer,
 1388        cx: &mut App,
 1389    ) -> Vec<LanguageServerId> {
 1390        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1391            let worktree_id = file.worktree_id(cx);
 1392
 1393            let path: Arc<RelPath> = file
 1394                .path()
 1395                .parent()
 1396                .map(Arc::from)
 1397                .unwrap_or_else(|| file.path().clone());
 1398            let worktree_path = ProjectPath { worktree_id, path };
 1399            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1400        } else {
 1401            Vec::new()
 1402        }
 1403    }
 1404
 1405    fn language_servers_for_buffer<'a>(
 1406        &'a self,
 1407        buffer: &'a Buffer,
 1408        cx: &'a mut App,
 1409    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1410        self.language_server_ids_for_buffer(buffer, cx)
 1411            .into_iter()
 1412            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1413                LanguageServerState::Running {
 1414                    adapter, server, ..
 1415                } => Some((adapter, server)),
 1416                _ => None,
 1417            })
 1418    }
 1419
 1420    async fn execute_code_action_kind_locally(
 1421        lsp_store: WeakEntity<LspStore>,
 1422        mut buffers: Vec<Entity<Buffer>>,
 1423        kind: CodeActionKind,
 1424        push_to_history: bool,
 1425        cx: &mut AsyncApp,
 1426    ) -> anyhow::Result<ProjectTransaction> {
 1427        // Do not allow multiple concurrent code actions requests for the
 1428        // same buffer.
 1429        lsp_store.update(cx, |this, cx| {
 1430            let this = this.as_local_mut().unwrap();
 1431            buffers.retain(|buffer| {
 1432                this.buffers_being_formatted
 1433                    .insert(buffer.read(cx).remote_id())
 1434            });
 1435        })?;
 1436        let _cleanup = defer({
 1437            let this = lsp_store.clone();
 1438            let mut cx = cx.clone();
 1439            let buffers = &buffers;
 1440            move || {
 1441                this.update(&mut cx, |this, cx| {
 1442                    let this = this.as_local_mut().unwrap();
 1443                    for buffer in buffers {
 1444                        this.buffers_being_formatted
 1445                            .remove(&buffer.read(cx).remote_id());
 1446                    }
 1447                })
 1448                .ok();
 1449            }
 1450        });
 1451        let mut project_transaction = ProjectTransaction::default();
 1452
 1453        for buffer in &buffers {
 1454            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1455                buffer.update(cx, |buffer, cx| {
 1456                    lsp_store
 1457                        .as_local()
 1458                        .unwrap()
 1459                        .language_servers_for_buffer(buffer, cx)
 1460                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1461                        .collect::<Vec<_>>()
 1462                })
 1463            })?;
 1464            for (_, language_server) in adapters_and_servers.iter() {
 1465                let actions = Self::get_server_code_actions_from_action_kinds(
 1466                    &lsp_store,
 1467                    language_server.server_id(),
 1468                    vec![kind.clone()],
 1469                    buffer,
 1470                    cx,
 1471                )
 1472                .await?;
 1473                Self::execute_code_actions_on_server(
 1474                    &lsp_store,
 1475                    language_server,
 1476                    actions,
 1477                    push_to_history,
 1478                    &mut project_transaction,
 1479                    cx,
 1480                )
 1481                .await?;
 1482            }
 1483        }
 1484        Ok(project_transaction)
 1485    }
 1486
 1487    async fn format_locally(
 1488        lsp_store: WeakEntity<LspStore>,
 1489        mut buffers: Vec<FormattableBuffer>,
 1490        push_to_history: bool,
 1491        trigger: FormatTrigger,
 1492        logger: zlog::Logger,
 1493        cx: &mut AsyncApp,
 1494    ) -> anyhow::Result<ProjectTransaction> {
 1495        // Do not allow multiple concurrent formatting requests for the
 1496        // same buffer.
 1497        lsp_store.update(cx, |this, cx| {
 1498            let this = this.as_local_mut().unwrap();
 1499            buffers.retain(|buffer| {
 1500                this.buffers_being_formatted
 1501                    .insert(buffer.handle.read(cx).remote_id())
 1502            });
 1503        })?;
 1504
 1505        let _cleanup = defer({
 1506            let this = lsp_store.clone();
 1507            let mut cx = cx.clone();
 1508            let buffers = &buffers;
 1509            move || {
 1510                this.update(&mut cx, |this, cx| {
 1511                    let this = this.as_local_mut().unwrap();
 1512                    for buffer in buffers {
 1513                        this.buffers_being_formatted
 1514                            .remove(&buffer.handle.read(cx).remote_id());
 1515                    }
 1516                })
 1517                .ok();
 1518            }
 1519        });
 1520
 1521        let mut project_transaction = ProjectTransaction::default();
 1522
 1523        for buffer in &buffers {
 1524            zlog::debug!(
 1525                logger =>
 1526                "formatting buffer '{:?}'",
 1527                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1528            );
 1529            // Create an empty transaction to hold all of the formatting edits.
 1530            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1531                // ensure no transactions created while formatting are
 1532                // grouped with the previous transaction in the history
 1533                // based on the transaction group interval
 1534                buffer.finalize_last_transaction();
 1535                buffer
 1536                    .start_transaction()
 1537                    .context("transaction already open")?;
 1538                buffer.end_transaction(cx);
 1539                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1540                buffer.finalize_last_transaction();
 1541                anyhow::Ok(transaction_id)
 1542            })?;
 1543
 1544            let result = Self::format_buffer_locally(
 1545                lsp_store.clone(),
 1546                buffer,
 1547                formatting_transaction_id,
 1548                trigger,
 1549                logger,
 1550                cx,
 1551            )
 1552            .await;
 1553
 1554            buffer.handle.update(cx, |buffer, cx| {
 1555                let Some(formatting_transaction) =
 1556                    buffer.get_transaction(formatting_transaction_id).cloned()
 1557                else {
 1558                    zlog::warn!(logger => "no formatting transaction");
 1559                    return;
 1560                };
 1561                if formatting_transaction.edit_ids.is_empty() {
 1562                    zlog::debug!(logger => "no changes made while formatting");
 1563                    buffer.forget_transaction(formatting_transaction_id);
 1564                    return;
 1565                }
 1566                if !push_to_history {
 1567                    zlog::trace!(logger => "forgetting format transaction");
 1568                    buffer.forget_transaction(formatting_transaction.id);
 1569                }
 1570                project_transaction
 1571                    .0
 1572                    .insert(cx.entity(), formatting_transaction);
 1573            });
 1574
 1575            result?;
 1576        }
 1577
 1578        Ok(project_transaction)
 1579    }
 1580
 1581    async fn format_buffer_locally(
 1582        lsp_store: WeakEntity<LspStore>,
 1583        buffer: &FormattableBuffer,
 1584        formatting_transaction_id: clock::Lamport,
 1585        trigger: FormatTrigger,
 1586        logger: zlog::Logger,
 1587        cx: &mut AsyncApp,
 1588    ) -> Result<()> {
 1589        let (adapters_and_servers, settings, request_timeout) =
 1590            lsp_store.update(cx, |lsp_store, cx| {
 1591                buffer.handle.update(cx, |buffer, cx| {
 1592                    let adapters_and_servers = lsp_store
 1593                        .as_local()
 1594                        .unwrap()
 1595                        .language_servers_for_buffer(buffer, cx)
 1596                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1597                        .collect::<Vec<_>>();
 1598                    let settings = LanguageSettings::for_buffer(buffer, cx).into_owned();
 1599                    let request_timeout = ProjectSettings::get_global(cx)
 1600                        .global_lsp_settings
 1601                        .get_request_timeout();
 1602                    (adapters_and_servers, settings, request_timeout)
 1603                })
 1604            })?;
 1605
 1606        // handle whitespace formatting
 1607        if settings.remove_trailing_whitespace_on_save {
 1608            zlog::trace!(logger => "removing trailing whitespace");
 1609            let diff = buffer
 1610                .handle
 1611                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1612                .await;
 1613            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1614                buffer.apply_diff(diff, cx);
 1615            })?;
 1616        }
 1617
 1618        if settings.ensure_final_newline_on_save {
 1619            zlog::trace!(logger => "ensuring final newline");
 1620            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1621                buffer.ensure_final_newline(cx);
 1622            })?;
 1623        }
 1624
 1625        // Formatter for `code_actions_on_format` that runs before
 1626        // the rest of the formatters
 1627        let mut code_actions_on_format_formatters = None;
 1628        let should_run_code_actions_on_format = !matches!(
 1629            (trigger, &settings.format_on_save),
 1630            (FormatTrigger::Save, &FormatOnSave::Off)
 1631        );
 1632        if should_run_code_actions_on_format {
 1633            let have_code_actions_to_run_on_format = settings
 1634                .code_actions_on_format
 1635                .values()
 1636                .any(|enabled| *enabled);
 1637            if have_code_actions_to_run_on_format {
 1638                zlog::trace!(logger => "going to run code actions on format");
 1639                code_actions_on_format_formatters = Some(
 1640                    settings
 1641                        .code_actions_on_format
 1642                        .iter()
 1643                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1644                        .cloned()
 1645                        .map(Formatter::CodeAction)
 1646                        .collect::<Vec<_>>(),
 1647                );
 1648            }
 1649        }
 1650
 1651        let formatters = match (trigger, &settings.format_on_save) {
 1652            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1653            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1654                settings.formatter.as_ref()
 1655            }
 1656        };
 1657
 1658        let formatters = code_actions_on_format_formatters
 1659            .iter()
 1660            .flatten()
 1661            .chain(formatters);
 1662
 1663        for formatter in formatters {
 1664            let formatter = if formatter == &Formatter::Auto {
 1665                if settings.prettier.allowed {
 1666                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1667                    &Formatter::Prettier
 1668                } else {
 1669                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1670                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1671                }
 1672            } else {
 1673                formatter
 1674            };
 1675            if let Err(err) = Self::apply_formatter(
 1676                formatter,
 1677                &lsp_store,
 1678                buffer,
 1679                formatting_transaction_id,
 1680                &adapters_and_servers,
 1681                &settings,
 1682                request_timeout,
 1683                logger,
 1684                cx,
 1685            )
 1686            .await
 1687            {
 1688                zlog::error!(logger => "Formatter failed, skipping: {err:#}");
 1689            }
 1690        }
 1691
 1692        Ok(())
 1693    }
 1694
 1695    async fn apply_formatter(
 1696        formatter: &Formatter,
 1697        lsp_store: &WeakEntity<LspStore>,
 1698        buffer: &FormattableBuffer,
 1699        formatting_transaction_id: clock::Lamport,
 1700        adapters_and_servers: &[(Arc<CachedLspAdapter>, Arc<LanguageServer>)],
 1701        settings: &LanguageSettings,
 1702        request_timeout: Duration,
 1703        logger: zlog::Logger,
 1704        cx: &mut AsyncApp,
 1705    ) -> anyhow::Result<()> {
 1706        match formatter {
 1707            Formatter::None => {
 1708                zlog::trace!(logger => "skipping formatter 'none'");
 1709                return Ok(());
 1710            }
 1711            Formatter::Auto => {
 1712                debug_panic!("Auto resolved above");
 1713                return Ok(());
 1714            }
 1715            Formatter::Prettier => {
 1716                let logger = zlog::scoped!(logger => "prettier");
 1717                zlog::trace!(logger => "formatting");
 1718                let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1719
 1720                // When selection ranges are provided (via FormatSelections), we pass the
 1721                // encompassing UTF-16 range to Prettier so it can scope its formatting.
 1722                // After diffing, we filter the resulting edits to only keep those that
 1723                // overlap with the original byte-level selection ranges.
 1724                let (range_utf16, byte_ranges) = match buffer.ranges.as_ref() {
 1725                    Some(ranges) if !ranges.is_empty() => {
 1726                        let (utf16_range, byte_ranges) =
 1727                            buffer.handle.read_with(cx, |buffer, _cx| {
 1728                                let snapshot = buffer.snapshot();
 1729                                let mut min_start_utf16 = OffsetUtf16(usize::MAX);
 1730                                let mut max_end_utf16 = OffsetUtf16(0);
 1731                                let mut byte_ranges = Vec::with_capacity(ranges.len());
 1732                                for range in ranges {
 1733                                    let start_utf16 = range.start.to_offset_utf16(&snapshot);
 1734                                    let end_utf16 = range.end.to_offset_utf16(&snapshot);
 1735                                    min_start_utf16.0 = min_start_utf16.0.min(start_utf16.0);
 1736                                    max_end_utf16.0 = max_end_utf16.0.max(end_utf16.0);
 1737
 1738                                    let start_byte = range.start.to_offset(&snapshot);
 1739                                    let end_byte = range.end.to_offset(&snapshot);
 1740                                    byte_ranges.push(start_byte..end_byte);
 1741                                }
 1742                                (min_start_utf16..max_end_utf16, byte_ranges)
 1743                            });
 1744                        (Some(utf16_range), Some(byte_ranges))
 1745                    }
 1746                    _ => (None, None),
 1747                };
 1748
 1749                let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1750                    lsp_store.prettier_store().unwrap().downgrade()
 1751                })?;
 1752                let diff = prettier_store::format_with_prettier(
 1753                    &prettier,
 1754                    &buffer.handle,
 1755                    range_utf16,
 1756                    cx,
 1757                )
 1758                .await
 1759                .transpose()?;
 1760                let Some(mut diff) = diff else {
 1761                    zlog::trace!(logger => "No changes");
 1762                    return Ok(());
 1763                };
 1764
 1765                if let Some(byte_ranges) = byte_ranges {
 1766                    diff.edits.retain(|(edit_range, _)| {
 1767                        byte_ranges.iter().any(|selection_range| {
 1768                            edit_range.start < selection_range.end
 1769                                && edit_range.end > selection_range.start
 1770                        })
 1771                    });
 1772                    if diff.edits.is_empty() {
 1773                        zlog::trace!(logger => "No changes within selection");
 1774                        return Ok(());
 1775                    }
 1776                }
 1777
 1778                extend_formatting_transaction(
 1779                    buffer,
 1780                    formatting_transaction_id,
 1781                    cx,
 1782                    |buffer, cx| {
 1783                        buffer.apply_diff(diff, cx);
 1784                    },
 1785                )?;
 1786            }
 1787            Formatter::External { command, arguments } => {
 1788                let logger = zlog::scoped!(logger => "command");
 1789
 1790                if buffer.ranges.is_some() {
 1791                    zlog::debug!(logger => "External formatter does not support range formatting; skipping");
 1792                    return Ok(());
 1793                }
 1794
 1795                zlog::trace!(logger => "formatting");
 1796                let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1797
 1798                let diff =
 1799                    Self::format_via_external_command(buffer, &command, arguments.as_deref(), cx)
 1800                        .await
 1801                        .with_context(|| {
 1802                            format!("Failed to format buffer via external command: {}", command)
 1803                        })?;
 1804                let Some(diff) = diff else {
 1805                    zlog::trace!(logger => "No changes");
 1806                    return Ok(());
 1807                };
 1808
 1809                extend_formatting_transaction(
 1810                    buffer,
 1811                    formatting_transaction_id,
 1812                    cx,
 1813                    |buffer, cx| {
 1814                        buffer.apply_diff(diff, cx);
 1815                    },
 1816                )?;
 1817            }
 1818            Formatter::LanguageServer(specifier) => {
 1819                let logger = zlog::scoped!(logger => "language-server");
 1820                zlog::trace!(logger => "formatting");
 1821                let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1822
 1823                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1824                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1825                    return Ok(());
 1826                };
 1827
 1828                let language_server = match specifier {
 1829                    settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1830                        adapters_and_servers.iter().find_map(|(adapter, server)| {
 1831                            if adapter.name.0.as_ref() == name {
 1832                                Some(server.clone())
 1833                            } else {
 1834                                None
 1835                            }
 1836                        })
 1837                    }
 1838                    settings::LanguageServerFormatterSpecifier::Current => adapters_and_servers
 1839                        .iter()
 1840                        .find(|(_, server)| Self::server_supports_formatting(server))
 1841                        .map(|(_, server)| server.clone()),
 1842                };
 1843
 1844                let Some(language_server) = language_server else {
 1845                    log::debug!(
 1846                        "No language server found to format buffer '{:?}'. Skipping",
 1847                        buffer_path_abs.as_path().to_string_lossy()
 1848                    );
 1849                    return Ok(());
 1850                };
 1851
 1852                zlog::trace!(
 1853                    logger =>
 1854                    "Formatting buffer '{:?}' using language server '{:?}'",
 1855                    buffer_path_abs.as_path().to_string_lossy(),
 1856                    language_server.name()
 1857                );
 1858
 1859                let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1860                    zlog::trace!(logger => "formatting ranges");
 1861                    Self::format_ranges_via_lsp(
 1862                        &lsp_store,
 1863                        &buffer.handle,
 1864                        ranges,
 1865                        buffer_path_abs,
 1866                        &language_server,
 1867                        &settings,
 1868                        cx,
 1869                    )
 1870                    .await
 1871                    .context("Failed to format ranges via language server")?
 1872                } else {
 1873                    zlog::trace!(logger => "formatting full");
 1874                    Self::format_via_lsp(
 1875                        &lsp_store,
 1876                        &buffer.handle,
 1877                        buffer_path_abs,
 1878                        &language_server,
 1879                        &settings,
 1880                        cx,
 1881                    )
 1882                    .await
 1883                    .context("failed to format via language server")?
 1884                };
 1885
 1886                if edits.is_empty() {
 1887                    zlog::trace!(logger => "No changes");
 1888                    return Ok(());
 1889                }
 1890                extend_formatting_transaction(
 1891                    buffer,
 1892                    formatting_transaction_id,
 1893                    cx,
 1894                    |buffer, cx| {
 1895                        buffer.edit(edits, None, cx);
 1896                    },
 1897                )?;
 1898            }
 1899            Formatter::CodeAction(code_action_name) => {
 1900                let logger = zlog::scoped!(logger => "code-actions");
 1901                zlog::trace!(logger => "formatting");
 1902                let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1903
 1904                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1905                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1906                    return Ok(());
 1907                };
 1908
 1909                let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1910                zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1911
 1912                let mut actions_and_servers = Vec::new();
 1913
 1914                for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1915                    let actions_result = Self::get_server_code_actions_from_action_kinds(
 1916                        &lsp_store,
 1917                        language_server.server_id(),
 1918                        vec![code_action_kind.clone()],
 1919                        &buffer.handle,
 1920                        cx,
 1921                    )
 1922                    .await
 1923                    .with_context(|| {
 1924                        format!(
 1925                            "Failed to resolve code action {:?} with language server {}",
 1926                            code_action_kind,
 1927                            language_server.name()
 1928                        )
 1929                    });
 1930                    let Ok(actions) = actions_result else {
 1931                        // note: it may be better to set result to the error and break formatters here
 1932                        // but for now we try to execute the actions that we can resolve and skip the rest
 1933                        zlog::error!(
 1934                            logger =>
 1935                            "Failed to resolve code action {:?} with language server {}",
 1936                            code_action_kind,
 1937                            language_server.name()
 1938                        );
 1939                        continue;
 1940                    };
 1941                    for action in actions {
 1942                        actions_and_servers.push((action, index));
 1943                    }
 1944                }
 1945
 1946                if actions_and_servers.is_empty() {
 1947                    zlog::warn!(logger => "No code actions were resolved, continuing");
 1948                    return Ok(());
 1949                }
 1950
 1951                'actions: for (mut action, server_index) in actions_and_servers {
 1952                    let server = &adapters_and_servers[server_index].1;
 1953
 1954                    let describe_code_action = |action: &CodeAction| {
 1955                        format!(
 1956                            "code action '{}' with title \"{}\" on server {}",
 1957                            action
 1958                                .lsp_action
 1959                                .action_kind()
 1960                                .unwrap_or("unknown".into())
 1961                                .as_str(),
 1962                            action.lsp_action.title(),
 1963                            server.name(),
 1964                        )
 1965                    };
 1966
 1967                    zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1968
 1969                    if let Err(err) =
 1970                        Self::try_resolve_code_action(server, &mut action, request_timeout).await
 1971                    {
 1972                        zlog::error!(
 1973                            logger =>
 1974                            "Failed to resolve {}. Error: {}",
 1975                            describe_code_action(&action),
 1976                            err
 1977                        );
 1978                        continue;
 1979                    }
 1980
 1981                    if let Some(edit) = action.lsp_action.edit().cloned() {
 1982                        // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1983                        // but filters out and logs warnings for code actions that require unreasonably
 1984                        // difficult handling on our part, such as:
 1985                        // - applying edits that call commands
 1986                        //   which can result in arbitrary workspace edits being sent from the server that
 1987                        //   have no way of being tied back to the command that initiated them (i.e. we
 1988                        //   can't know which edits are part of the format request, or if the server is done sending
 1989                        //   actions in response to the command)
 1990                        // - actions that create/delete/modify/rename files other than the one we are formatting
 1991                        //   as we then would need to handle such changes correctly in the local history as well
 1992                        //   as the remote history through the ProjectTransaction
 1993                        // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1994                        // Supporting these actions is not impossible, but not supported as of yet.
 1995                        if edit.changes.is_none() && edit.document_changes.is_none() {
 1996                            zlog::trace!(
 1997                                logger =>
 1998                                "No changes for code action. Skipping {}",
 1999                                describe_code_action(&action),
 2000                            );
 2001                            continue;
 2002                        }
 2003
 2004                        let mut operations = Vec::new();
 2005                        if let Some(document_changes) = edit.document_changes {
 2006                            match document_changes {
 2007                                lsp::DocumentChanges::Edits(edits) => operations.extend(
 2008                                    edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 2009                                ),
 2010                                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2011                            }
 2012                        } else if let Some(changes) = edit.changes {
 2013                            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2014                                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2015                                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2016                                        uri,
 2017                                        version: None,
 2018                                    },
 2019                                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2020                                })
 2021                            }));
 2022                        }
 2023
 2024                        let mut edits = Vec::with_capacity(operations.len());
 2025
 2026                        if operations.is_empty() {
 2027                            zlog::trace!(
 2028                                logger =>
 2029                                "No changes for code action. Skipping {}",
 2030                                describe_code_action(&action),
 2031                            );
 2032                            continue;
 2033                        }
 2034                        for operation in operations {
 2035                            let op = match operation {
 2036                                lsp::DocumentChangeOperation::Edit(op) => op,
 2037                                lsp::DocumentChangeOperation::Op(_) => {
 2038                                    zlog::warn!(
 2039                                        logger =>
 2040                                        "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 2041                                        describe_code_action(&action),
 2042                                    );
 2043                                    continue 'actions;
 2044                                }
 2045                            };
 2046                            let Ok(file_path) = op.text_document.uri.to_file_path() else {
 2047                                zlog::warn!(
 2048                                    logger =>
 2049                                    "Failed to convert URI '{:?}' to file path. Skipping {}",
 2050                                    &op.text_document.uri,
 2051                                    describe_code_action(&action),
 2052                                );
 2053                                continue 'actions;
 2054                            };
 2055                            if &file_path != buffer_path_abs {
 2056                                zlog::warn!(
 2057                                    logger =>
 2058                                    "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 2059                                    file_path,
 2060                                    buffer_path_abs,
 2061                                    describe_code_action(&action),
 2062                                );
 2063                                continue 'actions;
 2064                            }
 2065
 2066                            let mut lsp_edits = Vec::new();
 2067                            for edit in op.edits {
 2068                                match edit {
 2069                                    Edit::Plain(edit) => {
 2070                                        if !lsp_edits.contains(&edit) {
 2071                                            lsp_edits.push(edit);
 2072                                        }
 2073                                    }
 2074                                    Edit::Annotated(edit) => {
 2075                                        if !lsp_edits.contains(&edit.text_edit) {
 2076                                            lsp_edits.push(edit.text_edit);
 2077                                        }
 2078                                    }
 2079                                    Edit::Snippet(_) => {
 2080                                        zlog::warn!(
 2081                                            logger =>
 2082                                            "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 2083                                            describe_code_action(&action),
 2084                                        );
 2085                                        continue 'actions;
 2086                                    }
 2087                                }
 2088                            }
 2089                            let edits_result = lsp_store
 2090                                .update(cx, |lsp_store, cx| {
 2091                                    lsp_store.as_local_mut().unwrap().edits_from_lsp(
 2092                                        &buffer.handle,
 2093                                        lsp_edits,
 2094                                        server.server_id(),
 2095                                        op.text_document.version,
 2096                                        cx,
 2097                                    )
 2098                                })?
 2099                                .await;
 2100                            let Ok(resolved_edits) = edits_result else {
 2101                                zlog::warn!(
 2102                                    logger =>
 2103                                    "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 2104                                    buffer_path_abs.as_path(),
 2105                                    describe_code_action(&action),
 2106                                );
 2107                                continue 'actions;
 2108                            };
 2109                            edits.extend(resolved_edits);
 2110                        }
 2111
 2112                        if edits.is_empty() {
 2113                            zlog::warn!(logger => "No edits resolved from LSP");
 2114                            continue;
 2115                        }
 2116
 2117                        extend_formatting_transaction(
 2118                            buffer,
 2119                            formatting_transaction_id,
 2120                            cx,
 2121                            |buffer, cx| {
 2122                                zlog::info!(
 2123                                    "Applying edits {edits:?}. Content: {:?}",
 2124                                    buffer.text()
 2125                                );
 2126                                buffer.edit(edits, None, cx);
 2127                                zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 2128                            },
 2129                        )?;
 2130                    }
 2131
 2132                    let Some(command) = action.lsp_action.command() else {
 2133                        continue;
 2134                    };
 2135
 2136                    zlog::warn!(
 2137                        logger =>
 2138                        "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 2139                        &command.command,
 2140                    );
 2141
 2142                    let server_capabilities = server.capabilities();
 2143                    let available_commands = server_capabilities
 2144                        .execute_command_provider
 2145                        .as_ref()
 2146                        .map(|options| options.commands.as_slice())
 2147                        .unwrap_or_default();
 2148                    if !available_commands.contains(&command.command) {
 2149                        zlog::warn!(
 2150                            logger =>
 2151                            "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2152                            command.command,
 2153                            server.name(),
 2154                        );
 2155                        continue;
 2156                    }
 2157
 2158                    extend_formatting_transaction(
 2159                        buffer,
 2160                        formatting_transaction_id,
 2161                        cx,
 2162                        |_, _| {},
 2163                    )?;
 2164                    zlog::info!(logger => "Executing command {}", &command.command);
 2165
 2166                    lsp_store.update(cx, |this, _| {
 2167                        this.as_local_mut()
 2168                            .unwrap()
 2169                            .last_workspace_edits_by_language_server
 2170                            .remove(&server.server_id());
 2171                    })?;
 2172
 2173                    let execute_command_result = server
 2174                        .request::<lsp::request::ExecuteCommand>(
 2175                            lsp::ExecuteCommandParams {
 2176                                command: command.command.clone(),
 2177                                arguments: command.arguments.clone().unwrap_or_default(),
 2178                                ..Default::default()
 2179                            },
 2180                            request_timeout,
 2181                        )
 2182                        .await
 2183                        .into_response();
 2184
 2185                    if execute_command_result.is_err() {
 2186                        zlog::error!(
 2187                            logger =>
 2188                            "Failed to execute command '{}' as part of {}",
 2189                            &command.command,
 2190                            describe_code_action(&action),
 2191                        );
 2192                        continue 'actions;
 2193                    }
 2194
 2195                    let mut project_transaction_command = lsp_store.update(cx, |this, _| {
 2196                        this.as_local_mut()
 2197                            .unwrap()
 2198                            .last_workspace_edits_by_language_server
 2199                            .remove(&server.server_id())
 2200                            .unwrap_or_default()
 2201                    })?;
 2202
 2203                    if let Some(transaction) = project_transaction_command.0.remove(&buffer.handle)
 2204                    {
 2205                        zlog::trace!(
 2206                            logger =>
 2207                            "Successfully captured {} edits that resulted from command {}",
 2208                            transaction.edit_ids.len(),
 2209                            &command.command,
 2210                        );
 2211                        let transaction_id_project_transaction = transaction.id;
 2212                        buffer.handle.update(cx, |buffer, _| {
 2213                            // it may have been removed from history if push_to_history was
 2214                            // false in deserialize_workspace_edit. If so push it so we
 2215                            // can merge it with the format transaction
 2216                            // and pop the combined transaction off the history stack
 2217                            // later if push_to_history is false
 2218                            if buffer.get_transaction(transaction.id).is_none() {
 2219                                buffer.push_transaction(transaction, Instant::now());
 2220                            }
 2221                            buffer.merge_transactions(
 2222                                transaction_id_project_transaction,
 2223                                formatting_transaction_id,
 2224                            );
 2225                        });
 2226                    }
 2227
 2228                    if project_transaction_command.0.is_empty() {
 2229                        continue;
 2230                    }
 2231
 2232                    let mut extra_buffers = String::new();
 2233                    for buffer in project_transaction_command.0.keys() {
 2234                        buffer.read_with(cx, |b, cx| {
 2235                            let Some(path) = b.project_path(cx) else {
 2236                                return;
 2237                            };
 2238
 2239                            if !extra_buffers.is_empty() {
 2240                                extra_buffers.push_str(", ");
 2241                            }
 2242                            extra_buffers.push_str(path.path.as_unix_str());
 2243                        });
 2244                    }
 2245                    zlog::warn!(
 2246                        logger =>
 2247                        "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2248                        &command.command,
 2249                        extra_buffers,
 2250                    );
 2251                    // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2252                    // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2253                    // add it so it's included, and merge it into the format transaction when its created later
 2254                }
 2255            }
 2256        }
 2257
 2258        Ok(())
 2259    }
 2260
 2261    pub async fn format_ranges_via_lsp(
 2262        this: &WeakEntity<LspStore>,
 2263        buffer_handle: &Entity<Buffer>,
 2264        ranges: &[Range<Anchor>],
 2265        abs_path: &Path,
 2266        language_server: &Arc<LanguageServer>,
 2267        settings: &LanguageSettings,
 2268        cx: &mut AsyncApp,
 2269    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2270        let capabilities = &language_server.capabilities();
 2271        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2272        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2273            anyhow::bail!(
 2274                "{} language server does not support range formatting",
 2275                language_server.name()
 2276            );
 2277        }
 2278
 2279        let uri = file_path_to_lsp_url(abs_path)?;
 2280        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2281
 2282        let request_timeout = cx.update(|app| {
 2283            ProjectSettings::get_global(app)
 2284                .global_lsp_settings
 2285                .get_request_timeout()
 2286        });
 2287        let lsp_edits = {
 2288            let mut lsp_ranges = Vec::new();
 2289            this.update(cx, |_this, cx| {
 2290                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2291                // not have been sent to the language server. This seems like a fairly systemic
 2292                // issue, though, the resolution probably is not specific to formatting.
 2293                //
 2294                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2295                // LSP.
 2296                let snapshot = buffer_handle.read(cx).snapshot();
 2297                for range in ranges {
 2298                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2299                }
 2300                anyhow::Ok(())
 2301            })??;
 2302
 2303            let mut edits = None;
 2304            for range in lsp_ranges {
 2305                if let Some(mut edit) = language_server
 2306                    .request::<lsp::request::RangeFormatting>(
 2307                        lsp::DocumentRangeFormattingParams {
 2308                            text_document: text_document.clone(),
 2309                            range,
 2310                            options: lsp_command::lsp_formatting_options(settings),
 2311                            work_done_progress_params: Default::default(),
 2312                        },
 2313                        request_timeout,
 2314                    )
 2315                    .await
 2316                    .into_response()?
 2317                {
 2318                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2319                }
 2320            }
 2321            edits
 2322        };
 2323
 2324        if let Some(lsp_edits) = lsp_edits {
 2325            this.update(cx, |this, cx| {
 2326                this.as_local_mut().unwrap().edits_from_lsp(
 2327                    buffer_handle,
 2328                    lsp_edits,
 2329                    language_server.server_id(),
 2330                    None,
 2331                    cx,
 2332                )
 2333            })?
 2334            .await
 2335        } else {
 2336            Ok(Vec::with_capacity(0))
 2337        }
 2338    }
 2339
 2340    fn server_supports_formatting(server: &Arc<LanguageServer>) -> bool {
 2341        let capabilities = server.capabilities();
 2342        let formatting = capabilities.document_formatting_provider.as_ref();
 2343        let range_formatting = capabilities.document_range_formatting_provider.as_ref();
 2344        matches!(formatting, Some(p) if *p != OneOf::Left(false))
 2345            || matches!(range_formatting, Some(p) if *p != OneOf::Left(false))
 2346    }
 2347
 2348    async fn format_via_lsp(
 2349        this: &WeakEntity<LspStore>,
 2350        buffer: &Entity<Buffer>,
 2351        abs_path: &Path,
 2352        language_server: &Arc<LanguageServer>,
 2353        settings: &LanguageSettings,
 2354        cx: &mut AsyncApp,
 2355    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2356        let logger = zlog::scoped!("lsp_format");
 2357        zlog::debug!(logger => "Formatting via LSP");
 2358
 2359        let uri = file_path_to_lsp_url(abs_path)?;
 2360        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2361        let capabilities = &language_server.capabilities();
 2362
 2363        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2364        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2365
 2366        let request_timeout = cx.update(|app| {
 2367            ProjectSettings::get_global(app)
 2368                .global_lsp_settings
 2369                .get_request_timeout()
 2370        });
 2371
 2372        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2373            let _timer = zlog::time!(logger => "format-full");
 2374            language_server
 2375                .request::<lsp::request::Formatting>(
 2376                    lsp::DocumentFormattingParams {
 2377                        text_document,
 2378                        options: lsp_command::lsp_formatting_options(settings),
 2379                        work_done_progress_params: Default::default(),
 2380                    },
 2381                    request_timeout,
 2382                )
 2383                .await
 2384                .into_response()?
 2385        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2386            let _timer = zlog::time!(logger => "format-range");
 2387            let buffer_start = lsp::Position::new(0, 0);
 2388            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2389            language_server
 2390                .request::<lsp::request::RangeFormatting>(
 2391                    lsp::DocumentRangeFormattingParams {
 2392                        text_document: text_document.clone(),
 2393                        range: lsp::Range::new(buffer_start, buffer_end),
 2394                        options: lsp_command::lsp_formatting_options(settings),
 2395                        work_done_progress_params: Default::default(),
 2396                    },
 2397                    request_timeout,
 2398                )
 2399                .await
 2400                .into_response()?
 2401        } else {
 2402            None
 2403        };
 2404
 2405        if let Some(lsp_edits) = lsp_edits {
 2406            this.update(cx, |this, cx| {
 2407                this.as_local_mut().unwrap().edits_from_lsp(
 2408                    buffer,
 2409                    lsp_edits,
 2410                    language_server.server_id(),
 2411                    None,
 2412                    cx,
 2413                )
 2414            })?
 2415            .await
 2416        } else {
 2417            Ok(Vec::with_capacity(0))
 2418        }
 2419    }
 2420
 2421    async fn format_via_external_command(
 2422        buffer: &FormattableBuffer,
 2423        command: &str,
 2424        arguments: Option<&[String]>,
 2425        cx: &mut AsyncApp,
 2426    ) -> Result<Option<Diff>> {
 2427        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2428            let file = File::from_dyn(buffer.file())?;
 2429            let worktree = file.worktree.read(cx);
 2430            let mut worktree_path = worktree.abs_path().to_path_buf();
 2431            if worktree.root_entry()?.is_file() {
 2432                worktree_path.pop();
 2433            }
 2434            Some(worktree_path)
 2435        });
 2436
 2437        use util::command::Stdio;
 2438        let mut child = util::command::new_command(command);
 2439
 2440        if let Some(buffer_env) = buffer.env.as_ref() {
 2441            child.envs(buffer_env);
 2442        }
 2443
 2444        if let Some(working_dir_path) = working_dir_path {
 2445            child.current_dir(working_dir_path);
 2446        }
 2447
 2448        if let Some(arguments) = arguments {
 2449            child.args(arguments.iter().map(|arg| {
 2450                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2451                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2452                } else {
 2453                    arg.replace("{buffer_path}", "Untitled")
 2454                }
 2455            }));
 2456        }
 2457
 2458        let mut child = child
 2459            .stdin(Stdio::piped())
 2460            .stdout(Stdio::piped())
 2461            .stderr(Stdio::piped())
 2462            .spawn()?;
 2463
 2464        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2465        let text = buffer
 2466            .handle
 2467            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2468        for chunk in text.chunks() {
 2469            stdin.write_all(chunk.as_bytes()).await?;
 2470        }
 2471        stdin.flush().await?;
 2472
 2473        let output = child.output().await?;
 2474        anyhow::ensure!(
 2475            output.status.success(),
 2476            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2477            output.status.code(),
 2478            String::from_utf8_lossy(&output.stdout),
 2479            String::from_utf8_lossy(&output.stderr),
 2480        );
 2481
 2482        let stdout = String::from_utf8(output.stdout)?;
 2483        Ok(Some(
 2484            buffer
 2485                .handle
 2486                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2487                .await,
 2488        ))
 2489    }
 2490
 2491    async fn try_resolve_code_action(
 2492        lang_server: &LanguageServer,
 2493        action: &mut CodeAction,
 2494        request_timeout: Duration,
 2495    ) -> anyhow::Result<()> {
 2496        match &mut action.lsp_action {
 2497            LspAction::Action(lsp_action) => {
 2498                if !action.resolved
 2499                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2500                    && lsp_action.data.is_some()
 2501                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2502                {
 2503                    **lsp_action = lang_server
 2504                        .request::<lsp::request::CodeActionResolveRequest>(
 2505                            *lsp_action.clone(),
 2506                            request_timeout,
 2507                        )
 2508                        .await
 2509                        .into_response()?;
 2510                }
 2511            }
 2512            LspAction::CodeLens(lens) => {
 2513                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2514                    *lens = lang_server
 2515                        .request::<lsp::request::CodeLensResolve>(lens.clone(), request_timeout)
 2516                        .await
 2517                        .into_response()?;
 2518                }
 2519            }
 2520            LspAction::Command(_) => {}
 2521        }
 2522
 2523        action.resolved = true;
 2524        anyhow::Ok(())
 2525    }
 2526
 2527    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2528        let buffer = buffer_handle.read(cx);
 2529
 2530        let file = buffer.file().cloned();
 2531
 2532        let Some(file) = File::from_dyn(file.as_ref()) else {
 2533            return;
 2534        };
 2535        if !file.is_local() {
 2536            return;
 2537        }
 2538        let path = ProjectPath::from_file(file, cx);
 2539        let worktree_id = file.worktree_id(cx);
 2540        let language = buffer.language().cloned();
 2541
 2542        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2543            for (server_id, diagnostics) in
 2544                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2545            {
 2546                self.update_buffer_diagnostics(
 2547                    buffer_handle,
 2548                    server_id,
 2549                    None,
 2550                    None,
 2551                    None,
 2552                    Vec::new(),
 2553                    diagnostics,
 2554                    cx,
 2555                )
 2556                .log_err();
 2557            }
 2558        }
 2559        let Some(language) = language else {
 2560            return;
 2561        };
 2562        let Some(snapshot) = self
 2563            .worktree_store
 2564            .read(cx)
 2565            .worktree_for_id(worktree_id, cx)
 2566            .map(|worktree| worktree.read(cx).snapshot())
 2567        else {
 2568            return;
 2569        };
 2570        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2571
 2572        for server_id in
 2573            self.lsp_tree
 2574                .get(path, language.name(), language.manifest(), &delegate, cx)
 2575        {
 2576            let server = self
 2577                .language_servers
 2578                .get(&server_id)
 2579                .and_then(|server_state| {
 2580                    if let LanguageServerState::Running { server, .. } = server_state {
 2581                        Some(server.clone())
 2582                    } else {
 2583                        None
 2584                    }
 2585                });
 2586            let server = match server {
 2587                Some(server) => server,
 2588                None => continue,
 2589            };
 2590
 2591            buffer_handle.update(cx, |buffer, cx| {
 2592                buffer.set_completion_triggers(
 2593                    server.server_id(),
 2594                    server
 2595                        .capabilities()
 2596                        .completion_provider
 2597                        .as_ref()
 2598                        .and_then(|provider| {
 2599                            provider
 2600                                .trigger_characters
 2601                                .as_ref()
 2602                                .map(|characters| characters.iter().cloned().collect())
 2603                        })
 2604                        .unwrap_or_default(),
 2605                    cx,
 2606                );
 2607            });
 2608        }
 2609    }
 2610
 2611    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2612        buffer.update(cx, |buffer, cx| {
 2613            let Some(language) = buffer.language() else {
 2614                return;
 2615            };
 2616            let path = ProjectPath {
 2617                worktree_id: old_file.worktree_id(cx),
 2618                path: old_file.path.clone(),
 2619            };
 2620            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2621                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2622                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2623            }
 2624        });
 2625    }
 2626
 2627    fn update_buffer_diagnostics(
 2628        &mut self,
 2629        buffer: &Entity<Buffer>,
 2630        server_id: LanguageServerId,
 2631        registration_id: Option<Option<SharedString>>,
 2632        result_id: Option<SharedString>,
 2633        version: Option<i32>,
 2634        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2635        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2636        cx: &mut Context<LspStore>,
 2637    ) -> Result<()> {
 2638        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2639            Ordering::Equal
 2640                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2641                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2642                .then_with(|| a.severity.cmp(&b.severity))
 2643                .then_with(|| a.message.cmp(&b.message))
 2644        }
 2645
 2646        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2647        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2648        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2649
 2650        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2651            Ordering::Equal
 2652                .then_with(|| a.range.start.cmp(&b.range.start))
 2653                .then_with(|| b.range.end.cmp(&a.range.end))
 2654                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2655        });
 2656
 2657        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2658
 2659        let edits_since_save = std::cell::LazyCell::new(|| {
 2660            let saved_version = buffer.read(cx).saved_version();
 2661            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2662        });
 2663
 2664        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2665
 2666        for (new_diagnostic, entry) in diagnostics {
 2667            let start;
 2668            let end;
 2669            if new_diagnostic && entry.diagnostic.is_disk_based {
 2670                // Some diagnostics are based on files on disk instead of buffers'
 2671                // current contents. Adjust these diagnostics' ranges to reflect
 2672                // any unsaved edits.
 2673                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2674                // and were properly adjusted on reuse.
 2675                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2676                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2677            } else {
 2678                start = entry.range.start;
 2679                end = entry.range.end;
 2680            }
 2681
 2682            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2683                ..snapshot.clip_point_utf16(end, Bias::Right);
 2684
 2685            // Expand empty ranges by one codepoint
 2686            if range.start == range.end {
 2687                // This will be go to the next boundary when being clipped
 2688                range.end.column += 1;
 2689                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2690                if range.start == range.end && range.end.column > 0 {
 2691                    range.start.column -= 1;
 2692                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2693                }
 2694            }
 2695
 2696            sanitized_diagnostics.push(DiagnosticEntry {
 2697                range,
 2698                diagnostic: entry.diagnostic,
 2699            });
 2700        }
 2701        drop(edits_since_save);
 2702
 2703        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2704        buffer.update(cx, |buffer, cx| {
 2705            if let Some(registration_id) = registration_id {
 2706                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2707                    self.buffer_pull_diagnostics_result_ids
 2708                        .entry(server_id)
 2709                        .or_default()
 2710                        .entry(registration_id)
 2711                        .or_default()
 2712                        .insert(abs_path, result_id);
 2713                }
 2714            }
 2715
 2716            buffer.update_diagnostics(server_id, set, cx)
 2717        });
 2718
 2719        Ok(())
 2720    }
 2721
 2722    fn register_language_server_for_invisible_worktree(
 2723        &mut self,
 2724        worktree: &Entity<Worktree>,
 2725        language_server_id: LanguageServerId,
 2726        cx: &mut App,
 2727    ) {
 2728        let worktree = worktree.read(cx);
 2729        let worktree_id = worktree.id();
 2730        debug_assert!(!worktree.is_visible());
 2731        let Some(mut origin_seed) = self
 2732            .language_server_ids
 2733            .iter()
 2734            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2735        else {
 2736            return;
 2737        };
 2738        origin_seed.worktree_id = worktree_id;
 2739        self.language_server_ids
 2740            .entry(origin_seed)
 2741            .or_insert_with(|| UnifiedLanguageServer {
 2742                id: language_server_id,
 2743                project_roots: Default::default(),
 2744            });
 2745    }
 2746
 2747    fn register_buffer_with_language_servers(
 2748        &mut self,
 2749        buffer_handle: &Entity<Buffer>,
 2750        only_register_servers: HashSet<LanguageServerSelector>,
 2751        cx: &mut Context<LspStore>,
 2752    ) {
 2753        let buffer = buffer_handle.read(cx);
 2754        let buffer_id = buffer.remote_id();
 2755
 2756        let Some(file) = File::from_dyn(buffer.file()) else {
 2757            return;
 2758        };
 2759        if !file.is_local() {
 2760            return;
 2761        }
 2762
 2763        let abs_path = file.abs_path(cx);
 2764        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2765            return;
 2766        };
 2767        let initial_snapshot = buffer.text_snapshot();
 2768        let worktree_id = file.worktree_id(cx);
 2769
 2770        let Some(language) = buffer.language().cloned() else {
 2771            return;
 2772        };
 2773        let path: Arc<RelPath> = file
 2774            .path()
 2775            .parent()
 2776            .map(Arc::from)
 2777            .unwrap_or_else(|| file.path().clone());
 2778        let Some(worktree) = self
 2779            .worktree_store
 2780            .read(cx)
 2781            .worktree_for_id(worktree_id, cx)
 2782        else {
 2783            return;
 2784        };
 2785        let language_name = language.name();
 2786        let (reused, delegate, servers) = self
 2787            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2788            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2789            .unwrap_or_else(|| {
 2790                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2791                let delegate: Arc<dyn ManifestDelegate> =
 2792                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2793
 2794                let servers = self
 2795                    .lsp_tree
 2796                    .walk(
 2797                        ProjectPath { worktree_id, path },
 2798                        language.name(),
 2799                        language.manifest(),
 2800                        &delegate,
 2801                        cx,
 2802                    )
 2803                    .collect::<Vec<_>>();
 2804                (false, lsp_delegate, servers)
 2805            });
 2806        let servers_and_adapters = servers
 2807            .into_iter()
 2808            .filter_map(|server_node| {
 2809                if reused && server_node.server_id().is_none() {
 2810                    return None;
 2811                }
 2812                if !only_register_servers.is_empty() {
 2813                    if let Some(server_id) = server_node.server_id()
 2814                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2815                    {
 2816                        return None;
 2817                    }
 2818                    if let Some(name) = server_node.name()
 2819                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2820                    {
 2821                        return None;
 2822                    }
 2823                }
 2824
 2825                let server_id = server_node.server_id_or_init(|disposition| {
 2826                    let path = &disposition.path;
 2827
 2828                    {
 2829                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2830
 2831                        let server_id = self.get_or_insert_language_server(
 2832                            &worktree,
 2833                            delegate.clone(),
 2834                            disposition,
 2835                            &language_name,
 2836                            cx,
 2837                        );
 2838
 2839                        if let Some(state) = self.language_servers.get(&server_id)
 2840                            && let Ok(uri) = uri
 2841                        {
 2842                            state.add_workspace_folder(uri);
 2843                        };
 2844                        server_id
 2845                    }
 2846                })?;
 2847                let server_state = self.language_servers.get(&server_id)?;
 2848                if let LanguageServerState::Running {
 2849                    server, adapter, ..
 2850                } = server_state
 2851                {
 2852                    Some((server.clone(), adapter.clone()))
 2853                } else {
 2854                    None
 2855                }
 2856            })
 2857            .collect::<Vec<_>>();
 2858        for (server, adapter) in servers_and_adapters {
 2859            buffer_handle.update(cx, |buffer, cx| {
 2860                buffer.set_completion_triggers(
 2861                    server.server_id(),
 2862                    server
 2863                        .capabilities()
 2864                        .completion_provider
 2865                        .as_ref()
 2866                        .and_then(|provider| {
 2867                            provider
 2868                                .trigger_characters
 2869                                .as_ref()
 2870                                .map(|characters| characters.iter().cloned().collect())
 2871                        })
 2872                        .unwrap_or_default(),
 2873                    cx,
 2874                );
 2875            });
 2876
 2877            let snapshot = LspBufferSnapshot {
 2878                version: 0,
 2879                snapshot: initial_snapshot.clone(),
 2880            };
 2881
 2882            let mut registered = false;
 2883            self.buffer_snapshots
 2884                .entry(buffer_id)
 2885                .or_default()
 2886                .entry(server.server_id())
 2887                .or_insert_with(|| {
 2888                    registered = true;
 2889                    server.register_buffer(
 2890                        uri.clone(),
 2891                        adapter.language_id(&language.name()),
 2892                        0,
 2893                        initial_snapshot.text(),
 2894                    );
 2895
 2896                    vec![snapshot]
 2897                });
 2898
 2899            self.buffers_opened_in_servers
 2900                .entry(buffer_id)
 2901                .or_default()
 2902                .insert(server.server_id());
 2903            if registered {
 2904                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2905                    language_server_id: server.server_id(),
 2906                    name: None,
 2907                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2908                        proto::RegisteredForBuffer {
 2909                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2910                            buffer_id: buffer_id.to_proto(),
 2911                        },
 2912                    ),
 2913                });
 2914            }
 2915        }
 2916    }
 2917
 2918    fn reuse_existing_language_server<'lang_name>(
 2919        &self,
 2920        server_tree: &LanguageServerTree,
 2921        worktree: &Entity<Worktree>,
 2922        language_name: &'lang_name LanguageName,
 2923        cx: &mut App,
 2924    ) -> Option<(
 2925        Arc<LocalLspAdapterDelegate>,
 2926        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2927    )> {
 2928        if worktree.read(cx).is_visible() {
 2929            return None;
 2930        }
 2931
 2932        let worktree_store = self.worktree_store.read(cx);
 2933        let servers = server_tree
 2934            .instances
 2935            .iter()
 2936            .filter(|(worktree_id, _)| {
 2937                worktree_store
 2938                    .worktree_for_id(**worktree_id, cx)
 2939                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2940            })
 2941            .flat_map(|(worktree_id, servers)| {
 2942                servers
 2943                    .roots
 2944                    .iter()
 2945                    .flat_map(|(_, language_servers)| language_servers)
 2946                    .map(move |(_, (server_node, server_languages))| {
 2947                        (worktree_id, server_node, server_languages)
 2948                    })
 2949                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2950                    .map(|(worktree_id, server_node, _)| {
 2951                        (
 2952                            *worktree_id,
 2953                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2954                        )
 2955                    })
 2956            })
 2957            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2958                acc.entry(worktree_id)
 2959                    .or_insert_with(Vec::new)
 2960                    .push(server_node);
 2961                acc
 2962            })
 2963            .into_values()
 2964            .max_by_key(|servers| servers.len())?;
 2965
 2966        let worktree_id = worktree.read(cx).id();
 2967        let apply = move |tree: &mut LanguageServerTree| {
 2968            for server_node in &servers {
 2969                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2970            }
 2971            servers
 2972        };
 2973
 2974        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2975        Some((delegate, apply))
 2976    }
 2977
 2978    pub(crate) fn unregister_old_buffer_from_language_servers(
 2979        &mut self,
 2980        buffer: &Entity<Buffer>,
 2981        old_file: &File,
 2982        cx: &mut App,
 2983    ) {
 2984        let old_path = match old_file.as_local() {
 2985            Some(local) => local.abs_path(cx),
 2986            None => return,
 2987        };
 2988
 2989        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2990            debug_panic!("{old_path:?} is not parseable as an URI");
 2991            return;
 2992        };
 2993        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2994    }
 2995
 2996    pub(crate) fn unregister_buffer_from_language_servers(
 2997        &mut self,
 2998        buffer: &Entity<Buffer>,
 2999        file_url: &lsp::Uri,
 3000        cx: &mut App,
 3001    ) {
 3002        buffer.update(cx, |buffer, cx| {
 3003            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 3004
 3005            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 3006                if snapshots
 3007                    .as_mut()
 3008                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 3009                {
 3010                    language_server.unregister_buffer(file_url.clone());
 3011                }
 3012            }
 3013        });
 3014    }
 3015
 3016    fn buffer_snapshot_for_lsp_version(
 3017        &mut self,
 3018        buffer: &Entity<Buffer>,
 3019        server_id: LanguageServerId,
 3020        version: Option<i32>,
 3021        cx: &App,
 3022    ) -> Result<TextBufferSnapshot> {
 3023        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 3024
 3025        if let Some(version) = version {
 3026            let buffer_id = buffer.read(cx).remote_id();
 3027            let snapshots = if let Some(snapshots) = self
 3028                .buffer_snapshots
 3029                .get_mut(&buffer_id)
 3030                .and_then(|m| m.get_mut(&server_id))
 3031            {
 3032                snapshots
 3033            } else if version == 0 {
 3034                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 3035                // We detect this case and treat it as if the version was `None`.
 3036                return Ok(buffer.read(cx).text_snapshot());
 3037            } else {
 3038                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 3039            };
 3040
 3041            let found_snapshot = snapshots
 3042                    .binary_search_by_key(&version, |e| e.version)
 3043                    .map(|ix| snapshots[ix].snapshot.clone())
 3044                    .map_err(|_| {
 3045                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 3046                    })?;
 3047
 3048            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 3049            Ok(found_snapshot)
 3050        } else {
 3051            Ok((buffer.read(cx)).text_snapshot())
 3052        }
 3053    }
 3054
 3055    async fn get_server_code_actions_from_action_kinds(
 3056        lsp_store: &WeakEntity<LspStore>,
 3057        language_server_id: LanguageServerId,
 3058        code_action_kinds: Vec<lsp::CodeActionKind>,
 3059        buffer: &Entity<Buffer>,
 3060        cx: &mut AsyncApp,
 3061    ) -> Result<Vec<CodeAction>> {
 3062        let actions = lsp_store
 3063            .update(cx, move |this, cx| {
 3064                let request = GetCodeActions {
 3065                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 3066                    kinds: Some(code_action_kinds),
 3067                };
 3068                let server = LanguageServerToQuery::Other(language_server_id);
 3069                this.request_lsp(buffer.clone(), server, request, cx)
 3070            })?
 3071            .await?;
 3072        Ok(actions)
 3073    }
 3074
 3075    pub async fn execute_code_actions_on_server(
 3076        lsp_store: &WeakEntity<LspStore>,
 3077        language_server: &Arc<LanguageServer>,
 3078        actions: Vec<CodeAction>,
 3079        push_to_history: bool,
 3080        project_transaction: &mut ProjectTransaction,
 3081        cx: &mut AsyncApp,
 3082    ) -> anyhow::Result<()> {
 3083        let request_timeout = cx.update(|app| {
 3084            ProjectSettings::get_global(app)
 3085                .global_lsp_settings
 3086                .get_request_timeout()
 3087        });
 3088
 3089        for mut action in actions {
 3090            Self::try_resolve_code_action(language_server, &mut action, request_timeout)
 3091                .await
 3092                .context("resolving a formatting code action")?;
 3093
 3094            if let Some(edit) = action.lsp_action.edit() {
 3095                if edit.changes.is_none() && edit.document_changes.is_none() {
 3096                    continue;
 3097                }
 3098
 3099                let new = Self::deserialize_workspace_edit(
 3100                    lsp_store.upgrade().context("project dropped")?,
 3101                    edit.clone(),
 3102                    push_to_history,
 3103                    language_server.clone(),
 3104                    cx,
 3105                )
 3106                .await?;
 3107                project_transaction.0.extend(new.0);
 3108            }
 3109
 3110            let Some(command) = action.lsp_action.command() else {
 3111                continue;
 3112            };
 3113
 3114            let server_capabilities = language_server.capabilities();
 3115            let available_commands = server_capabilities
 3116                .execute_command_provider
 3117                .as_ref()
 3118                .map(|options| options.commands.as_slice())
 3119                .unwrap_or_default();
 3120            if !available_commands.contains(&command.command) {
 3121                log::warn!(
 3122                    "Cannot execute a command {} not listed in the language server capabilities",
 3123                    command.command
 3124                );
 3125                continue;
 3126            }
 3127
 3128            lsp_store.update(cx, |lsp_store, _| {
 3129                if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 3130                    mode.last_workspace_edits_by_language_server
 3131                        .remove(&language_server.server_id());
 3132                }
 3133            })?;
 3134
 3135            language_server
 3136                .request::<lsp::request::ExecuteCommand>(
 3137                    lsp::ExecuteCommandParams {
 3138                        command: command.command.clone(),
 3139                        arguments: command.arguments.clone().unwrap_or_default(),
 3140                        ..Default::default()
 3141                    },
 3142                    request_timeout,
 3143                )
 3144                .await
 3145                .into_response()
 3146                .context("execute command")?;
 3147
 3148            lsp_store.update(cx, |this, _| {
 3149                if let LspStoreMode::Local(mode) = &mut this.mode {
 3150                    project_transaction.0.extend(
 3151                        mode.last_workspace_edits_by_language_server
 3152                            .remove(&language_server.server_id())
 3153                            .unwrap_or_default()
 3154                            .0,
 3155                    )
 3156                }
 3157            })?;
 3158        }
 3159        Ok(())
 3160    }
 3161
 3162    pub async fn deserialize_text_edits(
 3163        this: Entity<LspStore>,
 3164        buffer_to_edit: Entity<Buffer>,
 3165        edits: Vec<lsp::TextEdit>,
 3166        push_to_history: bool,
 3167        _: Arc<CachedLspAdapter>,
 3168        language_server: Arc<LanguageServer>,
 3169        cx: &mut AsyncApp,
 3170    ) -> Result<Option<Transaction>> {
 3171        let edits = this
 3172            .update(cx, |this, cx| {
 3173                this.as_local_mut().unwrap().edits_from_lsp(
 3174                    &buffer_to_edit,
 3175                    edits,
 3176                    language_server.server_id(),
 3177                    None,
 3178                    cx,
 3179                )
 3180            })
 3181            .await?;
 3182
 3183        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3184            buffer.finalize_last_transaction();
 3185            buffer.start_transaction();
 3186            for (range, text) in edits {
 3187                buffer.edit([(range, text)], None, cx);
 3188            }
 3189
 3190            if buffer.end_transaction(cx).is_some() {
 3191                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3192                if !push_to_history {
 3193                    buffer.forget_transaction(transaction.id);
 3194                }
 3195                Some(transaction)
 3196            } else {
 3197                None
 3198            }
 3199        });
 3200
 3201        Ok(transaction)
 3202    }
 3203
 3204    #[allow(clippy::type_complexity)]
 3205    pub fn edits_from_lsp(
 3206        &mut self,
 3207        buffer: &Entity<Buffer>,
 3208        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3209        server_id: LanguageServerId,
 3210        version: Option<i32>,
 3211        cx: &mut Context<LspStore>,
 3212    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3213        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3214        cx.background_spawn(async move {
 3215            let snapshot = snapshot?;
 3216            let mut lsp_edits = lsp_edits
 3217                .into_iter()
 3218                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3219                .collect::<Vec<_>>();
 3220
 3221            lsp_edits.sort_unstable_by_key(|(range, _)| (range.start, range.end));
 3222
 3223            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3224            let mut edits = Vec::new();
 3225            while let Some((range, mut new_text)) = lsp_edits.next() {
 3226                // Clip invalid ranges provided by the language server.
 3227                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3228                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3229
 3230                // Combine any LSP edits that are adjacent.
 3231                //
 3232                // Also, combine LSP edits that are separated from each other by only
 3233                // a newline. This is important because for some code actions,
 3234                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3235                // are separated by unchanged newline characters.
 3236                //
 3237                // In order for the diffing logic below to work properly, any edits that
 3238                // cancel each other out must be combined into one.
 3239                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3240                    if next_range.start.0 > range.end {
 3241                        if next_range.start.0.row > range.end.row + 1
 3242                            || next_range.start.0.column > 0
 3243                            || snapshot.clip_point_utf16(
 3244                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3245                                Bias::Left,
 3246                            ) > range.end
 3247                        {
 3248                            break;
 3249                        }
 3250                        new_text.push('\n');
 3251                    }
 3252                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3253                    new_text.push_str(next_text);
 3254                    lsp_edits.next();
 3255                }
 3256
 3257                // For multiline edits, perform a diff of the old and new text so that
 3258                // we can identify the changes more precisely, preserving the locations
 3259                // of any anchors positioned in the unchanged regions.
 3260                if range.end.row > range.start.row {
 3261                    let offset = range.start.to_offset(&snapshot);
 3262                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3263                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3264                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3265                        (
 3266                            snapshot.anchor_after(offset + range.start)
 3267                                ..snapshot.anchor_before(offset + range.end),
 3268                            replacement,
 3269                        )
 3270                    }));
 3271                } else if range.end == range.start {
 3272                    let anchor = snapshot.anchor_after(range.start);
 3273                    edits.push((anchor..anchor, new_text.into()));
 3274                } else {
 3275                    let edit_start = snapshot.anchor_after(range.start);
 3276                    let edit_end = snapshot.anchor_before(range.end);
 3277                    edits.push((edit_start..edit_end, new_text.into()));
 3278                }
 3279            }
 3280
 3281            Ok(edits)
 3282        })
 3283    }
 3284
 3285    pub(crate) async fn deserialize_workspace_edit(
 3286        this: Entity<LspStore>,
 3287        edit: lsp::WorkspaceEdit,
 3288        push_to_history: bool,
 3289        language_server: Arc<LanguageServer>,
 3290        cx: &mut AsyncApp,
 3291    ) -> Result<ProjectTransaction> {
 3292        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3293
 3294        let mut operations = Vec::new();
 3295        if let Some(document_changes) = edit.document_changes {
 3296            match document_changes {
 3297                lsp::DocumentChanges::Edits(edits) => {
 3298                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3299                }
 3300                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3301            }
 3302        } else if let Some(changes) = edit.changes {
 3303            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3304                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3305                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3306                        uri,
 3307                        version: None,
 3308                    },
 3309                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3310                })
 3311            }));
 3312        }
 3313
 3314        let mut project_transaction = ProjectTransaction::default();
 3315        for operation in operations {
 3316            match operation {
 3317                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3318                    let abs_path = op
 3319                        .uri
 3320                        .to_file_path()
 3321                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3322
 3323                    if let Some(parent_path) = abs_path.parent() {
 3324                        fs.create_dir(parent_path).await?;
 3325                    }
 3326                    if abs_path.ends_with("/") {
 3327                        fs.create_dir(&abs_path).await?;
 3328                    } else {
 3329                        fs.create_file(
 3330                            &abs_path,
 3331                            op.options
 3332                                .map(|options| fs::CreateOptions {
 3333                                    overwrite: options.overwrite.unwrap_or(false),
 3334                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3335                                })
 3336                                .unwrap_or_default(),
 3337                        )
 3338                        .await?;
 3339                    }
 3340                }
 3341
 3342                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3343                    let source_abs_path = op
 3344                        .old_uri
 3345                        .to_file_path()
 3346                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3347                    let target_abs_path = op
 3348                        .new_uri
 3349                        .to_file_path()
 3350                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3351
 3352                    let options = fs::RenameOptions {
 3353                        overwrite: op
 3354                            .options
 3355                            .as_ref()
 3356                            .and_then(|options| options.overwrite)
 3357                            .unwrap_or(false),
 3358                        ignore_if_exists: op
 3359                            .options
 3360                            .as_ref()
 3361                            .and_then(|options| options.ignore_if_exists)
 3362                            .unwrap_or(false),
 3363                        create_parents: true,
 3364                    };
 3365
 3366                    fs.rename(&source_abs_path, &target_abs_path, options)
 3367                        .await?;
 3368                }
 3369
 3370                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3371                    let abs_path = op
 3372                        .uri
 3373                        .to_file_path()
 3374                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3375                    let options = op
 3376                        .options
 3377                        .map(|options| fs::RemoveOptions {
 3378                            recursive: options.recursive.unwrap_or(false),
 3379                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3380                        })
 3381                        .unwrap_or_default();
 3382                    if abs_path.ends_with("/") {
 3383                        fs.remove_dir(&abs_path, options).await?;
 3384                    } else {
 3385                        fs.remove_file(&abs_path, options).await?;
 3386                    }
 3387                }
 3388
 3389                lsp::DocumentChangeOperation::Edit(op) => {
 3390                    let buffer_to_edit = this
 3391                        .update(cx, |this, cx| {
 3392                            this.open_local_buffer_via_lsp(
 3393                                op.text_document.uri.clone(),
 3394                                language_server.server_id(),
 3395                                cx,
 3396                            )
 3397                        })
 3398                        .await?;
 3399
 3400                    let edits = this
 3401                        .update(cx, |this, cx| {
 3402                            let path = buffer_to_edit.read(cx).project_path(cx);
 3403                            let active_entry = this.active_entry;
 3404                            let is_active_entry = path.is_some_and(|project_path| {
 3405                                this.worktree_store
 3406                                    .read(cx)
 3407                                    .entry_for_path(&project_path, cx)
 3408                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3409                            });
 3410                            let local = this.as_local_mut().unwrap();
 3411
 3412                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3413                            for edit in op.edits {
 3414                                match edit {
 3415                                    Edit::Plain(edit) => {
 3416                                        if !edits.contains(&edit) {
 3417                                            edits.push(edit)
 3418                                        }
 3419                                    }
 3420                                    Edit::Annotated(edit) => {
 3421                                        if !edits.contains(&edit.text_edit) {
 3422                                            edits.push(edit.text_edit)
 3423                                        }
 3424                                    }
 3425                                    Edit::Snippet(edit) => {
 3426                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3427                                        else {
 3428                                            continue;
 3429                                        };
 3430
 3431                                        if is_active_entry {
 3432                                            snippet_edits.push((edit.range, snippet));
 3433                                        } else {
 3434                                            // Since this buffer is not focused, apply a normal edit.
 3435                                            let new_edit = TextEdit {
 3436                                                range: edit.range,
 3437                                                new_text: snippet.text,
 3438                                            };
 3439                                            if !edits.contains(&new_edit) {
 3440                                                edits.push(new_edit);
 3441                                            }
 3442                                        }
 3443                                    }
 3444                                }
 3445                            }
 3446                            if !snippet_edits.is_empty() {
 3447                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3448                                let version = if let Some(buffer_version) = op.text_document.version
 3449                                {
 3450                                    local
 3451                                        .buffer_snapshot_for_lsp_version(
 3452                                            &buffer_to_edit,
 3453                                            language_server.server_id(),
 3454                                            Some(buffer_version),
 3455                                            cx,
 3456                                        )
 3457                                        .ok()
 3458                                        .map(|snapshot| snapshot.version)
 3459                                } else {
 3460                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3461                                };
 3462
 3463                                let most_recent_edit =
 3464                                    version.and_then(|version| version.most_recent());
 3465                                // Check if the edit that triggered that edit has been made by this participant.
 3466
 3467                                if let Some(most_recent_edit) = most_recent_edit {
 3468                                    cx.emit(LspStoreEvent::SnippetEdit {
 3469                                        buffer_id,
 3470                                        edits: snippet_edits,
 3471                                        most_recent_edit,
 3472                                    });
 3473                                }
 3474                            }
 3475
 3476                            local.edits_from_lsp(
 3477                                &buffer_to_edit,
 3478                                edits,
 3479                                language_server.server_id(),
 3480                                op.text_document.version,
 3481                                cx,
 3482                            )
 3483                        })
 3484                        .await?;
 3485
 3486                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3487                        buffer.finalize_last_transaction();
 3488                        buffer.start_transaction();
 3489                        for (range, text) in edits {
 3490                            buffer.edit([(range, text)], None, cx);
 3491                        }
 3492
 3493                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3494                            if push_to_history {
 3495                                buffer.finalize_last_transaction();
 3496                                buffer.get_transaction(transaction_id).cloned()
 3497                            } else {
 3498                                buffer.forget_transaction(transaction_id)
 3499                            }
 3500                        })
 3501                    });
 3502                    if let Some(transaction) = transaction {
 3503                        project_transaction.0.insert(buffer_to_edit, transaction);
 3504                    }
 3505                }
 3506            }
 3507        }
 3508
 3509        Ok(project_transaction)
 3510    }
 3511
 3512    async fn on_lsp_workspace_edit(
 3513        this: WeakEntity<LspStore>,
 3514        params: lsp::ApplyWorkspaceEditParams,
 3515        server_id: LanguageServerId,
 3516        cx: &mut AsyncApp,
 3517    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3518        let this = this.upgrade().context("project project closed")?;
 3519        let language_server = this
 3520            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3521            .context("language server not found")?;
 3522        let transaction = Self::deserialize_workspace_edit(
 3523            this.clone(),
 3524            params.edit,
 3525            true,
 3526            language_server.clone(),
 3527            cx,
 3528        )
 3529        .await
 3530        .log_err();
 3531        this.update(cx, |this, cx| {
 3532            if let Some(transaction) = transaction {
 3533                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3534
 3535                this.as_local_mut()
 3536                    .unwrap()
 3537                    .last_workspace_edits_by_language_server
 3538                    .insert(server_id, transaction);
 3539            }
 3540        });
 3541        Ok(lsp::ApplyWorkspaceEditResponse {
 3542            applied: true,
 3543            failed_change: None,
 3544            failure_reason: None,
 3545        })
 3546    }
 3547
 3548    fn remove_worktree(
 3549        &mut self,
 3550        id_to_remove: WorktreeId,
 3551        cx: &mut Context<LspStore>,
 3552    ) -> Vec<LanguageServerId> {
 3553        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3554        self.diagnostics.remove(&id_to_remove);
 3555        self.prettier_store.update(cx, |prettier_store, cx| {
 3556            prettier_store.remove_worktree(id_to_remove, cx);
 3557        });
 3558
 3559        let mut servers_to_remove = BTreeSet::default();
 3560        let mut servers_to_preserve = HashSet::default();
 3561        for (seed, state) in &self.language_server_ids {
 3562            if seed.worktree_id == id_to_remove {
 3563                servers_to_remove.insert(state.id);
 3564            } else {
 3565                servers_to_preserve.insert(state.id);
 3566            }
 3567        }
 3568        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3569        self.language_server_ids
 3570            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3571        for server_id_to_remove in &servers_to_remove {
 3572            self.language_server_watched_paths
 3573                .remove(server_id_to_remove);
 3574            self.language_server_paths_watched_for_rename
 3575                .remove(server_id_to_remove);
 3576            self.last_workspace_edits_by_language_server
 3577                .remove(server_id_to_remove);
 3578            self.language_servers.remove(server_id_to_remove);
 3579            self.buffer_pull_diagnostics_result_ids
 3580                .remove(server_id_to_remove);
 3581            self.workspace_pull_diagnostics_result_ids
 3582                .remove(server_id_to_remove);
 3583            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3584                buffer_servers.remove(server_id_to_remove);
 3585            }
 3586            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3587        }
 3588        servers_to_remove.into_iter().collect()
 3589    }
 3590
 3591    fn rebuild_watched_paths_inner<'a>(
 3592        &'a self,
 3593        language_server_id: LanguageServerId,
 3594        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3595        cx: &mut Context<LspStore>,
 3596    ) -> LanguageServerWatchedPathsBuilder {
 3597        let worktrees = self
 3598            .worktree_store
 3599            .read(cx)
 3600            .worktrees()
 3601            .filter_map(|worktree| {
 3602                self.language_servers_for_worktree(worktree.read(cx).id())
 3603                    .find(|server| server.server_id() == language_server_id)
 3604                    .map(|_| worktree)
 3605            })
 3606            .collect::<Vec<_>>();
 3607
 3608        let mut worktree_globs = HashMap::default();
 3609        let mut abs_globs = HashMap::default();
 3610        log::trace!(
 3611            "Processing new watcher paths for language server with id {}",
 3612            language_server_id
 3613        );
 3614
 3615        for watcher in watchers {
 3616            if let Some((worktree, literal_prefix, pattern)) =
 3617                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3618            {
 3619                worktree.update(cx, |worktree, _| {
 3620                    if let Some((tree, glob)) =
 3621                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3622                    {
 3623                        tree.add_path_prefix_to_scan(literal_prefix);
 3624                        worktree_globs
 3625                            .entry(tree.id())
 3626                            .or_insert_with(GlobSetBuilder::new)
 3627                            .add(glob);
 3628                    }
 3629                });
 3630            } else {
 3631                let (path, pattern) = match &watcher.glob_pattern {
 3632                    lsp::GlobPattern::String(s) => {
 3633                        let watcher_path = SanitizedPath::new(s);
 3634                        let path = glob_literal_prefix(watcher_path.as_path());
 3635                        let pattern = watcher_path
 3636                            .as_path()
 3637                            .strip_prefix(&path)
 3638                            .map(|p| p.to_string_lossy().into_owned())
 3639                            .unwrap_or_else(|e| {
 3640                                debug_panic!(
 3641                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3642                                    s,
 3643                                    path.display(),
 3644                                    e
 3645                                );
 3646                                watcher_path.as_path().to_string_lossy().into_owned()
 3647                            });
 3648                        (path, pattern)
 3649                    }
 3650                    lsp::GlobPattern::Relative(rp) => {
 3651                        let Ok(mut base_uri) = match &rp.base_uri {
 3652                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3653                            lsp::OneOf::Right(base_uri) => base_uri,
 3654                        }
 3655                        .to_file_path() else {
 3656                            continue;
 3657                        };
 3658
 3659                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3660                        let pattern = Path::new(&rp.pattern)
 3661                            .strip_prefix(&path)
 3662                            .map(|p| p.to_string_lossy().into_owned())
 3663                            .unwrap_or_else(|e| {
 3664                                debug_panic!(
 3665                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3666                                    rp.pattern,
 3667                                    path.display(),
 3668                                    e
 3669                                );
 3670                                rp.pattern.clone()
 3671                            });
 3672                        base_uri.push(path);
 3673                        (base_uri, pattern)
 3674                    }
 3675                };
 3676
 3677                if let Some(glob) = Glob::new(&pattern).log_err() {
 3678                    if !path
 3679                        .components()
 3680                        .any(|c| matches!(c, path::Component::Normal(_)))
 3681                    {
 3682                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3683                        // rather than adding a new watcher for `/`.
 3684                        for worktree in &worktrees {
 3685                            worktree_globs
 3686                                .entry(worktree.read(cx).id())
 3687                                .or_insert_with(GlobSetBuilder::new)
 3688                                .add(glob.clone());
 3689                        }
 3690                    } else {
 3691                        abs_globs
 3692                            .entry(path.into())
 3693                            .or_insert_with(GlobSetBuilder::new)
 3694                            .add(glob);
 3695                    }
 3696                }
 3697            }
 3698        }
 3699
 3700        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3701        for (worktree_id, builder) in worktree_globs {
 3702            if let Ok(globset) = builder.build() {
 3703                watch_builder.watch_worktree(worktree_id, globset);
 3704            }
 3705        }
 3706        for (abs_path, builder) in abs_globs {
 3707            if let Ok(globset) = builder.build() {
 3708                watch_builder.watch_abs_path(abs_path, globset);
 3709            }
 3710        }
 3711        watch_builder
 3712    }
 3713
 3714    fn worktree_and_path_for_file_watcher(
 3715        worktrees: &[Entity<Worktree>],
 3716        watcher: &FileSystemWatcher,
 3717        cx: &App,
 3718    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3719        worktrees.iter().find_map(|worktree| {
 3720            let tree = worktree.read(cx);
 3721            let worktree_root_path = tree.abs_path();
 3722            let path_style = tree.path_style();
 3723            match &watcher.glob_pattern {
 3724                lsp::GlobPattern::String(s) => {
 3725                    let watcher_path = SanitizedPath::new(s);
 3726                    let relative = watcher_path
 3727                        .as_path()
 3728                        .strip_prefix(&worktree_root_path)
 3729                        .ok()?;
 3730                    let literal_prefix = glob_literal_prefix(relative);
 3731                    Some((
 3732                        worktree.clone(),
 3733                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3734                        relative.to_string_lossy().into_owned(),
 3735                    ))
 3736                }
 3737                lsp::GlobPattern::Relative(rp) => {
 3738                    let base_uri = match &rp.base_uri {
 3739                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3740                        lsp::OneOf::Right(base_uri) => base_uri,
 3741                    }
 3742                    .to_file_path()
 3743                    .ok()?;
 3744                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3745                    let mut literal_prefix = relative.to_owned();
 3746                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3747                    Some((
 3748                        worktree.clone(),
 3749                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3750                        rp.pattern.clone(),
 3751                    ))
 3752                }
 3753            }
 3754        })
 3755    }
 3756
 3757    fn rebuild_watched_paths(
 3758        &mut self,
 3759        language_server_id: LanguageServerId,
 3760        cx: &mut Context<LspStore>,
 3761    ) {
 3762        let Some(registrations) = self
 3763            .language_server_dynamic_registrations
 3764            .get(&language_server_id)
 3765        else {
 3766            return;
 3767        };
 3768
 3769        let watch_builder = self.rebuild_watched_paths_inner(
 3770            language_server_id,
 3771            registrations.did_change_watched_files.values().flatten(),
 3772            cx,
 3773        );
 3774        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3775        self.language_server_watched_paths
 3776            .insert(language_server_id, watcher);
 3777
 3778        cx.notify();
 3779    }
 3780
 3781    fn on_lsp_did_change_watched_files(
 3782        &mut self,
 3783        language_server_id: LanguageServerId,
 3784        registration_id: &str,
 3785        params: DidChangeWatchedFilesRegistrationOptions,
 3786        cx: &mut Context<LspStore>,
 3787    ) {
 3788        let registrations = self
 3789            .language_server_dynamic_registrations
 3790            .entry(language_server_id)
 3791            .or_default();
 3792
 3793        registrations
 3794            .did_change_watched_files
 3795            .insert(registration_id.to_string(), params.watchers);
 3796
 3797        self.rebuild_watched_paths(language_server_id, cx);
 3798    }
 3799
 3800    fn on_lsp_unregister_did_change_watched_files(
 3801        &mut self,
 3802        language_server_id: LanguageServerId,
 3803        registration_id: &str,
 3804        cx: &mut Context<LspStore>,
 3805    ) {
 3806        let registrations = self
 3807            .language_server_dynamic_registrations
 3808            .entry(language_server_id)
 3809            .or_default();
 3810
 3811        if registrations
 3812            .did_change_watched_files
 3813            .remove(registration_id)
 3814            .is_some()
 3815        {
 3816            log::info!(
 3817                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3818                language_server_id,
 3819                registration_id
 3820            );
 3821        } else {
 3822            log::warn!(
 3823                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3824                language_server_id,
 3825                registration_id
 3826            );
 3827        }
 3828
 3829        self.rebuild_watched_paths(language_server_id, cx);
 3830    }
 3831
 3832    async fn initialization_options_for_adapter(
 3833        adapter: Arc<dyn LspAdapter>,
 3834        delegate: &Arc<dyn LspAdapterDelegate>,
 3835        cx: &mut AsyncApp,
 3836    ) -> Result<Option<serde_json::Value>> {
 3837        let Some(mut initialization_config) =
 3838            adapter.clone().initialization_options(delegate, cx).await?
 3839        else {
 3840            return Ok(None);
 3841        };
 3842
 3843        for other_adapter in delegate.registered_lsp_adapters() {
 3844            if other_adapter.name() == adapter.name() {
 3845                continue;
 3846            }
 3847            if let Ok(Some(target_config)) = other_adapter
 3848                .clone()
 3849                .additional_initialization_options(adapter.name(), delegate)
 3850                .await
 3851            {
 3852                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3853            }
 3854        }
 3855
 3856        Ok(Some(initialization_config))
 3857    }
 3858
 3859    async fn workspace_configuration_for_adapter(
 3860        adapter: Arc<dyn LspAdapter>,
 3861        delegate: &Arc<dyn LspAdapterDelegate>,
 3862        toolchain: Option<Toolchain>,
 3863        requested_uri: Option<Uri>,
 3864        cx: &mut AsyncApp,
 3865    ) -> Result<serde_json::Value> {
 3866        let mut workspace_config = adapter
 3867            .clone()
 3868            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3869            .await?;
 3870
 3871        for other_adapter in delegate.registered_lsp_adapters() {
 3872            if other_adapter.name() == adapter.name() {
 3873                continue;
 3874            }
 3875            if let Ok(Some(target_config)) = other_adapter
 3876                .clone()
 3877                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3878                .await
 3879            {
 3880                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3881            }
 3882        }
 3883
 3884        Ok(workspace_config)
 3885    }
 3886
 3887    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3888        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3889            Some(server.clone())
 3890        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3891            Some(Arc::clone(server))
 3892        } else {
 3893            None
 3894        }
 3895    }
 3896}
 3897
 3898fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3899    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3900        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3901            language_server_id: server.server_id(),
 3902            name: Some(server.name()),
 3903            message: proto::update_language_server::Variant::MetadataUpdated(
 3904                proto::ServerMetadataUpdated {
 3905                    capabilities: Some(capabilities),
 3906                    binary: Some(proto::LanguageServerBinaryInfo {
 3907                        path: server.binary().path.to_string_lossy().into_owned(),
 3908                        arguments: server
 3909                            .binary()
 3910                            .arguments
 3911                            .iter()
 3912                            .map(|arg| arg.to_string_lossy().into_owned())
 3913                            .collect(),
 3914                    }),
 3915                    configuration: serde_json::to_string(server.configuration()).ok(),
 3916                    workspace_folders: server
 3917                        .workspace_folders()
 3918                        .iter()
 3919                        .map(|uri| uri.to_string())
 3920                        .collect(),
 3921                },
 3922            ),
 3923        });
 3924    }
 3925}
 3926
 3927#[derive(Debug)]
 3928pub struct FormattableBuffer {
 3929    handle: Entity<Buffer>,
 3930    abs_path: Option<PathBuf>,
 3931    env: Option<HashMap<String, String>>,
 3932    ranges: Option<Vec<Range<Anchor>>>,
 3933}
 3934
 3935pub struct RemoteLspStore {
 3936    upstream_client: Option<AnyProtoClient>,
 3937    upstream_project_id: u64,
 3938}
 3939
 3940pub(crate) enum LspStoreMode {
 3941    Local(LocalLspStore),   // ssh host and collab host
 3942    Remote(RemoteLspStore), // collab guest
 3943}
 3944
 3945impl LspStoreMode {
 3946    fn is_local(&self) -> bool {
 3947        matches!(self, LspStoreMode::Local(_))
 3948    }
 3949}
 3950
 3951pub struct LspStore {
 3952    mode: LspStoreMode,
 3953    last_formatting_failure: Option<String>,
 3954    downstream_client: Option<(AnyProtoClient, u64)>,
 3955    nonce: u128,
 3956    buffer_store: Entity<BufferStore>,
 3957    worktree_store: Entity<WorktreeStore>,
 3958    pub languages: Arc<LanguageRegistry>,
 3959    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3960    active_entry: Option<ProjectEntryId>,
 3961    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3962    _maintain_buffer_languages: Task<()>,
 3963    diagnostic_summaries:
 3964        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3965    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3966    semantic_token_config: SemanticTokenConfig,
 3967    lsp_data: HashMap<BufferId, BufferLspData>,
 3968    buffer_reload_tasks: HashMap<BufferId, Task<anyhow::Result<()>>>,
 3969    next_hint_id: Arc<AtomicUsize>,
 3970}
 3971
 3972#[derive(Debug)]
 3973pub struct BufferLspData {
 3974    buffer_version: Global,
 3975    document_colors: Option<DocumentColorData>,
 3976    code_lens: Option<CodeLensData>,
 3977    semantic_tokens: Option<SemanticTokensData>,
 3978    folding_ranges: Option<FoldingRangeData>,
 3979    document_symbols: Option<DocumentSymbolsData>,
 3980    inlay_hints: BufferInlayHints,
 3981    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3982    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3983}
 3984
 3985#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3986struct LspKey {
 3987    request_type: TypeId,
 3988    server_queried: Option<LanguageServerId>,
 3989}
 3990
 3991impl BufferLspData {
 3992    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3993        Self {
 3994            buffer_version: buffer.read(cx).version(),
 3995            document_colors: None,
 3996            code_lens: None,
 3997            semantic_tokens: None,
 3998            folding_ranges: None,
 3999            document_symbols: None,
 4000            inlay_hints: BufferInlayHints::new(buffer, cx),
 4001            lsp_requests: HashMap::default(),
 4002            chunk_lsp_requests: HashMap::default(),
 4003        }
 4004    }
 4005
 4006    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 4007        if let Some(document_colors) = &mut self.document_colors {
 4008            document_colors.remove_server_data(for_server);
 4009        }
 4010
 4011        if let Some(code_lens) = &mut self.code_lens {
 4012            code_lens.remove_server_data(for_server);
 4013        }
 4014
 4015        self.inlay_hints.remove_server_data(for_server);
 4016
 4017        if let Some(semantic_tokens) = &mut self.semantic_tokens {
 4018            semantic_tokens.remove_server_data(for_server);
 4019        }
 4020
 4021        if let Some(folding_ranges) = &mut self.folding_ranges {
 4022            folding_ranges.ranges.remove(&for_server);
 4023        }
 4024
 4025        if let Some(document_symbols) = &mut self.document_symbols {
 4026            document_symbols.remove_server_data(for_server);
 4027        }
 4028    }
 4029
 4030    #[cfg(any(test, feature = "test-support"))]
 4031    pub fn inlay_hints(&self) -> &BufferInlayHints {
 4032        &self.inlay_hints
 4033    }
 4034}
 4035
 4036#[derive(Debug)]
 4037pub enum LspStoreEvent {
 4038    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 4039    LanguageServerRemoved(LanguageServerId),
 4040    LanguageServerUpdate {
 4041        language_server_id: LanguageServerId,
 4042        name: Option<LanguageServerName>,
 4043        message: proto::update_language_server::Variant,
 4044    },
 4045    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 4046    LanguageServerPrompt(LanguageServerPromptRequest),
 4047    LanguageDetected {
 4048        buffer: Entity<Buffer>,
 4049        new_language: Option<Arc<Language>>,
 4050    },
 4051    Notification(String),
 4052    RefreshInlayHints {
 4053        server_id: LanguageServerId,
 4054        request_id: Option<usize>,
 4055    },
 4056    RefreshSemanticTokens {
 4057        server_id: LanguageServerId,
 4058        request_id: Option<usize>,
 4059    },
 4060    RefreshCodeLens,
 4061    DiagnosticsUpdated {
 4062        server_id: LanguageServerId,
 4063        paths: Vec<ProjectPath>,
 4064    },
 4065    DiskBasedDiagnosticsStarted {
 4066        language_server_id: LanguageServerId,
 4067    },
 4068    DiskBasedDiagnosticsFinished {
 4069        language_server_id: LanguageServerId,
 4070    },
 4071    SnippetEdit {
 4072        buffer_id: BufferId,
 4073        edits: Vec<(lsp::Range, Snippet)>,
 4074        most_recent_edit: clock::Lamport,
 4075    },
 4076    WorkspaceEditApplied(ProjectTransaction),
 4077}
 4078
 4079#[derive(Clone, Debug, Serialize)]
 4080pub struct LanguageServerStatus {
 4081    pub name: LanguageServerName,
 4082    pub server_version: Option<SharedString>,
 4083    pub server_readable_version: Option<SharedString>,
 4084    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 4085    pub has_pending_diagnostic_updates: bool,
 4086    pub progress_tokens: HashSet<ProgressToken>,
 4087    pub worktree: Option<WorktreeId>,
 4088    pub binary: Option<LanguageServerBinary>,
 4089    pub configuration: Option<Value>,
 4090    pub workspace_folders: BTreeSet<Uri>,
 4091    pub process_id: Option<u32>,
 4092}
 4093
 4094#[derive(Clone, Debug)]
 4095struct CoreSymbol {
 4096    pub language_server_name: LanguageServerName,
 4097    pub source_worktree_id: WorktreeId,
 4098    pub source_language_server_id: LanguageServerId,
 4099    pub path: SymbolLocation,
 4100    pub name: String,
 4101    pub kind: lsp::SymbolKind,
 4102    pub range: Range<Unclipped<PointUtf16>>,
 4103    pub container_name: Option<String>,
 4104}
 4105
 4106#[derive(Clone, Debug, PartialEq, Eq)]
 4107pub enum SymbolLocation {
 4108    InProject(ProjectPath),
 4109    OutsideProject {
 4110        abs_path: Arc<Path>,
 4111        signature: [u8; 32],
 4112    },
 4113}
 4114
 4115impl SymbolLocation {
 4116    fn file_name(&self) -> Option<&str> {
 4117        match self {
 4118            Self::InProject(path) => path.path.file_name(),
 4119            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 4120        }
 4121    }
 4122}
 4123
 4124impl LspStore {
 4125    pub fn init(client: &AnyProtoClient) {
 4126        client.add_entity_request_handler(Self::handle_lsp_query);
 4127        client.add_entity_message_handler(Self::handle_lsp_query_response);
 4128        client.add_entity_request_handler(Self::handle_restart_language_servers);
 4129        client.add_entity_request_handler(Self::handle_stop_language_servers);
 4130        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 4131        client.add_entity_message_handler(Self::handle_start_language_server);
 4132        client.add_entity_message_handler(Self::handle_update_language_server);
 4133        client.add_entity_message_handler(Self::handle_language_server_log);
 4134        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 4135        client.add_entity_request_handler(Self::handle_format_buffers);
 4136        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 4137        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 4138        client.add_entity_request_handler(Self::handle_apply_code_action);
 4139        client.add_entity_request_handler(Self::handle_get_project_symbols);
 4140        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 4141        client.add_entity_request_handler(Self::handle_get_color_presentation);
 4142        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 4143        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 4144        client.add_entity_request_handler(Self::handle_refresh_semantic_tokens);
 4145        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 4146        client.add_entity_request_handler(Self::handle_on_type_formatting);
 4147        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 4148        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 4149        client.add_entity_request_handler(Self::handle_rename_project_entry);
 4150        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 4151        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 4152        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 4153        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 4154        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 4155        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 4156        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 4157
 4158        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 4159        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 4160        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 4161        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 4162        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 4163        client.add_entity_request_handler(
 4164            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 4165        );
 4166        client.add_entity_request_handler(
 4167            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 4168        );
 4169        client.add_entity_request_handler(
 4170            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 4171        );
 4172    }
 4173
 4174    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 4175        match &self.mode {
 4176            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 4177            _ => None,
 4178        }
 4179    }
 4180
 4181    pub fn as_local(&self) -> Option<&LocalLspStore> {
 4182        match &self.mode {
 4183            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4184            _ => None,
 4185        }
 4186    }
 4187
 4188    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 4189        match &mut self.mode {
 4190            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4191            _ => None,
 4192        }
 4193    }
 4194
 4195    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4196        match &self.mode {
 4197            LspStoreMode::Remote(RemoteLspStore {
 4198                upstream_client: Some(upstream_client),
 4199                upstream_project_id,
 4200                ..
 4201            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4202
 4203            LspStoreMode::Remote(RemoteLspStore {
 4204                upstream_client: None,
 4205                ..
 4206            }) => None,
 4207            LspStoreMode::Local(_) => None,
 4208        }
 4209    }
 4210
 4211    pub fn new_local(
 4212        buffer_store: Entity<BufferStore>,
 4213        worktree_store: Entity<WorktreeStore>,
 4214        prettier_store: Entity<PrettierStore>,
 4215        toolchain_store: Entity<LocalToolchainStore>,
 4216        environment: Entity<ProjectEnvironment>,
 4217        manifest_tree: Entity<ManifestTree>,
 4218        languages: Arc<LanguageRegistry>,
 4219        http_client: Arc<dyn HttpClient>,
 4220        fs: Arc<dyn Fs>,
 4221        cx: &mut Context<Self>,
 4222    ) -> Self {
 4223        let yarn = YarnPathStore::new(fs.clone(), cx);
 4224        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4225            .detach();
 4226        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4227            .detach();
 4228        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4229            .detach();
 4230        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4231            .detach();
 4232        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4233            .detach();
 4234        subscribe_to_binary_statuses(&languages, cx).detach();
 4235
 4236        let _maintain_workspace_config = {
 4237            let (sender, receiver) = watch::channel();
 4238            (Self::maintain_workspace_config(receiver, cx), sender)
 4239        };
 4240
 4241        Self {
 4242            mode: LspStoreMode::Local(LocalLspStore {
 4243                weak: cx.weak_entity(),
 4244                worktree_store: worktree_store.clone(),
 4245
 4246                supplementary_language_servers: Default::default(),
 4247                languages: languages.clone(),
 4248                language_server_ids: Default::default(),
 4249                language_servers: Default::default(),
 4250                last_workspace_edits_by_language_server: Default::default(),
 4251                language_server_watched_paths: Default::default(),
 4252                language_server_paths_watched_for_rename: Default::default(),
 4253                language_server_dynamic_registrations: Default::default(),
 4254                buffers_being_formatted: Default::default(),
 4255                buffers_to_refresh_hash_set: HashSet::default(),
 4256                buffers_to_refresh_queue: VecDeque::new(),
 4257                _background_diagnostics_worker: Task::ready(()).shared(),
 4258                buffer_snapshots: Default::default(),
 4259                prettier_store,
 4260                environment,
 4261                http_client,
 4262                fs,
 4263                yarn,
 4264                next_diagnostic_group_id: Default::default(),
 4265                diagnostics: Default::default(),
 4266                _subscription: cx.on_app_quit(|this, _| {
 4267                    this.as_local_mut()
 4268                        .unwrap()
 4269                        .shutdown_language_servers_on_quit()
 4270                }),
 4271                lsp_tree: LanguageServerTree::new(
 4272                    manifest_tree,
 4273                    languages.clone(),
 4274                    toolchain_store.clone(),
 4275                ),
 4276                toolchain_store,
 4277                registered_buffers: HashMap::default(),
 4278                buffers_opened_in_servers: HashMap::default(),
 4279                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4280                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4281                restricted_worktrees_tasks: HashMap::default(),
 4282                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4283                    .manifest_file_names(),
 4284            }),
 4285            last_formatting_failure: None,
 4286            downstream_client: None,
 4287            buffer_store,
 4288            worktree_store,
 4289            languages: languages.clone(),
 4290            language_server_statuses: Default::default(),
 4291            nonce: StdRng::from_os_rng().random(),
 4292            diagnostic_summaries: HashMap::default(),
 4293            lsp_server_capabilities: HashMap::default(),
 4294            semantic_token_config: SemanticTokenConfig::new(cx),
 4295            lsp_data: HashMap::default(),
 4296            buffer_reload_tasks: HashMap::default(),
 4297            next_hint_id: Arc::default(),
 4298            active_entry: None,
 4299            _maintain_workspace_config,
 4300            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4301        }
 4302    }
 4303
 4304    fn send_lsp_proto_request<R: LspCommand>(
 4305        &self,
 4306        buffer: Entity<Buffer>,
 4307        client: AnyProtoClient,
 4308        upstream_project_id: u64,
 4309        request: R,
 4310        cx: &mut Context<LspStore>,
 4311    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4312        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4313            return Task::ready(Ok(R::Response::default()));
 4314        }
 4315        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4316        cx.spawn(async move |this, cx| {
 4317            let response = client.request(message).await?;
 4318            let this = this.upgrade().context("project dropped")?;
 4319            request
 4320                .response_from_proto(response, this, buffer, cx.clone())
 4321                .await
 4322        })
 4323    }
 4324
 4325    pub(super) fn new_remote(
 4326        buffer_store: Entity<BufferStore>,
 4327        worktree_store: Entity<WorktreeStore>,
 4328        languages: Arc<LanguageRegistry>,
 4329        upstream_client: AnyProtoClient,
 4330        project_id: u64,
 4331        cx: &mut Context<Self>,
 4332    ) -> Self {
 4333        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4334            .detach();
 4335        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4336            .detach();
 4337        subscribe_to_binary_statuses(&languages, cx).detach();
 4338        let _maintain_workspace_config = {
 4339            let (sender, receiver) = watch::channel();
 4340            (Self::maintain_workspace_config(receiver, cx), sender)
 4341        };
 4342        Self {
 4343            mode: LspStoreMode::Remote(RemoteLspStore {
 4344                upstream_client: Some(upstream_client),
 4345                upstream_project_id: project_id,
 4346            }),
 4347            downstream_client: None,
 4348            last_formatting_failure: None,
 4349            buffer_store,
 4350            worktree_store,
 4351            languages: languages.clone(),
 4352            language_server_statuses: Default::default(),
 4353            nonce: StdRng::from_os_rng().random(),
 4354            diagnostic_summaries: HashMap::default(),
 4355            lsp_server_capabilities: HashMap::default(),
 4356            semantic_token_config: SemanticTokenConfig::new(cx),
 4357            next_hint_id: Arc::default(),
 4358            lsp_data: HashMap::default(),
 4359            buffer_reload_tasks: HashMap::default(),
 4360            active_entry: None,
 4361
 4362            _maintain_workspace_config,
 4363            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4364        }
 4365    }
 4366
 4367    fn on_buffer_store_event(
 4368        &mut self,
 4369        _: Entity<BufferStore>,
 4370        event: &BufferStoreEvent,
 4371        cx: &mut Context<Self>,
 4372    ) {
 4373        match event {
 4374            BufferStoreEvent::BufferAdded(buffer) => {
 4375                self.on_buffer_added(buffer, cx).log_err();
 4376            }
 4377            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4378                let buffer_id = buffer.read(cx).remote_id();
 4379                if let Some(local) = self.as_local_mut()
 4380                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4381                {
 4382                    local.reset_buffer(buffer, old_file, cx);
 4383
 4384                    if local.registered_buffers.contains_key(&buffer_id) {
 4385                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4386                    }
 4387                }
 4388
 4389                self.detect_language_for_buffer(buffer, cx);
 4390                if let Some(local) = self.as_local_mut() {
 4391                    local.initialize_buffer(buffer, cx);
 4392                    if local.registered_buffers.contains_key(&buffer_id) {
 4393                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4394                    }
 4395                }
 4396            }
 4397            _ => {}
 4398        }
 4399    }
 4400
 4401    fn on_worktree_store_event(
 4402        &mut self,
 4403        _: Entity<WorktreeStore>,
 4404        event: &WorktreeStoreEvent,
 4405        cx: &mut Context<Self>,
 4406    ) {
 4407        match event {
 4408            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4409                if !worktree.read(cx).is_local() {
 4410                    return;
 4411                }
 4412                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4413                    worktree::Event::UpdatedEntries(changes) => {
 4414                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4415                    }
 4416                    worktree::Event::UpdatedGitRepositories(_)
 4417                    | worktree::Event::DeletedEntry(_)
 4418                    | worktree::Event::Deleted
 4419                    | worktree::Event::UpdatedRootRepoCommonDir => {}
 4420                })
 4421                .detach()
 4422            }
 4423            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4424            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4425                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4426            }
 4427            WorktreeStoreEvent::WorktreeUpdatedEntries(worktree_id, changes) => {
 4428                self.invalidate_diagnostic_summaries_for_removed_entries(*worktree_id, changes, cx);
 4429            }
 4430            WorktreeStoreEvent::WorktreeReleased(..)
 4431            | WorktreeStoreEvent::WorktreeOrderChanged
 4432            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4433            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4434        }
 4435    }
 4436
 4437    fn on_prettier_store_event(
 4438        &mut self,
 4439        _: Entity<PrettierStore>,
 4440        event: &PrettierStoreEvent,
 4441        cx: &mut Context<Self>,
 4442    ) {
 4443        match event {
 4444            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4445                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4446            }
 4447            PrettierStoreEvent::LanguageServerAdded {
 4448                new_server_id,
 4449                name,
 4450                prettier_server,
 4451            } => {
 4452                self.register_supplementary_language_server(
 4453                    *new_server_id,
 4454                    name.clone(),
 4455                    prettier_server.clone(),
 4456                    cx,
 4457                );
 4458            }
 4459        }
 4460    }
 4461
 4462    fn on_toolchain_store_event(
 4463        &mut self,
 4464        _: Entity<LocalToolchainStore>,
 4465        event: &ToolchainStoreEvent,
 4466        _: &mut Context<Self>,
 4467    ) {
 4468        if let ToolchainStoreEvent::ToolchainActivated = event {
 4469            self.request_workspace_config_refresh()
 4470        }
 4471    }
 4472
 4473    fn request_workspace_config_refresh(&mut self) {
 4474        *self._maintain_workspace_config.1.borrow_mut() = ();
 4475    }
 4476
 4477    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4478        self.as_local().map(|local| local.prettier_store.clone())
 4479    }
 4480
 4481    fn on_buffer_event(
 4482        &mut self,
 4483        buffer: Entity<Buffer>,
 4484        event: &language::BufferEvent,
 4485        cx: &mut Context<Self>,
 4486    ) {
 4487        match event {
 4488            language::BufferEvent::Edited { .. } => {
 4489                self.on_buffer_edited(buffer, cx);
 4490            }
 4491
 4492            language::BufferEvent::Saved => {
 4493                self.on_buffer_saved(buffer, cx);
 4494            }
 4495
 4496            language::BufferEvent::Reloaded => {
 4497                self.on_buffer_reloaded(buffer, cx);
 4498            }
 4499
 4500            _ => {}
 4501        }
 4502    }
 4503
 4504    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4505        buffer
 4506            .read(cx)
 4507            .set_language_registry(self.languages.clone());
 4508
 4509        cx.subscribe(buffer, |this, buffer, event, cx| {
 4510            this.on_buffer_event(buffer, event, cx);
 4511        })
 4512        .detach();
 4513
 4514        self.parse_modeline(buffer, cx);
 4515        self.detect_language_for_buffer(buffer, cx);
 4516        if let Some(local) = self.as_local_mut() {
 4517            local.initialize_buffer(buffer, cx);
 4518        }
 4519
 4520        Ok(())
 4521    }
 4522
 4523    pub fn refresh_background_diagnostics_for_buffers(
 4524        &mut self,
 4525        buffers: HashSet<BufferId>,
 4526        cx: &mut Context<Self>,
 4527    ) -> Shared<Task<()>> {
 4528        let Some(local) = self.as_local_mut() else {
 4529            return Task::ready(()).shared();
 4530        };
 4531        for buffer in buffers {
 4532            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4533                local.buffers_to_refresh_queue.push_back(buffer);
 4534                if local.buffers_to_refresh_queue.len() == 1 {
 4535                    local._background_diagnostics_worker =
 4536                        Self::background_diagnostics_worker(cx).shared();
 4537                }
 4538            }
 4539        }
 4540
 4541        local._background_diagnostics_worker.clone()
 4542    }
 4543
 4544    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4545        let buffer_store = self.buffer_store.clone();
 4546        let local = self.as_local_mut()?;
 4547        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4548            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4549            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4550                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4551            }
 4552        }
 4553        None
 4554    }
 4555
 4556    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4557        cx.spawn(async move |this, cx| {
 4558            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4559                task.await.log_err();
 4560            }
 4561        })
 4562    }
 4563
 4564    fn on_buffer_reloaded(&mut self, buffer: Entity<Buffer>, cx: &mut Context<Self>) {
 4565        if self.parse_modeline(&buffer, cx) {
 4566            self.detect_language_for_buffer(&buffer, cx);
 4567        }
 4568
 4569        let buffer_id = buffer.read(cx).remote_id();
 4570        let task = self.pull_diagnostics_for_buffer(buffer, cx);
 4571        self.buffer_reload_tasks.insert(buffer_id, task);
 4572    }
 4573
 4574    pub(crate) fn register_buffer_with_language_servers(
 4575        &mut self,
 4576        buffer: &Entity<Buffer>,
 4577        only_register_servers: HashSet<LanguageServerSelector>,
 4578        ignore_refcounts: bool,
 4579        cx: &mut Context<Self>,
 4580    ) -> OpenLspBufferHandle {
 4581        let buffer_id = buffer.read(cx).remote_id();
 4582        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4583        if let Some(local) = self.as_local_mut() {
 4584            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4585            if !ignore_refcounts {
 4586                *refcount += 1;
 4587            }
 4588
 4589            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4590            // 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
 4591            // 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
 4592            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4593            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4594                return handle;
 4595            };
 4596            if !file.is_local() {
 4597                return handle;
 4598            }
 4599
 4600            if ignore_refcounts || *refcount == 1 {
 4601                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4602            }
 4603            if !ignore_refcounts {
 4604                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4605                    let refcount = {
 4606                        let local = lsp_store.as_local_mut().unwrap();
 4607                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4608                            debug_panic!("bad refcounting");
 4609                            return;
 4610                        };
 4611
 4612                        *refcount -= 1;
 4613                        *refcount
 4614                    };
 4615                    if refcount == 0 {
 4616                        lsp_store.lsp_data.remove(&buffer_id);
 4617                        lsp_store.buffer_reload_tasks.remove(&buffer_id);
 4618                        let local = lsp_store.as_local_mut().unwrap();
 4619                        local.registered_buffers.remove(&buffer_id);
 4620
 4621                        local.buffers_opened_in_servers.remove(&buffer_id);
 4622                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4623                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4624
 4625                            let buffer_abs_path = file.abs_path(cx);
 4626                            for (_, buffer_pull_diagnostics_result_ids) in
 4627                                &mut local.buffer_pull_diagnostics_result_ids
 4628                            {
 4629                                buffer_pull_diagnostics_result_ids.retain(
 4630                                    |_, buffer_result_ids| {
 4631                                        buffer_result_ids.remove(&buffer_abs_path);
 4632                                        !buffer_result_ids.is_empty()
 4633                                    },
 4634                                );
 4635                            }
 4636
 4637                            let diagnostic_updates = local
 4638                                .language_servers
 4639                                .keys()
 4640                                .cloned()
 4641                                .map(|server_id| DocumentDiagnosticsUpdate {
 4642                                    diagnostics: DocumentDiagnostics {
 4643                                        document_abs_path: buffer_abs_path.clone(),
 4644                                        version: None,
 4645                                        diagnostics: Vec::new(),
 4646                                    },
 4647                                    result_id: None,
 4648                                    registration_id: None,
 4649                                    server_id,
 4650                                    disk_based_sources: Cow::Borrowed(&[]),
 4651                                })
 4652                                .collect::<Vec<_>>();
 4653
 4654                            lsp_store
 4655                                .merge_diagnostic_entries(
 4656                                    diagnostic_updates,
 4657                                    |_, diagnostic, _| {
 4658                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4659                                    },
 4660                                    cx,
 4661                                )
 4662                                .context("Clearing diagnostics for the closed buffer")
 4663                                .log_err();
 4664                        }
 4665                    }
 4666                })
 4667                .detach();
 4668            }
 4669        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4670            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4671            cx.background_spawn(async move {
 4672                upstream_client
 4673                    .request(proto::RegisterBufferWithLanguageServers {
 4674                        project_id: upstream_project_id,
 4675                        buffer_id,
 4676                        only_servers: only_register_servers
 4677                            .into_iter()
 4678                            .map(|selector| {
 4679                                let selector = match selector {
 4680                                    LanguageServerSelector::Id(language_server_id) => {
 4681                                        proto::language_server_selector::Selector::ServerId(
 4682                                            language_server_id.to_proto(),
 4683                                        )
 4684                                    }
 4685                                    LanguageServerSelector::Name(language_server_name) => {
 4686                                        proto::language_server_selector::Selector::Name(
 4687                                            language_server_name.to_string(),
 4688                                        )
 4689                                    }
 4690                                };
 4691                                proto::LanguageServerSelector {
 4692                                    selector: Some(selector),
 4693                                }
 4694                            })
 4695                            .collect(),
 4696                    })
 4697                    .await
 4698            })
 4699            .detach();
 4700        } else {
 4701            // Our remote connection got closed
 4702        }
 4703        handle
 4704    }
 4705
 4706    fn maintain_buffer_languages(
 4707        languages: Arc<LanguageRegistry>,
 4708        cx: &mut Context<Self>,
 4709    ) -> Task<()> {
 4710        let mut subscription = languages.subscribe();
 4711        let mut prev_reload_count = languages.reload_count();
 4712        cx.spawn(async move |this, cx| {
 4713            while let Some(()) = subscription.next().await {
 4714                if let Some(this) = this.upgrade() {
 4715                    // If the language registry has been reloaded, then remove and
 4716                    // re-assign the languages on all open buffers.
 4717                    let reload_count = languages.reload_count();
 4718                    if reload_count > prev_reload_count {
 4719                        prev_reload_count = reload_count;
 4720                        this.update(cx, |this, cx| {
 4721                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4722                                for buffer in buffer_store.buffers() {
 4723                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4724                                    {
 4725                                        buffer.update(cx, |buffer, cx| {
 4726                                            buffer.set_language_async(None, cx)
 4727                                        });
 4728                                        if let Some(local) = this.as_local_mut() {
 4729                                            local.reset_buffer(&buffer, &f, cx);
 4730
 4731                                            if local
 4732                                                .registered_buffers
 4733                                                .contains_key(&buffer.read(cx).remote_id())
 4734                                                && let Some(file_url) =
 4735                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4736                                            {
 4737                                                local.unregister_buffer_from_language_servers(
 4738                                                    &buffer, &file_url, cx,
 4739                                                );
 4740                                            }
 4741                                        }
 4742                                    }
 4743                                }
 4744                            });
 4745                        });
 4746                    }
 4747
 4748                    this.update(cx, |this, cx| {
 4749                        let mut plain_text_buffers = Vec::new();
 4750                        let mut buffers_with_unknown_injections = Vec::new();
 4751                        for handle in this.buffer_store.read(cx).buffers() {
 4752                            let buffer = handle.read(cx);
 4753                            if buffer.language().is_none()
 4754                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4755                            {
 4756                                plain_text_buffers.push(handle);
 4757                            } else if buffer.contains_unknown_injections() {
 4758                                buffers_with_unknown_injections.push(handle);
 4759                            }
 4760                        }
 4761
 4762                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4763                        // and reused later in the invisible worktrees.
 4764                        plain_text_buffers.sort_by_key(|buffer| {
 4765                            Reverse(
 4766                                File::from_dyn(buffer.read(cx).file())
 4767                                    .map(|file| file.worktree.read(cx).is_visible()),
 4768                            )
 4769                        });
 4770
 4771                        for buffer in plain_text_buffers {
 4772                            this.detect_language_for_buffer(&buffer, cx);
 4773                            if let Some(local) = this.as_local_mut() {
 4774                                local.initialize_buffer(&buffer, cx);
 4775                                if local
 4776                                    .registered_buffers
 4777                                    .contains_key(&buffer.read(cx).remote_id())
 4778                                {
 4779                                    local.register_buffer_with_language_servers(
 4780                                        &buffer,
 4781                                        HashSet::default(),
 4782                                        cx,
 4783                                    );
 4784                                }
 4785                            }
 4786                        }
 4787
 4788                        for buffer in buffers_with_unknown_injections {
 4789                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4790                        }
 4791                    });
 4792                }
 4793            }
 4794        })
 4795    }
 4796
 4797    fn parse_modeline(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<Self>) -> bool {
 4798        let buffer = buffer_handle.read(cx);
 4799        let content = buffer.as_rope();
 4800
 4801        let modeline_settings = {
 4802            let settings_store = cx.global::<SettingsStore>();
 4803            let modeline_lines = settings_store
 4804                .raw_user_settings()
 4805                .and_then(|s| s.content.modeline_lines)
 4806                .or(settings_store.raw_default_settings().modeline_lines)
 4807                .unwrap_or(5);
 4808
 4809            const MAX_MODELINE_BYTES: usize = 1024;
 4810
 4811            let first_bytes =
 4812                content.clip_offset(content.len().min(MAX_MODELINE_BYTES), Bias::Left);
 4813            let mut first_lines = Vec::new();
 4814            let mut lines = content.chunks_in_range(0..first_bytes).lines();
 4815            for _ in 0..modeline_lines {
 4816                if let Some(line) = lines.next() {
 4817                    first_lines.push(line.to_string());
 4818                } else {
 4819                    break;
 4820                }
 4821            }
 4822            let first_lines_ref: Vec<_> = first_lines.iter().map(|line| line.as_str()).collect();
 4823
 4824            let last_start =
 4825                content.clip_offset(content.len().saturating_sub(MAX_MODELINE_BYTES), Bias::Left);
 4826            let mut last_lines = Vec::new();
 4827            let mut lines = content
 4828                .reversed_chunks_in_range(last_start..content.len())
 4829                .lines();
 4830            for _ in 0..modeline_lines {
 4831                if let Some(line) = lines.next() {
 4832                    last_lines.push(line.to_string());
 4833                } else {
 4834                    break;
 4835                }
 4836            }
 4837            let last_lines_ref: Vec<_> =
 4838                last_lines.iter().rev().map(|line| line.as_str()).collect();
 4839            modeline::parse_modeline(&first_lines_ref, &last_lines_ref)
 4840        };
 4841
 4842        log::debug!("Parsed modeline settings: {:?}", modeline_settings);
 4843
 4844        buffer_handle.update(cx, |buffer, _cx| buffer.set_modeline(modeline_settings))
 4845    }
 4846
 4847    fn detect_language_for_buffer(
 4848        &mut self,
 4849        buffer_handle: &Entity<Buffer>,
 4850        cx: &mut Context<Self>,
 4851    ) -> Option<language::AvailableLanguage> {
 4852        // If the buffer has a language, set it and start the language server if we haven't already.
 4853        let buffer = buffer_handle.read(cx);
 4854        let file = buffer.file()?;
 4855        let content = buffer.as_rope();
 4856        let modeline_settings = buffer.modeline().map(Arc::as_ref);
 4857
 4858        let available_language = if let Some(ModelineSettings {
 4859            mode: Some(mode_name),
 4860            ..
 4861        }) = modeline_settings
 4862        {
 4863            self.languages
 4864                .available_language_for_modeline_name(mode_name)
 4865        } else {
 4866            self.languages.language_for_file(file, Some(content), cx)
 4867        };
 4868        if let Some(available_language) = &available_language {
 4869            if let Some(Ok(Ok(new_language))) = self
 4870                .languages
 4871                .load_language(available_language)
 4872                .now_or_never()
 4873            {
 4874                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4875            }
 4876        } else {
 4877            cx.emit(LspStoreEvent::LanguageDetected {
 4878                buffer: buffer_handle.clone(),
 4879                new_language: None,
 4880            });
 4881        }
 4882
 4883        available_language
 4884    }
 4885
 4886    pub(crate) fn set_language_for_buffer(
 4887        &mut self,
 4888        buffer_entity: &Entity<Buffer>,
 4889        new_language: Arc<Language>,
 4890        cx: &mut Context<Self>,
 4891    ) {
 4892        let buffer = buffer_entity.read(cx);
 4893        let buffer_file = buffer.file().cloned();
 4894        let buffer_id = buffer.remote_id();
 4895        if let Some(local_store) = self.as_local_mut()
 4896            && local_store.registered_buffers.contains_key(&buffer_id)
 4897            && let Some(abs_path) =
 4898                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4899            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4900        {
 4901            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4902        }
 4903        buffer_entity.update(cx, |buffer, cx| {
 4904            if buffer
 4905                .language()
 4906                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4907            {
 4908                buffer.set_language_async(Some(new_language.clone()), cx);
 4909            }
 4910        });
 4911
 4912        let settings = LanguageSettings::resolve(
 4913            Some(&buffer_entity.read(cx)),
 4914            Some(&new_language.name()),
 4915            cx,
 4916        )
 4917        .into_owned();
 4918        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4919
 4920        let worktree_id = if let Some(file) = buffer_file {
 4921            let worktree = file.worktree.clone();
 4922
 4923            if let Some(local) = self.as_local_mut()
 4924                && local.registered_buffers.contains_key(&buffer_id)
 4925            {
 4926                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4927            }
 4928            Some(worktree.read(cx).id())
 4929        } else {
 4930            None
 4931        };
 4932
 4933        if settings.prettier.allowed
 4934            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4935        {
 4936            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4937            if let Some(prettier_store) = prettier_store {
 4938                prettier_store.update(cx, |prettier_store, cx| {
 4939                    prettier_store.install_default_prettier(
 4940                        worktree_id,
 4941                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4942                        cx,
 4943                    )
 4944                })
 4945            }
 4946        }
 4947
 4948        cx.emit(LspStoreEvent::LanguageDetected {
 4949            buffer: buffer_entity.clone(),
 4950            new_language: Some(new_language),
 4951        })
 4952    }
 4953
 4954    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4955        self.buffer_store.clone()
 4956    }
 4957
 4958    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4959        self.active_entry = active_entry;
 4960    }
 4961
 4962    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4963        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4964            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4965        {
 4966            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4967                summaries
 4968                    .iter()
 4969                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4970            });
 4971            if let Some(summary) = summaries.next() {
 4972                client
 4973                    .send(proto::UpdateDiagnosticSummary {
 4974                        project_id: downstream_project_id,
 4975                        worktree_id: worktree.id().to_proto(),
 4976                        summary: Some(summary),
 4977                        more_summaries: summaries.collect(),
 4978                    })
 4979                    .log_err();
 4980            }
 4981        }
 4982    }
 4983
 4984    fn is_capable_for_proto_request<R>(
 4985        &self,
 4986        buffer: &Entity<Buffer>,
 4987        request: &R,
 4988        cx: &App,
 4989    ) -> bool
 4990    where
 4991        R: LspCommand,
 4992    {
 4993        self.check_if_capable_for_proto_request(
 4994            buffer,
 4995            |capabilities| {
 4996                request.check_capabilities(AdapterServerCapabilities {
 4997                    server_capabilities: capabilities.clone(),
 4998                    code_action_kinds: None,
 4999                })
 5000            },
 5001            cx,
 5002        )
 5003    }
 5004
 5005    fn check_if_capable_for_proto_request<F>(
 5006        &self,
 5007        buffer: &Entity<Buffer>,
 5008        check: F,
 5009        cx: &App,
 5010    ) -> bool
 5011    where
 5012        F: FnMut(&lsp::ServerCapabilities) -> bool,
 5013    {
 5014        let Some(language) = buffer.read(cx).language().cloned() else {
 5015            return false;
 5016        };
 5017        let registered_language_servers = self
 5018            .languages
 5019            .lsp_adapters(&language.name())
 5020            .into_iter()
 5021            .map(|lsp_adapter| lsp_adapter.name())
 5022            .collect::<HashSet<_>>();
 5023        self.language_server_statuses
 5024            .iter()
 5025            .filter_map(|(server_id, server_status)| {
 5026                // Include servers that are either registered for this language OR
 5027                // available to be loaded (for SSH remote mode where adapters like
 5028                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 5029                // but only loaded on the server side)
 5030                let is_relevant = registered_language_servers.contains(&server_status.name)
 5031                    || self.languages.is_lsp_adapter_available(&server_status.name);
 5032                is_relevant.then_some(server_id)
 5033            })
 5034            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 5035            .any(check)
 5036    }
 5037
 5038    fn all_capable_for_proto_request<F>(
 5039        &self,
 5040        buffer: &Entity<Buffer>,
 5041        mut check: F,
 5042        cx: &App,
 5043    ) -> Vec<(lsp::LanguageServerId, lsp::LanguageServerName)>
 5044    where
 5045        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 5046    {
 5047        let Some(language) = buffer.read(cx).language().cloned() else {
 5048            return Vec::default();
 5049        };
 5050        let registered_language_servers = self
 5051            .languages
 5052            .lsp_adapters(&language.name())
 5053            .into_iter()
 5054            .map(|lsp_adapter| lsp_adapter.name())
 5055            .collect::<HashSet<_>>();
 5056        self.language_server_statuses
 5057            .iter()
 5058            .filter_map(|(server_id, server_status)| {
 5059                // Include servers that are either registered for this language OR
 5060                // available to be loaded (for SSH remote mode where adapters like
 5061                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 5062                // but only loaded on the server side)
 5063                let is_relevant = registered_language_servers.contains(&server_status.name)
 5064                    || self.languages.is_lsp_adapter_available(&server_status.name);
 5065                is_relevant.then_some((server_id, &server_status.name))
 5066            })
 5067            .filter_map(|(server_id, server_name)| {
 5068                self.lsp_server_capabilities
 5069                    .get(server_id)
 5070                    .map(|c| (server_id, server_name, c))
 5071            })
 5072            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 5073            .map(|(server_id, server_name, _)| (*server_id, server_name.clone()))
 5074            .collect()
 5075    }
 5076
 5077    pub fn request_lsp<R>(
 5078        &mut self,
 5079        buffer: Entity<Buffer>,
 5080        server: LanguageServerToQuery,
 5081        request: R,
 5082        cx: &mut Context<Self>,
 5083    ) -> Task<Result<R::Response>>
 5084    where
 5085        R: LspCommand,
 5086        <R::LspRequest as lsp::request::Request>::Result: Send,
 5087        <R::LspRequest as lsp::request::Request>::Params: Send,
 5088    {
 5089        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 5090            return self.send_lsp_proto_request(
 5091                buffer,
 5092                upstream_client,
 5093                upstream_project_id,
 5094                request,
 5095                cx,
 5096            );
 5097        }
 5098
 5099        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 5100            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 5101                local
 5102                    .language_servers_for_buffer(buffer, cx)
 5103                    .find(|(_, server)| {
 5104                        request.check_capabilities(server.adapter_server_capabilities())
 5105                    })
 5106                    .map(|(_, server)| server.clone())
 5107            }),
 5108            LanguageServerToQuery::Other(id) => self
 5109                .language_server_for_local_buffer(buffer, id, cx)
 5110                .and_then(|(_, server)| {
 5111                    request
 5112                        .check_capabilities(server.adapter_server_capabilities())
 5113                        .then(|| Arc::clone(server))
 5114                }),
 5115        }) else {
 5116            return Task::ready(Ok(Default::default()));
 5117        };
 5118
 5119        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 5120
 5121        let Some(file) = file else {
 5122            return Task::ready(Ok(Default::default()));
 5123        };
 5124
 5125        let lsp_params = match request.to_lsp_params_or_response(
 5126            &file.abs_path(cx),
 5127            buffer.read(cx),
 5128            &language_server,
 5129            cx,
 5130        ) {
 5131            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 5132            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 5133            Err(err) => {
 5134                let message = format!(
 5135                    "{} via {} failed: {}",
 5136                    request.display_name(),
 5137                    language_server.name(),
 5138                    err
 5139                );
 5140                // rust-analyzer likes to error with this when its still loading up
 5141                if !message.ends_with("content modified") {
 5142                    log::warn!("{message}");
 5143                }
 5144                return Task::ready(Err(anyhow!(message)));
 5145            }
 5146        };
 5147
 5148        let status = request.status();
 5149        let request_timeout = ProjectSettings::get_global(cx)
 5150            .global_lsp_settings
 5151            .get_request_timeout();
 5152
 5153        cx.spawn(async move |this, cx| {
 5154            let lsp_request = language_server.request::<R::LspRequest>(lsp_params, request_timeout);
 5155
 5156            let id = lsp_request.id();
 5157            let _cleanup = if status.is_some() {
 5158                cx.update(|cx| {
 5159                    this.update(cx, |this, cx| {
 5160                        this.on_lsp_work_start(
 5161                            language_server.server_id(),
 5162                            ProgressToken::Number(id),
 5163                            LanguageServerProgress {
 5164                                is_disk_based_diagnostics_progress: false,
 5165                                is_cancellable: false,
 5166                                title: None,
 5167                                message: status.clone(),
 5168                                percentage: None,
 5169                                last_update_at: cx.background_executor().now(),
 5170                            },
 5171                            cx,
 5172                        );
 5173                    })
 5174                })
 5175                .log_err();
 5176
 5177                Some(defer(|| {
 5178                    cx.update(|cx| {
 5179                        this.update(cx, |this, cx| {
 5180                            this.on_lsp_work_end(
 5181                                language_server.server_id(),
 5182                                ProgressToken::Number(id),
 5183                                cx,
 5184                            );
 5185                        })
 5186                    })
 5187                    .log_err();
 5188                }))
 5189            } else {
 5190                None
 5191            };
 5192
 5193            let result = lsp_request.await.into_response();
 5194
 5195            let response = result.map_err(|err| {
 5196                let message = format!(
 5197                    "{} via {} failed: {}",
 5198                    request.display_name(),
 5199                    language_server.name(),
 5200                    err
 5201                );
 5202                // rust-analyzer likes to error with this when its still loading up
 5203                if !message.ends_with("content modified") {
 5204                    log::warn!("{message}");
 5205                }
 5206                anyhow::anyhow!(message)
 5207            })?;
 5208
 5209            request
 5210                .response_from_lsp(
 5211                    response,
 5212                    this.upgrade().context("no app context")?,
 5213                    buffer,
 5214                    language_server.server_id(),
 5215                    cx.clone(),
 5216                )
 5217                .await
 5218        })
 5219    }
 5220
 5221    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 5222        let mut language_formatters_to_check = Vec::new();
 5223        for buffer in self.buffer_store.read(cx).buffers() {
 5224            let buffer = buffer.read(cx);
 5225            let settings = LanguageSettings::for_buffer(buffer, cx);
 5226            if buffer.language().is_some() {
 5227                let buffer_file = File::from_dyn(buffer.file());
 5228                language_formatters_to_check.push((
 5229                    buffer_file.map(|f| f.worktree_id(cx)),
 5230                    settings.into_owned(),
 5231                ));
 5232            }
 5233        }
 5234
 5235        self.request_workspace_config_refresh();
 5236
 5237        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 5238            prettier_store.update(cx, |prettier_store, cx| {
 5239                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 5240            })
 5241        }
 5242
 5243        let new_semantic_token_rules = crate::project_settings::ProjectSettings::get_global(cx)
 5244            .global_lsp_settings
 5245            .semantic_token_rules
 5246            .clone();
 5247        self.semantic_token_config
 5248            .update_rules(new_semantic_token_rules);
 5249        // Always clear cached stylizers so that changes to language-specific
 5250        // semantic token rules (e.g. from extension install/uninstall) are
 5251        // picked up. Stylizers are recreated lazily, so this is cheap.
 5252        self.semantic_token_config.clear_stylizers();
 5253
 5254        let new_global_semantic_tokens_mode =
 5255            all_language_settings(None, cx).defaults.semantic_tokens;
 5256        if self
 5257            .semantic_token_config
 5258            .update_global_mode(new_global_semantic_tokens_mode)
 5259        {
 5260            self.restart_all_language_servers(cx);
 5261        }
 5262
 5263        cx.notify();
 5264    }
 5265
 5266    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 5267        let buffer_store = self.buffer_store.clone();
 5268        let Some(local) = self.as_local_mut() else {
 5269            return;
 5270        };
 5271        let mut adapters = BTreeMap::default();
 5272        let get_adapter = {
 5273            let languages = local.languages.clone();
 5274            let environment = local.environment.clone();
 5275            let weak = local.weak.clone();
 5276            let worktree_store = local.worktree_store.clone();
 5277            let http_client = local.http_client.clone();
 5278            let fs = local.fs.clone();
 5279            move |worktree_id, cx: &mut App| {
 5280                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 5281                Some(LocalLspAdapterDelegate::new(
 5282                    languages.clone(),
 5283                    &environment,
 5284                    weak.clone(),
 5285                    &worktree,
 5286                    http_client.clone(),
 5287                    fs.clone(),
 5288                    cx,
 5289                ))
 5290            }
 5291        };
 5292
 5293        let mut messages_to_report = Vec::new();
 5294        let (new_tree, to_stop) = {
 5295            let mut rebase = local.lsp_tree.rebase();
 5296            let buffers = buffer_store
 5297                .read(cx)
 5298                .buffers()
 5299                .filter_map(|buffer| {
 5300                    let raw_buffer = buffer.read(cx);
 5301                    if !local
 5302                        .registered_buffers
 5303                        .contains_key(&raw_buffer.remote_id())
 5304                    {
 5305                        return None;
 5306                    }
 5307                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5308                    let language = raw_buffer.language().cloned()?;
 5309                    Some((file, language, raw_buffer.remote_id()))
 5310                })
 5311                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5312            for (file, language, buffer_id) in buffers {
 5313                let worktree_id = file.worktree_id(cx);
 5314                let Some(worktree) = local
 5315                    .worktree_store
 5316                    .read(cx)
 5317                    .worktree_for_id(worktree_id, cx)
 5318                else {
 5319                    continue;
 5320                };
 5321
 5322                if let Some((_, apply)) = local.reuse_existing_language_server(
 5323                    rebase.server_tree(),
 5324                    &worktree,
 5325                    &language.name(),
 5326                    cx,
 5327                ) {
 5328                    (apply)(rebase.server_tree());
 5329                } else if let Some(lsp_delegate) = adapters
 5330                    .entry(worktree_id)
 5331                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5332                    .clone()
 5333                {
 5334                    let delegate =
 5335                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5336                    let path = file
 5337                        .path()
 5338                        .parent()
 5339                        .map(Arc::from)
 5340                        .unwrap_or_else(|| file.path().clone());
 5341                    let worktree_path = ProjectPath { worktree_id, path };
 5342                    let abs_path = file.abs_path(cx);
 5343                    let nodes = rebase
 5344                        .walk(
 5345                            worktree_path,
 5346                            language.name(),
 5347                            language.manifest(),
 5348                            delegate.clone(),
 5349                            cx,
 5350                        )
 5351                        .collect::<Vec<_>>();
 5352                    for node in nodes {
 5353                        let server_id = node.server_id_or_init(|disposition| {
 5354                            let path = &disposition.path;
 5355                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5356                            let key = LanguageServerSeed {
 5357                                worktree_id,
 5358                                name: disposition.server_name.clone(),
 5359                                settings: LanguageServerSeedSettings {
 5360                                    binary: disposition.settings.binary.clone(),
 5361                                    initialization_options: disposition
 5362                                        .settings
 5363                                        .initialization_options
 5364                                        .clone(),
 5365                                },
 5366                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5367                                    path.worktree_id,
 5368                                    &path.path,
 5369                                    language.name(),
 5370                                ),
 5371                            };
 5372                            local.language_server_ids.remove(&key);
 5373
 5374                            let server_id = local.get_or_insert_language_server(
 5375                                &worktree,
 5376                                lsp_delegate.clone(),
 5377                                disposition,
 5378                                &language.name(),
 5379                                cx,
 5380                            );
 5381                            if let Some(state) = local.language_servers.get(&server_id)
 5382                                && let Ok(uri) = uri
 5383                            {
 5384                                state.add_workspace_folder(uri);
 5385                            };
 5386                            server_id
 5387                        });
 5388
 5389                        if let Some(language_server_id) = server_id {
 5390                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5391                                language_server_id,
 5392                                name: node.name(),
 5393                                message:
 5394                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5395                                        proto::RegisteredForBuffer {
 5396                                            buffer_abs_path: abs_path
 5397                                                .to_string_lossy()
 5398                                                .into_owned(),
 5399                                            buffer_id: buffer_id.to_proto(),
 5400                                        },
 5401                                    ),
 5402                            });
 5403                        }
 5404                    }
 5405                } else {
 5406                    continue;
 5407                }
 5408            }
 5409            rebase.finish()
 5410        };
 5411        for message in messages_to_report {
 5412            cx.emit(message);
 5413        }
 5414        local.lsp_tree = new_tree;
 5415        for (id, _) in to_stop {
 5416            self.stop_local_language_server(id, cx).detach();
 5417        }
 5418    }
 5419
 5420    pub fn apply_code_action(
 5421        &self,
 5422        buffer_handle: Entity<Buffer>,
 5423        mut action: CodeAction,
 5424        push_to_history: bool,
 5425        cx: &mut Context<Self>,
 5426    ) -> Task<Result<ProjectTransaction>> {
 5427        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5428            let request = proto::ApplyCodeAction {
 5429                project_id,
 5430                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5431                action: Some(Self::serialize_code_action(&action)),
 5432            };
 5433            let buffer_store = self.buffer_store();
 5434            cx.spawn(async move |_, cx| {
 5435                let response = upstream_client
 5436                    .request(request)
 5437                    .await?
 5438                    .transaction
 5439                    .context("missing transaction")?;
 5440
 5441                buffer_store
 5442                    .update(cx, |buffer_store, cx| {
 5443                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5444                    })
 5445                    .await
 5446            })
 5447        } else if self.mode.is_local() {
 5448            let Some((_, lang_server, request_timeout)) = buffer_handle.update(cx, |buffer, cx| {
 5449                let request_timeout = ProjectSettings::get_global(cx)
 5450                    .global_lsp_settings
 5451                    .get_request_timeout();
 5452                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5453                    .map(|(adapter, server)| (adapter.clone(), server.clone(), request_timeout))
 5454            }) else {
 5455                return Task::ready(Ok(ProjectTransaction::default()));
 5456            };
 5457
 5458            cx.spawn(async move |this, cx| {
 5459                LocalLspStore::try_resolve_code_action(&lang_server, &mut action, request_timeout)
 5460                    .await
 5461                    .context("resolving a code action")?;
 5462                if let Some(edit) = action.lsp_action.edit()
 5463                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5464                        return LocalLspStore::deserialize_workspace_edit(
 5465                            this.upgrade().context("no app present")?,
 5466                            edit.clone(),
 5467                            push_to_history,
 5468
 5469                            lang_server.clone(),
 5470                            cx,
 5471                        )
 5472                        .await;
 5473                    }
 5474
 5475                let Some(command) = action.lsp_action.command() else {
 5476                    return Ok(ProjectTransaction::default())
 5477                };
 5478
 5479                let server_capabilities = lang_server.capabilities();
 5480                let available_commands = server_capabilities
 5481                    .execute_command_provider
 5482                    .as_ref()
 5483                    .map(|options| options.commands.as_slice())
 5484                    .unwrap_or_default();
 5485
 5486                if !available_commands.contains(&command.command) {
 5487                    log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5488                    return Ok(ProjectTransaction::default())
 5489                }
 5490
 5491                let request_timeout = cx.update(|app|
 5492                    ProjectSettings::get_global(app)
 5493                    .global_lsp_settings
 5494                    .get_request_timeout()
 5495                );
 5496
 5497                this.update(cx, |this, _| {
 5498                    this.as_local_mut()
 5499                        .unwrap()
 5500                        .last_workspace_edits_by_language_server
 5501                        .remove(&lang_server.server_id());
 5502                })?;
 5503
 5504                let _result = lang_server
 5505                    .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5506                        command: command.command.clone(),
 5507                        arguments: command.arguments.clone().unwrap_or_default(),
 5508                        ..lsp::ExecuteCommandParams::default()
 5509                    }, request_timeout)
 5510                    .await.into_response()
 5511                    .context("execute command")?;
 5512
 5513                return this.update(cx, |this, _| {
 5514                    this.as_local_mut()
 5515                        .unwrap()
 5516                        .last_workspace_edits_by_language_server
 5517                        .remove(&lang_server.server_id())
 5518                        .unwrap_or_default()
 5519                });
 5520            })
 5521        } else {
 5522            Task::ready(Err(anyhow!("no upstream client and not local")))
 5523        }
 5524    }
 5525
 5526    pub fn apply_code_action_kind(
 5527        &mut self,
 5528        buffers: HashSet<Entity<Buffer>>,
 5529        kind: CodeActionKind,
 5530        push_to_history: bool,
 5531        cx: &mut Context<Self>,
 5532    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5533        if self.as_local().is_some() {
 5534            cx.spawn(async move |lsp_store, cx| {
 5535                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5536                let result = LocalLspStore::execute_code_action_kind_locally(
 5537                    lsp_store.clone(),
 5538                    buffers,
 5539                    kind,
 5540                    push_to_history,
 5541                    cx,
 5542                )
 5543                .await;
 5544                lsp_store.update(cx, |lsp_store, _| {
 5545                    lsp_store.update_last_formatting_failure(&result);
 5546                })?;
 5547                result
 5548            })
 5549        } else if let Some((client, project_id)) = self.upstream_client() {
 5550            let buffer_store = self.buffer_store();
 5551            cx.spawn(async move |lsp_store, cx| {
 5552                let result = client
 5553                    .request(proto::ApplyCodeActionKind {
 5554                        project_id,
 5555                        kind: kind.as_str().to_owned(),
 5556                        buffer_ids: buffers
 5557                            .iter()
 5558                            .map(|buffer| {
 5559                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5560                            })
 5561                            .collect(),
 5562                    })
 5563                    .await
 5564                    .and_then(|result| result.transaction.context("missing transaction"));
 5565                lsp_store.update(cx, |lsp_store, _| {
 5566                    lsp_store.update_last_formatting_failure(&result);
 5567                })?;
 5568
 5569                let transaction_response = result?;
 5570                buffer_store
 5571                    .update(cx, |buffer_store, cx| {
 5572                        buffer_store.deserialize_project_transaction(
 5573                            transaction_response,
 5574                            push_to_history,
 5575                            cx,
 5576                        )
 5577                    })
 5578                    .await
 5579            })
 5580        } else {
 5581            Task::ready(Ok(ProjectTransaction::default()))
 5582        }
 5583    }
 5584
 5585    pub fn resolved_hint(
 5586        &mut self,
 5587        buffer_id: BufferId,
 5588        id: InlayId,
 5589        cx: &mut Context<Self>,
 5590    ) -> Option<ResolvedHint> {
 5591        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5592
 5593        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5594        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5595        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5596        let (server_id, resolve_data) = match &hint.resolve_state {
 5597            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5598            ResolveState::Resolving => {
 5599                return Some(ResolvedHint::Resolving(
 5600                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5601                ));
 5602            }
 5603            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5604        };
 5605
 5606        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5607        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5608        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5609            id,
 5610            cx.spawn(async move |lsp_store, cx| {
 5611                let resolved_hint = resolve_task.await;
 5612                lsp_store
 5613                    .update(cx, |lsp_store, _| {
 5614                        if let Some(old_inlay_hint) = lsp_store
 5615                            .lsp_data
 5616                            .get_mut(&buffer_id)
 5617                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5618                        {
 5619                            match resolved_hint {
 5620                                Ok(resolved_hint) => {
 5621                                    *old_inlay_hint = resolved_hint;
 5622                                }
 5623                                Err(e) => {
 5624                                    old_inlay_hint.resolve_state =
 5625                                        ResolveState::CanResolve(server_id, resolve_data);
 5626                                    log::error!("Inlay hint resolve failed: {e:#}");
 5627                                }
 5628                            }
 5629                        }
 5630                    })
 5631                    .ok();
 5632            })
 5633            .shared(),
 5634        );
 5635        debug_assert!(
 5636            previous_task.is_none(),
 5637            "Did not change hint's resolve state after spawning its resolve"
 5638        );
 5639        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5640        None
 5641    }
 5642
 5643    pub(crate) fn linked_edits(
 5644        &mut self,
 5645        buffer: &Entity<Buffer>,
 5646        position: Anchor,
 5647        cx: &mut Context<Self>,
 5648    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5649        let snapshot = buffer.read(cx).snapshot();
 5650        let scope = snapshot.language_scope_at(position);
 5651        let Some(server_id) = self
 5652            .as_local()
 5653            .and_then(|local| {
 5654                buffer.update(cx, |buffer, cx| {
 5655                    local
 5656                        .language_servers_for_buffer(buffer, cx)
 5657                        .filter(|(_, server)| {
 5658                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5659                        })
 5660                        .filter(|(adapter, _)| {
 5661                            scope
 5662                                .as_ref()
 5663                                .map(|scope| scope.language_allowed(&adapter.name))
 5664                                .unwrap_or(true)
 5665                        })
 5666                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5667                        .next()
 5668                })
 5669            })
 5670            .or_else(|| {
 5671                self.upstream_client()
 5672                    .is_some()
 5673                    .then_some(LanguageServerToQuery::FirstCapable)
 5674            })
 5675            .filter(|_| {
 5676                maybe!({
 5677                    buffer.read(cx).language_at(position)?;
 5678                    Some(
 5679                        LanguageSettings::for_buffer_at(&buffer.read(cx), position, cx)
 5680                            .linked_edits,
 5681                    )
 5682                }) == Some(true)
 5683            })
 5684        else {
 5685            return Task::ready(Ok(Vec::new()));
 5686        };
 5687
 5688        self.request_lsp(
 5689            buffer.clone(),
 5690            server_id,
 5691            LinkedEditingRange { position },
 5692            cx,
 5693        )
 5694    }
 5695
 5696    fn apply_on_type_formatting(
 5697        &mut self,
 5698        buffer: Entity<Buffer>,
 5699        position: Anchor,
 5700        trigger: String,
 5701        cx: &mut Context<Self>,
 5702    ) -> Task<Result<Option<Transaction>>> {
 5703        if let Some((client, project_id)) = self.upstream_client() {
 5704            if !self.check_if_capable_for_proto_request(
 5705                &buffer,
 5706                |capabilities| {
 5707                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5708                },
 5709                cx,
 5710            ) {
 5711                return Task::ready(Ok(None));
 5712            }
 5713            let request = proto::OnTypeFormatting {
 5714                project_id,
 5715                buffer_id: buffer.read(cx).remote_id().into(),
 5716                position: Some(serialize_anchor(&position)),
 5717                trigger,
 5718                version: serialize_version(&buffer.read(cx).version()),
 5719            };
 5720            cx.background_spawn(async move {
 5721                client
 5722                    .request(request)
 5723                    .await?
 5724                    .transaction
 5725                    .map(language::proto::deserialize_transaction)
 5726                    .transpose()
 5727            })
 5728        } else if let Some(local) = self.as_local_mut() {
 5729            let buffer_id = buffer.read(cx).remote_id();
 5730            local.buffers_being_formatted.insert(buffer_id);
 5731            cx.spawn(async move |this, cx| {
 5732                let _cleanup = defer({
 5733                    let this = this.clone();
 5734                    let mut cx = cx.clone();
 5735                    move || {
 5736                        this.update(&mut cx, |this, _| {
 5737                            if let Some(local) = this.as_local_mut() {
 5738                                local.buffers_being_formatted.remove(&buffer_id);
 5739                            }
 5740                        })
 5741                        .ok();
 5742                    }
 5743                });
 5744
 5745                buffer
 5746                    .update(cx, |buffer, _| {
 5747                        buffer.wait_for_edits(Some(position.timestamp()))
 5748                    })
 5749                    .await?;
 5750                this.update(cx, |this, cx| {
 5751                    let position = position.to_point_utf16(buffer.read(cx));
 5752                    this.on_type_format(buffer, position, trigger, false, cx)
 5753                })?
 5754                .await
 5755            })
 5756        } else {
 5757            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5758        }
 5759    }
 5760
 5761    pub fn on_type_format<T: ToPointUtf16>(
 5762        &mut self,
 5763        buffer: Entity<Buffer>,
 5764        position: T,
 5765        trigger: String,
 5766        push_to_history: bool,
 5767        cx: &mut Context<Self>,
 5768    ) -> Task<Result<Option<Transaction>>> {
 5769        let position = position.to_point_utf16(buffer.read(cx));
 5770        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5771    }
 5772
 5773    fn on_type_format_impl(
 5774        &mut self,
 5775        buffer: Entity<Buffer>,
 5776        position: PointUtf16,
 5777        trigger: String,
 5778        push_to_history: bool,
 5779        cx: &mut Context<Self>,
 5780    ) -> Task<Result<Option<Transaction>>> {
 5781        let options = buffer.update(cx, |buffer, cx| {
 5782            lsp_command::lsp_formatting_options(
 5783                LanguageSettings::for_buffer_at(buffer, position, cx).as_ref(),
 5784            )
 5785        });
 5786
 5787        cx.spawn(async move |this, cx| {
 5788            if let Some(waiter) =
 5789                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5790            {
 5791                waiter.await?;
 5792            }
 5793            cx.update(|cx| {
 5794                this.update(cx, |this, cx| {
 5795                    this.request_lsp(
 5796                        buffer.clone(),
 5797                        LanguageServerToQuery::FirstCapable,
 5798                        OnTypeFormatting {
 5799                            position,
 5800                            trigger,
 5801                            options,
 5802                            push_to_history,
 5803                        },
 5804                        cx,
 5805                    )
 5806                })
 5807            })?
 5808            .await
 5809        })
 5810    }
 5811
 5812    pub fn definitions(
 5813        &mut self,
 5814        buffer: &Entity<Buffer>,
 5815        position: PointUtf16,
 5816        cx: &mut Context<Self>,
 5817    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5818        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5819            let request = GetDefinitions { position };
 5820            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5821                return Task::ready(Ok(None));
 5822            }
 5823
 5824            let request_timeout = ProjectSettings::get_global(cx)
 5825                .global_lsp_settings
 5826                .get_request_timeout();
 5827
 5828            let request_task = upstream_client.request_lsp(
 5829                project_id,
 5830                None,
 5831                request_timeout,
 5832                cx.background_executor().clone(),
 5833                request.to_proto(project_id, buffer.read(cx)),
 5834            );
 5835            let buffer = buffer.clone();
 5836            cx.spawn(async move |weak_lsp_store, cx| {
 5837                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5838                    return Ok(None);
 5839                };
 5840                let Some(responses) = request_task.await? else {
 5841                    return Ok(None);
 5842                };
 5843                let actions = join_all(responses.payload.into_iter().map(|response| {
 5844                    GetDefinitions { position }.response_from_proto(
 5845                        response.response,
 5846                        lsp_store.clone(),
 5847                        buffer.clone(),
 5848                        cx.clone(),
 5849                    )
 5850                }))
 5851                .await;
 5852
 5853                Ok(Some(
 5854                    actions
 5855                        .into_iter()
 5856                        .collect::<Result<Vec<Vec<_>>>>()?
 5857                        .into_iter()
 5858                        .flatten()
 5859                        .dedup()
 5860                        .collect(),
 5861                ))
 5862            })
 5863        } else {
 5864            let definitions_task = self.request_multiple_lsp_locally(
 5865                buffer,
 5866                Some(position),
 5867                GetDefinitions { position },
 5868                cx,
 5869            );
 5870            cx.background_spawn(async move {
 5871                Ok(Some(
 5872                    definitions_task
 5873                        .await
 5874                        .into_iter()
 5875                        .flat_map(|(_, definitions)| definitions)
 5876                        .dedup()
 5877                        .collect(),
 5878                ))
 5879            })
 5880        }
 5881    }
 5882
 5883    pub fn declarations(
 5884        &mut self,
 5885        buffer: &Entity<Buffer>,
 5886        position: PointUtf16,
 5887        cx: &mut Context<Self>,
 5888    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5889        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5890            let request = GetDeclarations { position };
 5891            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5892                return Task::ready(Ok(None));
 5893            }
 5894            let request_timeout = ProjectSettings::get_global(cx)
 5895                .global_lsp_settings
 5896                .get_request_timeout();
 5897            let request_task = upstream_client.request_lsp(
 5898                project_id,
 5899                None,
 5900                request_timeout,
 5901                cx.background_executor().clone(),
 5902                request.to_proto(project_id, buffer.read(cx)),
 5903            );
 5904            let buffer = buffer.clone();
 5905            cx.spawn(async move |weak_lsp_store, cx| {
 5906                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5907                    return Ok(None);
 5908                };
 5909                let Some(responses) = request_task.await? else {
 5910                    return Ok(None);
 5911                };
 5912                let actions = join_all(responses.payload.into_iter().map(|response| {
 5913                    GetDeclarations { position }.response_from_proto(
 5914                        response.response,
 5915                        lsp_store.clone(),
 5916                        buffer.clone(),
 5917                        cx.clone(),
 5918                    )
 5919                }))
 5920                .await;
 5921
 5922                Ok(Some(
 5923                    actions
 5924                        .into_iter()
 5925                        .collect::<Result<Vec<Vec<_>>>>()?
 5926                        .into_iter()
 5927                        .flatten()
 5928                        .dedup()
 5929                        .collect(),
 5930                ))
 5931            })
 5932        } else {
 5933            let declarations_task = self.request_multiple_lsp_locally(
 5934                buffer,
 5935                Some(position),
 5936                GetDeclarations { position },
 5937                cx,
 5938            );
 5939            cx.background_spawn(async move {
 5940                Ok(Some(
 5941                    declarations_task
 5942                        .await
 5943                        .into_iter()
 5944                        .flat_map(|(_, declarations)| declarations)
 5945                        .dedup()
 5946                        .collect(),
 5947                ))
 5948            })
 5949        }
 5950    }
 5951
 5952    pub fn type_definitions(
 5953        &mut self,
 5954        buffer: &Entity<Buffer>,
 5955        position: PointUtf16,
 5956        cx: &mut Context<Self>,
 5957    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5958        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5959            let request = GetTypeDefinitions { position };
 5960            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5961                return Task::ready(Ok(None));
 5962            }
 5963            let request_timeout = ProjectSettings::get_global(cx)
 5964                .global_lsp_settings
 5965                .get_request_timeout();
 5966            let request_task = upstream_client.request_lsp(
 5967                project_id,
 5968                None,
 5969                request_timeout,
 5970                cx.background_executor().clone(),
 5971                request.to_proto(project_id, buffer.read(cx)),
 5972            );
 5973            let buffer = buffer.clone();
 5974            cx.spawn(async move |weak_lsp_store, cx| {
 5975                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5976                    return Ok(None);
 5977                };
 5978                let Some(responses) = request_task.await? else {
 5979                    return Ok(None);
 5980                };
 5981                let actions = join_all(responses.payload.into_iter().map(|response| {
 5982                    GetTypeDefinitions { position }.response_from_proto(
 5983                        response.response,
 5984                        lsp_store.clone(),
 5985                        buffer.clone(),
 5986                        cx.clone(),
 5987                    )
 5988                }))
 5989                .await;
 5990
 5991                Ok(Some(
 5992                    actions
 5993                        .into_iter()
 5994                        .collect::<Result<Vec<Vec<_>>>>()?
 5995                        .into_iter()
 5996                        .flatten()
 5997                        .dedup()
 5998                        .collect(),
 5999                ))
 6000            })
 6001        } else {
 6002            let type_definitions_task = self.request_multiple_lsp_locally(
 6003                buffer,
 6004                Some(position),
 6005                GetTypeDefinitions { position },
 6006                cx,
 6007            );
 6008            cx.background_spawn(async move {
 6009                Ok(Some(
 6010                    type_definitions_task
 6011                        .await
 6012                        .into_iter()
 6013                        .flat_map(|(_, type_definitions)| type_definitions)
 6014                        .dedup()
 6015                        .collect(),
 6016                ))
 6017            })
 6018        }
 6019    }
 6020
 6021    pub fn implementations(
 6022        &mut self,
 6023        buffer: &Entity<Buffer>,
 6024        position: PointUtf16,
 6025        cx: &mut Context<Self>,
 6026    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 6027        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6028            let request = GetImplementations { position };
 6029            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6030                return Task::ready(Ok(None));
 6031            }
 6032
 6033            let request_timeout = ProjectSettings::get_global(cx)
 6034                .global_lsp_settings
 6035                .get_request_timeout();
 6036            let request_task = upstream_client.request_lsp(
 6037                project_id,
 6038                None,
 6039                request_timeout,
 6040                cx.background_executor().clone(),
 6041                request.to_proto(project_id, buffer.read(cx)),
 6042            );
 6043            let buffer = buffer.clone();
 6044            cx.spawn(async move |weak_lsp_store, cx| {
 6045                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6046                    return Ok(None);
 6047                };
 6048                let Some(responses) = request_task.await? else {
 6049                    return Ok(None);
 6050                };
 6051                let actions = join_all(responses.payload.into_iter().map(|response| {
 6052                    GetImplementations { position }.response_from_proto(
 6053                        response.response,
 6054                        lsp_store.clone(),
 6055                        buffer.clone(),
 6056                        cx.clone(),
 6057                    )
 6058                }))
 6059                .await;
 6060
 6061                Ok(Some(
 6062                    actions
 6063                        .into_iter()
 6064                        .collect::<Result<Vec<Vec<_>>>>()?
 6065                        .into_iter()
 6066                        .flatten()
 6067                        .dedup()
 6068                        .collect(),
 6069                ))
 6070            })
 6071        } else {
 6072            let implementations_task = self.request_multiple_lsp_locally(
 6073                buffer,
 6074                Some(position),
 6075                GetImplementations { position },
 6076                cx,
 6077            );
 6078            cx.background_spawn(async move {
 6079                Ok(Some(
 6080                    implementations_task
 6081                        .await
 6082                        .into_iter()
 6083                        .flat_map(|(_, implementations)| implementations)
 6084                        .dedup()
 6085                        .collect(),
 6086                ))
 6087            })
 6088        }
 6089    }
 6090
 6091    pub fn references(
 6092        &mut self,
 6093        buffer: &Entity<Buffer>,
 6094        position: PointUtf16,
 6095        cx: &mut Context<Self>,
 6096    ) -> Task<Result<Option<Vec<Location>>>> {
 6097        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6098            let request = GetReferences { position };
 6099            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6100                return Task::ready(Ok(None));
 6101            }
 6102
 6103            let request_timeout = ProjectSettings::get_global(cx)
 6104                .global_lsp_settings
 6105                .get_request_timeout();
 6106            let request_task = upstream_client.request_lsp(
 6107                project_id,
 6108                None,
 6109                request_timeout,
 6110                cx.background_executor().clone(),
 6111                request.to_proto(project_id, buffer.read(cx)),
 6112            );
 6113            let buffer = buffer.clone();
 6114            cx.spawn(async move |weak_lsp_store, cx| {
 6115                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6116                    return Ok(None);
 6117                };
 6118                let Some(responses) = request_task.await? else {
 6119                    return Ok(None);
 6120                };
 6121
 6122                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 6123                    GetReferences { position }.response_from_proto(
 6124                        lsp_response.response,
 6125                        lsp_store.clone(),
 6126                        buffer.clone(),
 6127                        cx.clone(),
 6128                    )
 6129                }))
 6130                .await
 6131                .into_iter()
 6132                .collect::<Result<Vec<Vec<_>>>>()?
 6133                .into_iter()
 6134                .flatten()
 6135                .dedup()
 6136                .collect();
 6137                Ok(Some(locations))
 6138            })
 6139        } else {
 6140            let references_task = self.request_multiple_lsp_locally(
 6141                buffer,
 6142                Some(position),
 6143                GetReferences { position },
 6144                cx,
 6145            );
 6146            cx.background_spawn(async move {
 6147                Ok(Some(
 6148                    references_task
 6149                        .await
 6150                        .into_iter()
 6151                        .flat_map(|(_, references)| references)
 6152                        .dedup()
 6153                        .collect(),
 6154                ))
 6155            })
 6156        }
 6157    }
 6158
 6159    pub fn code_actions(
 6160        &mut self,
 6161        buffer: &Entity<Buffer>,
 6162        range: Range<Anchor>,
 6163        kinds: Option<Vec<CodeActionKind>>,
 6164        cx: &mut Context<Self>,
 6165    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6166        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6167            let request = GetCodeActions {
 6168                range: range.clone(),
 6169                kinds: kinds.clone(),
 6170            };
 6171            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6172                return Task::ready(Ok(None));
 6173            }
 6174            let request_timeout = ProjectSettings::get_global(cx)
 6175                .global_lsp_settings
 6176                .get_request_timeout();
 6177            let request_task = upstream_client.request_lsp(
 6178                project_id,
 6179                None,
 6180                request_timeout,
 6181                cx.background_executor().clone(),
 6182                request.to_proto(project_id, buffer.read(cx)),
 6183            );
 6184            let buffer = buffer.clone();
 6185            cx.spawn(async move |weak_lsp_store, cx| {
 6186                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6187                    return Ok(None);
 6188                };
 6189                let Some(responses) = request_task.await? else {
 6190                    return Ok(None);
 6191                };
 6192                let actions = join_all(responses.payload.into_iter().map(|response| {
 6193                    GetCodeActions {
 6194                        range: range.clone(),
 6195                        kinds: kinds.clone(),
 6196                    }
 6197                    .response_from_proto(
 6198                        response.response,
 6199                        lsp_store.clone(),
 6200                        buffer.clone(),
 6201                        cx.clone(),
 6202                    )
 6203                }))
 6204                .await;
 6205
 6206                Ok(Some(
 6207                    actions
 6208                        .into_iter()
 6209                        .collect::<Result<Vec<Vec<_>>>>()?
 6210                        .into_iter()
 6211                        .flatten()
 6212                        .collect(),
 6213                ))
 6214            })
 6215        } else {
 6216            let all_actions_task = self.request_multiple_lsp_locally(
 6217                buffer,
 6218                Some(range.start),
 6219                GetCodeActions { range, kinds },
 6220                cx,
 6221            );
 6222            cx.background_spawn(async move {
 6223                Ok(Some(
 6224                    all_actions_task
 6225                        .await
 6226                        .into_iter()
 6227                        .flat_map(|(_, actions)| actions)
 6228                        .collect(),
 6229                ))
 6230            })
 6231        }
 6232    }
 6233
 6234    #[inline(never)]
 6235    pub fn completions(
 6236        &self,
 6237        buffer: &Entity<Buffer>,
 6238        position: PointUtf16,
 6239        context: CompletionContext,
 6240        cx: &mut Context<Self>,
 6241    ) -> Task<Result<Vec<CompletionResponse>>> {
 6242        let language_registry = self.languages.clone();
 6243
 6244        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6245            let snapshot = buffer.read(cx).snapshot();
 6246            let offset = position.to_offset(&snapshot);
 6247            let scope = snapshot.language_scope_at(offset);
 6248            let capable_lsps = self.all_capable_for_proto_request(
 6249                buffer,
 6250                |server_name, capabilities| {
 6251                    capabilities.completion_provider.is_some()
 6252                        && scope
 6253                            .as_ref()
 6254                            .map(|scope| scope.language_allowed(server_name))
 6255                            .unwrap_or(true)
 6256                },
 6257                cx,
 6258            );
 6259            if capable_lsps.is_empty() {
 6260                return Task::ready(Ok(Vec::new()));
 6261            }
 6262
 6263            let language = buffer.read(cx).language().cloned();
 6264
 6265            let buffer = buffer.clone();
 6266
 6267            cx.spawn(async move |this, cx| {
 6268                let requests = join_all(
 6269                    capable_lsps
 6270                        .into_iter()
 6271                        .map(|(id, server_name)| {
 6272                            let request = GetCompletions {
 6273                                position,
 6274                                context: context.clone(),
 6275                                server_id: Some(id),
 6276                            };
 6277                            let buffer = buffer.clone();
 6278                            let language = language.clone();
 6279                            let lsp_adapter = language.as_ref().and_then(|language| {
 6280                                let adapters = language_registry.lsp_adapters(&language.name());
 6281                                adapters
 6282                                    .iter()
 6283                                    .find(|adapter| adapter.name() == server_name)
 6284                                    .or_else(|| adapters.first())
 6285                                    .cloned()
 6286                            });
 6287                            let upstream_client = upstream_client.clone();
 6288                            let response = this
 6289                                .update(cx, |this, cx| {
 6290                                    this.send_lsp_proto_request(
 6291                                        buffer,
 6292                                        upstream_client,
 6293                                        project_id,
 6294                                        request,
 6295                                        cx,
 6296                                    )
 6297                                })
 6298                                .log_err();
 6299                            async move {
 6300                                let response = response?.await.log_err()?;
 6301
 6302                                let completions = populate_labels_for_completions(
 6303                                    response.completions,
 6304                                    language,
 6305                                    lsp_adapter,
 6306                                )
 6307                                .await;
 6308
 6309                                Some(CompletionResponse {
 6310                                    completions,
 6311                                    display_options: CompletionDisplayOptions::default(),
 6312                                    is_incomplete: response.is_incomplete,
 6313                                })
 6314                            }
 6315                        })
 6316                        .collect::<Vec<_>>(),
 6317                );
 6318                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6319            })
 6320        } else if let Some(local) = self.as_local() {
 6321            let snapshot = buffer.read(cx).snapshot();
 6322            let offset = position.to_offset(&snapshot);
 6323            let scope = snapshot.language_scope_at(offset);
 6324            let language = snapshot.language().cloned();
 6325            let completion_settings = LanguageSettings::for_buffer(&buffer.read(cx), cx)
 6326                .completions
 6327                .clone();
 6328            if !completion_settings.lsp {
 6329                return Task::ready(Ok(Vec::new()));
 6330            }
 6331
 6332            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6333                local
 6334                    .language_servers_for_buffer(buffer, cx)
 6335                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6336                    .filter(|(adapter, _)| {
 6337                        scope
 6338                            .as_ref()
 6339                            .map(|scope| scope.language_allowed(&adapter.name))
 6340                            .unwrap_or(true)
 6341                    })
 6342                    .map(|(_, server)| server.server_id())
 6343                    .collect()
 6344            });
 6345
 6346            let buffer = buffer.clone();
 6347            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6348            let lsp_timeout = if lsp_timeout > 0 {
 6349                Some(Duration::from_millis(lsp_timeout))
 6350            } else {
 6351                None
 6352            };
 6353            cx.spawn(async move |this,  cx| {
 6354                let mut tasks = Vec::with_capacity(server_ids.len());
 6355                this.update(cx, |lsp_store, cx| {
 6356                    for server_id in server_ids {
 6357                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6358                        let lsp_timeout = lsp_timeout
 6359                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6360                        let mut timeout = cx.background_spawn(async move {
 6361                            match lsp_timeout {
 6362                                Some(lsp_timeout) => {
 6363                                    lsp_timeout.await;
 6364                                    true
 6365                                },
 6366                                None => false,
 6367                            }
 6368                        }).fuse();
 6369                        let mut lsp_request = lsp_store.request_lsp(
 6370                            buffer.clone(),
 6371                            LanguageServerToQuery::Other(server_id),
 6372                            GetCompletions {
 6373                                position,
 6374                                context: context.clone(),
 6375                                server_id: Some(server_id),
 6376                            },
 6377                            cx,
 6378                        ).fuse();
 6379                        let new_task = cx.background_spawn(async move {
 6380                            select_biased! {
 6381                                response = lsp_request => anyhow::Ok(Some(response?)),
 6382                                timeout_happened = timeout => {
 6383                                    if timeout_happened {
 6384                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6385                                        Ok(None)
 6386                                    } else {
 6387                                        let completions = lsp_request.await?;
 6388                                        Ok(Some(completions))
 6389                                    }
 6390                                },
 6391                            }
 6392                        });
 6393                        tasks.push((lsp_adapter, new_task));
 6394                    }
 6395                })?;
 6396
 6397                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6398                    let completion_response = task.await.ok()??;
 6399                    let completions = populate_labels_for_completions(
 6400                            completion_response.completions,
 6401                            language.clone(),
 6402                            lsp_adapter,
 6403                        )
 6404                        .await;
 6405                    Some(CompletionResponse {
 6406                        completions,
 6407                        display_options: CompletionDisplayOptions::default(),
 6408                        is_incomplete: completion_response.is_incomplete,
 6409                    })
 6410                });
 6411
 6412                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6413
 6414                Ok(responses.into_iter().flatten().collect())
 6415            })
 6416        } else {
 6417            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6418        }
 6419    }
 6420
 6421    pub fn resolve_completions(
 6422        &self,
 6423        buffer: Entity<Buffer>,
 6424        completion_indices: Vec<usize>,
 6425        completions: Rc<RefCell<Box<[Completion]>>>,
 6426        cx: &mut Context<Self>,
 6427    ) -> Task<Result<bool>> {
 6428        let client = self.upstream_client();
 6429        let buffer_id = buffer.read(cx).remote_id();
 6430        let buffer_snapshot = buffer.read(cx).snapshot();
 6431
 6432        if !self.check_if_capable_for_proto_request(
 6433            &buffer,
 6434            GetCompletions::can_resolve_completions,
 6435            cx,
 6436        ) {
 6437            return Task::ready(Ok(false));
 6438        }
 6439        cx.spawn(async move |lsp_store, cx| {
 6440            let request_timeout = cx.update(|app| {
 6441                ProjectSettings::get_global(app)
 6442                    .global_lsp_settings
 6443                    .get_request_timeout()
 6444            });
 6445
 6446            let mut did_resolve = false;
 6447            if let Some((client, project_id)) = client {
 6448                for completion_index in completion_indices {
 6449                    let server_id = {
 6450                        let completion = &completions.borrow()[completion_index];
 6451                        completion.source.server_id()
 6452                    };
 6453                    if let Some(server_id) = server_id {
 6454                        if Self::resolve_completion_remote(
 6455                            project_id,
 6456                            server_id,
 6457                            buffer_id,
 6458                            completions.clone(),
 6459                            completion_index,
 6460                            client.clone(),
 6461                        )
 6462                        .await
 6463                        .log_err()
 6464                        .is_some()
 6465                        {
 6466                            did_resolve = true;
 6467                        }
 6468                    } else {
 6469                        resolve_word_completion(
 6470                            &buffer_snapshot,
 6471                            &mut completions.borrow_mut()[completion_index],
 6472                        );
 6473                    }
 6474                }
 6475            } else {
 6476                for completion_index in completion_indices {
 6477                    let server_id = {
 6478                        let completion = &completions.borrow()[completion_index];
 6479                        completion.source.server_id()
 6480                    };
 6481                    if let Some(server_id) = server_id {
 6482                        let server_and_adapter = lsp_store
 6483                            .read_with(cx, |lsp_store, _| {
 6484                                let server = lsp_store.language_server_for_id(server_id)?;
 6485                                let adapter =
 6486                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6487                                Some((server, adapter))
 6488                            })
 6489                            .ok()
 6490                            .flatten();
 6491                        let Some((server, adapter)) = server_and_adapter else {
 6492                            continue;
 6493                        };
 6494
 6495                        let resolved = Self::resolve_completion_local(
 6496                            server,
 6497                            completions.clone(),
 6498                            completion_index,
 6499                            request_timeout,
 6500                        )
 6501                        .await
 6502                        .log_err()
 6503                        .is_some();
 6504                        if resolved {
 6505                            Self::regenerate_completion_labels(
 6506                                adapter,
 6507                                &buffer_snapshot,
 6508                                completions.clone(),
 6509                                completion_index,
 6510                            )
 6511                            .await
 6512                            .log_err();
 6513                            did_resolve = true;
 6514                        }
 6515                    } else {
 6516                        resolve_word_completion(
 6517                            &buffer_snapshot,
 6518                            &mut completions.borrow_mut()[completion_index],
 6519                        );
 6520                    }
 6521                }
 6522            }
 6523
 6524            Ok(did_resolve)
 6525        })
 6526    }
 6527
 6528    async fn resolve_completion_local(
 6529        server: Arc<lsp::LanguageServer>,
 6530        completions: Rc<RefCell<Box<[Completion]>>>,
 6531        completion_index: usize,
 6532        request_timeout: Duration,
 6533    ) -> Result<()> {
 6534        let server_id = server.server_id();
 6535        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6536            return Ok(());
 6537        }
 6538
 6539        let request = {
 6540            let completion = &completions.borrow()[completion_index];
 6541            match &completion.source {
 6542                CompletionSource::Lsp {
 6543                    lsp_completion,
 6544                    resolved,
 6545                    server_id: completion_server_id,
 6546                    ..
 6547                } => {
 6548                    if *resolved {
 6549                        return Ok(());
 6550                    }
 6551                    anyhow::ensure!(
 6552                        server_id == *completion_server_id,
 6553                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6554                    );
 6555                    server.request::<lsp::request::ResolveCompletionItem>(
 6556                        *lsp_completion.clone(),
 6557                        request_timeout,
 6558                    )
 6559                }
 6560                CompletionSource::BufferWord { .. }
 6561                | CompletionSource::Dap { .. }
 6562                | CompletionSource::Custom => {
 6563                    return Ok(());
 6564                }
 6565            }
 6566        };
 6567        let resolved_completion = request
 6568            .await
 6569            .into_response()
 6570            .context("resolve completion")?;
 6571
 6572        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6573        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6574
 6575        let mut completions = completions.borrow_mut();
 6576        let completion = &mut completions[completion_index];
 6577        if let CompletionSource::Lsp {
 6578            lsp_completion,
 6579            resolved,
 6580            server_id: completion_server_id,
 6581            ..
 6582        } = &mut completion.source
 6583        {
 6584            if *resolved {
 6585                return Ok(());
 6586            }
 6587            anyhow::ensure!(
 6588                server_id == *completion_server_id,
 6589                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6590            );
 6591            **lsp_completion = resolved_completion;
 6592            *resolved = true;
 6593        }
 6594        Ok(())
 6595    }
 6596
 6597    async fn regenerate_completion_labels(
 6598        adapter: Arc<CachedLspAdapter>,
 6599        snapshot: &BufferSnapshot,
 6600        completions: Rc<RefCell<Box<[Completion]>>>,
 6601        completion_index: usize,
 6602    ) -> Result<()> {
 6603        let completion_item = completions.borrow()[completion_index]
 6604            .source
 6605            .lsp_completion(true)
 6606            .map(Cow::into_owned);
 6607        if let Some(lsp_documentation) = completion_item
 6608            .as_ref()
 6609            .and_then(|completion_item| completion_item.documentation.clone())
 6610        {
 6611            let mut completions = completions.borrow_mut();
 6612            let completion = &mut completions[completion_index];
 6613            completion.documentation = Some(lsp_documentation.into());
 6614        } else {
 6615            let mut completions = completions.borrow_mut();
 6616            let completion = &mut completions[completion_index];
 6617            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6618        }
 6619
 6620        let mut new_label = match completion_item {
 6621            Some(completion_item) => {
 6622                // Some language servers always return `detail` lazily via resolve, regardless of
 6623                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6624                // See: https://github.com/yioneko/vtsls/issues/213
 6625                let language = snapshot.language();
 6626                match language {
 6627                    Some(language) => {
 6628                        adapter
 6629                            .labels_for_completions(
 6630                                std::slice::from_ref(&completion_item),
 6631                                language,
 6632                            )
 6633                            .await?
 6634                    }
 6635                    None => Vec::new(),
 6636                }
 6637                .pop()
 6638                .flatten()
 6639                .unwrap_or_else(|| {
 6640                    CodeLabel::fallback_for_completion(
 6641                        &completion_item,
 6642                        language.map(|language| language.as_ref()),
 6643                    )
 6644                })
 6645            }
 6646            None => CodeLabel::plain(
 6647                completions.borrow()[completion_index].new_text.clone(),
 6648                None,
 6649            ),
 6650        };
 6651        ensure_uniform_list_compatible_label(&mut new_label);
 6652
 6653        let mut completions = completions.borrow_mut();
 6654        let completion = &mut completions[completion_index];
 6655        if completion.label.filter_text() == new_label.filter_text() {
 6656            completion.label = new_label;
 6657        } else {
 6658            log::error!(
 6659                "Resolved completion changed display label from {} to {}. \
 6660                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6661                completion.label.text(),
 6662                new_label.text(),
 6663                completion.label.filter_text(),
 6664                new_label.filter_text()
 6665            );
 6666        }
 6667
 6668        Ok(())
 6669    }
 6670
 6671    async fn resolve_completion_remote(
 6672        project_id: u64,
 6673        server_id: LanguageServerId,
 6674        buffer_id: BufferId,
 6675        completions: Rc<RefCell<Box<[Completion]>>>,
 6676        completion_index: usize,
 6677        client: AnyProtoClient,
 6678    ) -> Result<()> {
 6679        let lsp_completion = {
 6680            let completion = &completions.borrow()[completion_index];
 6681            match &completion.source {
 6682                CompletionSource::Lsp {
 6683                    lsp_completion,
 6684                    resolved,
 6685                    server_id: completion_server_id,
 6686                    ..
 6687                } => {
 6688                    anyhow::ensure!(
 6689                        server_id == *completion_server_id,
 6690                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6691                    );
 6692                    if *resolved {
 6693                        return Ok(());
 6694                    }
 6695                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6696                }
 6697                CompletionSource::Custom
 6698                | CompletionSource::Dap { .. }
 6699                | CompletionSource::BufferWord { .. } => {
 6700                    return Ok(());
 6701                }
 6702            }
 6703        };
 6704        let request = proto::ResolveCompletionDocumentation {
 6705            project_id,
 6706            language_server_id: server_id.0 as u64,
 6707            lsp_completion,
 6708            buffer_id: buffer_id.into(),
 6709        };
 6710
 6711        let response = client
 6712            .request(request)
 6713            .await
 6714            .context("completion documentation resolve proto request")?;
 6715        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6716
 6717        let documentation = if response.documentation.is_empty() {
 6718            CompletionDocumentation::Undocumented
 6719        } else if response.documentation_is_markdown {
 6720            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6721        } else if response.documentation.lines().count() <= 1 {
 6722            CompletionDocumentation::SingleLine(response.documentation.into())
 6723        } else {
 6724            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6725        };
 6726
 6727        let mut completions = completions.borrow_mut();
 6728        let completion = &mut completions[completion_index];
 6729        completion.documentation = Some(documentation);
 6730        if let CompletionSource::Lsp {
 6731            insert_range,
 6732            lsp_completion,
 6733            resolved,
 6734            server_id: completion_server_id,
 6735            lsp_defaults: _,
 6736        } = &mut completion.source
 6737        {
 6738            let completion_insert_range = response
 6739                .old_insert_start
 6740                .and_then(deserialize_anchor)
 6741                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6742            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6743
 6744            if *resolved {
 6745                return Ok(());
 6746            }
 6747            anyhow::ensure!(
 6748                server_id == *completion_server_id,
 6749                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6750            );
 6751            **lsp_completion = resolved_lsp_completion;
 6752            *resolved = true;
 6753        }
 6754
 6755        let replace_range = response
 6756            .old_replace_start
 6757            .and_then(deserialize_anchor)
 6758            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6759        if let Some((old_replace_start, old_replace_end)) = replace_range
 6760            && !response.new_text.is_empty()
 6761        {
 6762            completion.new_text = response.new_text;
 6763            completion.replace_range = old_replace_start..old_replace_end;
 6764        }
 6765
 6766        Ok(())
 6767    }
 6768
 6769    pub fn apply_additional_edits_for_completion(
 6770        &self,
 6771        buffer_handle: Entity<Buffer>,
 6772        completions: Rc<RefCell<Box<[Completion]>>>,
 6773        completion_index: usize,
 6774        push_to_history: bool,
 6775        all_commit_ranges: Vec<Range<language::Anchor>>,
 6776        cx: &mut Context<Self>,
 6777    ) -> Task<Result<Option<Transaction>>> {
 6778        if let Some((client, project_id)) = self.upstream_client() {
 6779            let buffer = buffer_handle.read(cx);
 6780            let buffer_id = buffer.remote_id();
 6781            cx.spawn(async move |_, cx| {
 6782                let request = {
 6783                    let completion = completions.borrow()[completion_index].clone();
 6784                    proto::ApplyCompletionAdditionalEdits {
 6785                        project_id,
 6786                        buffer_id: buffer_id.into(),
 6787                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6788                            replace_range: completion.replace_range,
 6789                            new_text: completion.new_text,
 6790                            source: completion.source,
 6791                        })),
 6792                        all_commit_ranges: all_commit_ranges
 6793                            .iter()
 6794                            .cloned()
 6795                            .map(language::proto::serialize_anchor_range)
 6796                            .collect(),
 6797                    }
 6798                };
 6799
 6800                let Some(transaction) = client.request(request).await?.transaction else {
 6801                    return Ok(None);
 6802                };
 6803
 6804                let transaction = language::proto::deserialize_transaction(transaction)?;
 6805                buffer_handle
 6806                    .update(cx, |buffer, _| {
 6807                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6808                    })
 6809                    .await?;
 6810                if push_to_history {
 6811                    buffer_handle.update(cx, |buffer, _| {
 6812                        buffer.push_transaction(transaction.clone(), Instant::now());
 6813                        buffer.finalize_last_transaction();
 6814                    });
 6815                }
 6816                Ok(Some(transaction))
 6817            })
 6818        } else {
 6819            let request_timeout = ProjectSettings::get_global(cx)
 6820                .global_lsp_settings
 6821                .get_request_timeout();
 6822
 6823            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6824                let completion = &completions.borrow()[completion_index];
 6825                let server_id = completion.source.server_id()?;
 6826                Some(
 6827                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6828                        .1
 6829                        .clone(),
 6830                )
 6831            }) else {
 6832                return Task::ready(Ok(None));
 6833            };
 6834
 6835            cx.spawn(async move |this, cx| {
 6836                Self::resolve_completion_local(
 6837                    server.clone(),
 6838                    completions.clone(),
 6839                    completion_index,
 6840                    request_timeout,
 6841                )
 6842                .await
 6843                .context("resolving completion")?;
 6844                let completion = completions.borrow()[completion_index].clone();
 6845                let additional_text_edits = completion
 6846                    .source
 6847                    .lsp_completion(true)
 6848                    .as_ref()
 6849                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6850                if let Some(edits) = additional_text_edits {
 6851                    let edits = this
 6852                        .update(cx, |this, cx| {
 6853                            this.as_local_mut().unwrap().edits_from_lsp(
 6854                                &buffer_handle,
 6855                                edits,
 6856                                server.server_id(),
 6857                                None,
 6858                                cx,
 6859                            )
 6860                        })?
 6861                        .await?;
 6862
 6863                    buffer_handle.update(cx, |buffer, cx| {
 6864                        buffer.finalize_last_transaction();
 6865                        buffer.start_transaction();
 6866
 6867                        for (range, text) in edits {
 6868                            let primary = &completion.replace_range;
 6869
 6870                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6871                            // and the primary completion is just an insertion (empty range), then this is likely
 6872                            // an auto-import scenario and should not be considered overlapping
 6873                            // https://github.com/zed-industries/zed/issues/26136
 6874                            let is_file_start_auto_import = {
 6875                                let snapshot = buffer.snapshot();
 6876                                let primary_start_point = primary.start.to_point(&snapshot);
 6877                                let range_start_point = range.start.to_point(&snapshot);
 6878
 6879                                let result = primary_start_point.row == 0
 6880                                    && primary_start_point.column == 0
 6881                                    && range_start_point.row == 0
 6882                                    && range_start_point.column == 0;
 6883
 6884                                result
 6885                            };
 6886
 6887                            let has_overlap = if is_file_start_auto_import {
 6888                                false
 6889                            } else {
 6890                                all_commit_ranges.iter().any(|commit_range| {
 6891                                    let start_within =
 6892                                        commit_range.start.cmp(&range.start, buffer).is_le()
 6893                                            && commit_range.end.cmp(&range.start, buffer).is_ge();
 6894                                    let end_within =
 6895                                        range.start.cmp(&commit_range.end, buffer).is_le()
 6896                                            && range.end.cmp(&commit_range.end, buffer).is_ge();
 6897                                    start_within || end_within
 6898                                })
 6899                            };
 6900
 6901                            //Skip additional edits which overlap with the primary completion edit
 6902                            //https://github.com/zed-industries/zed/pull/1871
 6903                            if !has_overlap {
 6904                                buffer.edit([(range, text)], None, cx);
 6905                            }
 6906                        }
 6907
 6908                        let transaction = if buffer.end_transaction(cx).is_some() {
 6909                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6910                            if !push_to_history {
 6911                                buffer.forget_transaction(transaction.id);
 6912                            }
 6913                            Some(transaction)
 6914                        } else {
 6915                            None
 6916                        };
 6917                        Ok(transaction)
 6918                    })
 6919                } else {
 6920                    Ok(None)
 6921                }
 6922            })
 6923        }
 6924    }
 6925
 6926    pub fn pull_diagnostics(
 6927        &mut self,
 6928        buffer: Entity<Buffer>,
 6929        cx: &mut Context<Self>,
 6930    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6931        let buffer_id = buffer.read(cx).remote_id();
 6932
 6933        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6934            let mut suitable_capabilities = None;
 6935            // Are we capable for proto request?
 6936            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6937                &buffer,
 6938                |capabilities| {
 6939                    if let Some(caps) = &capabilities.diagnostic_provider {
 6940                        suitable_capabilities = Some(caps.clone());
 6941                        true
 6942                    } else {
 6943                        false
 6944                    }
 6945                },
 6946                cx,
 6947            );
 6948            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6949            let Some(dynamic_caps) = suitable_capabilities else {
 6950                return Task::ready(Ok(None));
 6951            };
 6952            assert!(any_server_has_diagnostics_provider);
 6953
 6954            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6955            let request = GetDocumentDiagnostics {
 6956                previous_result_id: None,
 6957                identifier,
 6958                registration_id: None,
 6959            };
 6960            let request_timeout = ProjectSettings::get_global(cx)
 6961                .global_lsp_settings
 6962                .get_request_timeout();
 6963            let request_task = client.request_lsp(
 6964                upstream_project_id,
 6965                None,
 6966                request_timeout,
 6967                cx.background_executor().clone(),
 6968                request.to_proto(upstream_project_id, buffer.read(cx)),
 6969            );
 6970            cx.background_spawn(async move {
 6971                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6972                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6973                // Do not attempt to further process the dummy responses here.
 6974                let _response = request_task.await?;
 6975                Ok(None)
 6976            })
 6977        } else {
 6978            let servers = buffer.update(cx, |buffer, cx| {
 6979                self.running_language_servers_for_local_buffer(buffer, cx)
 6980                    .map(|(_, server)| server.clone())
 6981                    .collect::<Vec<_>>()
 6982            });
 6983
 6984            let pull_diagnostics = servers
 6985                .into_iter()
 6986                .flat_map(|server| {
 6987                    let result = maybe!({
 6988                        let local = self.as_local()?;
 6989                        let server_id = server.server_id();
 6990                        let providers_with_identifiers = local
 6991                            .language_server_dynamic_registrations
 6992                            .get(&server_id)
 6993                            .into_iter()
 6994                            .flat_map(|registrations| registrations.diagnostics.clone())
 6995                            .collect::<Vec<_>>();
 6996                        Some(
 6997                            providers_with_identifiers
 6998                                .into_iter()
 6999                                .map(|(registration_id, dynamic_caps)| {
 7000                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 7001                                    let registration_id = registration_id.map(SharedString::from);
 7002                                    let result_id = self.result_id_for_buffer_pull(
 7003                                        server_id,
 7004                                        buffer_id,
 7005                                        &registration_id,
 7006                                        cx,
 7007                                    );
 7008                                    self.request_lsp(
 7009                                        buffer.clone(),
 7010                                        LanguageServerToQuery::Other(server_id),
 7011                                        GetDocumentDiagnostics {
 7012                                            previous_result_id: result_id,
 7013                                            registration_id,
 7014                                            identifier,
 7015                                        },
 7016                                        cx,
 7017                                    )
 7018                                })
 7019                                .collect::<Vec<_>>(),
 7020                        )
 7021                    });
 7022
 7023                    result.unwrap_or_default()
 7024                })
 7025                .collect::<Vec<_>>();
 7026
 7027            cx.background_spawn(async move {
 7028                let mut responses = Vec::new();
 7029                for diagnostics in join_all(pull_diagnostics).await {
 7030                    responses.extend(diagnostics?);
 7031                }
 7032                Ok(Some(responses))
 7033            })
 7034        }
 7035    }
 7036
 7037    pub fn applicable_inlay_chunks(
 7038        &mut self,
 7039        buffer: &Entity<Buffer>,
 7040        ranges: &[Range<text::Anchor>],
 7041        cx: &mut Context<Self>,
 7042    ) -> Vec<Range<BufferRow>> {
 7043        let buffer_snapshot = buffer.read(cx).snapshot();
 7044        let ranges = ranges
 7045            .iter()
 7046            .map(|range| range.to_point(&buffer_snapshot))
 7047            .collect::<Vec<_>>();
 7048
 7049        self.latest_lsp_data(buffer, cx)
 7050            .inlay_hints
 7051            .applicable_chunks(ranges.as_slice())
 7052            .map(|chunk| chunk.row_range())
 7053            .collect()
 7054    }
 7055
 7056    pub fn invalidate_inlay_hints<'a>(
 7057        &'a mut self,
 7058        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 7059    ) {
 7060        for buffer_id in for_buffers {
 7061            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 7062                lsp_data.inlay_hints.clear();
 7063            }
 7064        }
 7065    }
 7066
 7067    pub fn inlay_hints(
 7068        &mut self,
 7069        invalidate: InvalidationStrategy,
 7070        buffer: Entity<Buffer>,
 7071        ranges: Vec<Range<text::Anchor>>,
 7072        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 7073        cx: &mut Context<Self>,
 7074    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 7075        let next_hint_id = self.next_hint_id.clone();
 7076        let lsp_data = self.latest_lsp_data(&buffer, cx);
 7077        let query_version = lsp_data.buffer_version.clone();
 7078        let mut lsp_refresh_requested = false;
 7079        let for_server = if let InvalidationStrategy::RefreshRequested {
 7080            server_id,
 7081            request_id,
 7082        } = invalidate
 7083        {
 7084            let invalidated = lsp_data
 7085                .inlay_hints
 7086                .invalidate_for_server_refresh(server_id, request_id);
 7087            lsp_refresh_requested = invalidated;
 7088            Some(server_id)
 7089        } else {
 7090            None
 7091        };
 7092        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 7093        let known_chunks = known_chunks
 7094            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 7095            .map(|(_, known_chunks)| known_chunks)
 7096            .unwrap_or_default();
 7097
 7098        let buffer_snapshot = buffer.read(cx).snapshot();
 7099        let ranges = ranges
 7100            .iter()
 7101            .map(|range| range.to_point(&buffer_snapshot))
 7102            .collect::<Vec<_>>();
 7103
 7104        let mut hint_fetch_tasks = Vec::new();
 7105        let mut cached_inlay_hints = None;
 7106        let mut ranges_to_query = None;
 7107        let applicable_chunks = existing_inlay_hints
 7108            .applicable_chunks(ranges.as_slice())
 7109            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7110            .collect::<Vec<_>>();
 7111        if applicable_chunks.is_empty() {
 7112            return HashMap::default();
 7113        }
 7114
 7115        for row_chunk in applicable_chunks {
 7116            match (
 7117                existing_inlay_hints
 7118                    .cached_hints(&row_chunk)
 7119                    .filter(|_| !lsp_refresh_requested)
 7120                    .cloned(),
 7121                existing_inlay_hints
 7122                    .fetched_hints(&row_chunk)
 7123                    .as_ref()
 7124                    .filter(|_| !lsp_refresh_requested)
 7125                    .cloned(),
 7126            ) {
 7127                (None, None) => {
 7128                    let chunk_range = row_chunk.anchor_range();
 7129                    ranges_to_query
 7130                        .get_or_insert_with(Vec::new)
 7131                        .push((row_chunk, chunk_range));
 7132                }
 7133                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7134                (Some(cached_hints), None) => {
 7135                    for (server_id, cached_hints) in cached_hints {
 7136                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7137                            cached_inlay_hints
 7138                                .get_or_insert_with(HashMap::default)
 7139                                .entry(row_chunk.row_range())
 7140                                .or_insert_with(HashMap::default)
 7141                                .entry(server_id)
 7142                                .or_insert_with(Vec::new)
 7143                                .extend(cached_hints);
 7144                        }
 7145                    }
 7146                }
 7147                (Some(cached_hints), Some(fetched_hints)) => {
 7148                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7149                    for (server_id, cached_hints) in cached_hints {
 7150                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7151                            cached_inlay_hints
 7152                                .get_or_insert_with(HashMap::default)
 7153                                .entry(row_chunk.row_range())
 7154                                .or_insert_with(HashMap::default)
 7155                                .entry(server_id)
 7156                                .or_insert_with(Vec::new)
 7157                                .extend(cached_hints);
 7158                        }
 7159                    }
 7160                }
 7161            }
 7162        }
 7163
 7164        if hint_fetch_tasks.is_empty()
 7165            && ranges_to_query
 7166                .as_ref()
 7167                .is_none_or(|ranges| ranges.is_empty())
 7168            && let Some(cached_inlay_hints) = cached_inlay_hints
 7169        {
 7170            cached_inlay_hints
 7171                .into_iter()
 7172                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7173                .collect()
 7174        } else {
 7175            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7176                // When a server refresh was requested, other servers' cached hints
 7177                // are unaffected by the refresh and must be included in the result.
 7178                // Otherwise apply_fetched_hints (with should_invalidate()=true)
 7179                // removes all visible hints but only adds back the requesting
 7180                // server's new hints, permanently losing other servers' hints.
 7181                let other_servers_cached: CacheInlayHints = if lsp_refresh_requested {
 7182                    lsp_data
 7183                        .inlay_hints
 7184                        .cached_hints(&chunk)
 7185                        .cloned()
 7186                        .unwrap_or_default()
 7187                } else {
 7188                    HashMap::default()
 7189                };
 7190
 7191                let next_hint_id = next_hint_id.clone();
 7192                let buffer = buffer.clone();
 7193                let query_version = query_version.clone();
 7194                let new_inlay_hints = cx
 7195                    .spawn(async move |lsp_store, cx| {
 7196                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7197                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7198                        })?;
 7199                        new_fetch_task
 7200                            .await
 7201                            .and_then(|new_hints_by_server| {
 7202                                lsp_store.update(cx, |lsp_store, cx| {
 7203                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7204                                    let update_cache = lsp_data.buffer_version == query_version;
 7205                                    if new_hints_by_server.is_empty() {
 7206                                        if update_cache {
 7207                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7208                                        }
 7209                                        other_servers_cached
 7210                                    } else {
 7211                                        let mut result = other_servers_cached;
 7212                                        for (server_id, new_hints) in new_hints_by_server {
 7213                                            let new_hints = new_hints
 7214                                                .into_iter()
 7215                                                .map(|new_hint| {
 7216                                                    (
 7217                                                        InlayId::Hint(next_hint_id.fetch_add(
 7218                                                            1,
 7219                                                            atomic::Ordering::AcqRel,
 7220                                                        )),
 7221                                                        new_hint,
 7222                                                    )
 7223                                                })
 7224                                                .collect::<Vec<_>>();
 7225                                            if update_cache {
 7226                                                lsp_data.inlay_hints.insert_new_hints(
 7227                                                    chunk,
 7228                                                    server_id,
 7229                                                    new_hints.clone(),
 7230                                                );
 7231                                            }
 7232                                            result.insert(server_id, new_hints);
 7233                                        }
 7234                                        result
 7235                                    }
 7236                                })
 7237                            })
 7238                            .map_err(Arc::new)
 7239                    })
 7240                    .shared();
 7241
 7242                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7243                *fetch_task = Some(new_inlay_hints.clone());
 7244                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7245            }
 7246
 7247            cached_inlay_hints
 7248                .unwrap_or_default()
 7249                .into_iter()
 7250                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7251                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7252                    (
 7253                        chunk.row_range(),
 7254                        cx.spawn(async move |_, _| {
 7255                            hints_fetch.await.map_err(|e| {
 7256                                if e.error_code() != ErrorCode::Internal {
 7257                                    anyhow!(e.error_code())
 7258                                } else {
 7259                                    anyhow!("{e:#}")
 7260                                }
 7261                            })
 7262                        }),
 7263                    )
 7264                }))
 7265                .collect()
 7266        }
 7267    }
 7268
 7269    fn fetch_inlay_hints(
 7270        &mut self,
 7271        for_server: Option<LanguageServerId>,
 7272        buffer: &Entity<Buffer>,
 7273        range: Range<Anchor>,
 7274        cx: &mut Context<Self>,
 7275    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7276        let request = InlayHints {
 7277            range: range.clone(),
 7278        };
 7279        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7280            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7281                return Task::ready(Ok(HashMap::default()));
 7282            }
 7283            let request_timeout = ProjectSettings::get_global(cx)
 7284                .global_lsp_settings
 7285                .get_request_timeout();
 7286            let request_task = upstream_client.request_lsp(
 7287                project_id,
 7288                for_server.map(|id| id.to_proto()),
 7289                request_timeout,
 7290                cx.background_executor().clone(),
 7291                request.to_proto(project_id, buffer.read(cx)),
 7292            );
 7293            let buffer = buffer.clone();
 7294            cx.spawn(async move |weak_lsp_store, cx| {
 7295                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7296                    return Ok(HashMap::default());
 7297                };
 7298                let Some(responses) = request_task.await? else {
 7299                    return Ok(HashMap::default());
 7300                };
 7301
 7302                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7303                    let lsp_store = lsp_store.clone();
 7304                    let buffer = buffer.clone();
 7305                    let cx = cx.clone();
 7306                    let request = request.clone();
 7307                    async move {
 7308                        (
 7309                            LanguageServerId::from_proto(response.server_id),
 7310                            request
 7311                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7312                                .await,
 7313                        )
 7314                    }
 7315                }))
 7316                .await;
 7317
 7318                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7319                let mut has_errors = false;
 7320                let inlay_hints = inlay_hints
 7321                    .into_iter()
 7322                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7323                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7324                        Err(e) => {
 7325                            has_errors = true;
 7326                            log::error!("{e:#}");
 7327                            None
 7328                        }
 7329                    })
 7330                    .map(|(server_id, mut new_hints)| {
 7331                        new_hints.retain(|hint| {
 7332                            hint.position.is_valid(&buffer_snapshot)
 7333                                && range.start.is_valid(&buffer_snapshot)
 7334                                && range.end.is_valid(&buffer_snapshot)
 7335                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7336                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7337                        });
 7338                        (server_id, new_hints)
 7339                    })
 7340                    .collect::<HashMap<_, _>>();
 7341                anyhow::ensure!(
 7342                    !has_errors || !inlay_hints.is_empty(),
 7343                    "Failed to fetch inlay hints"
 7344                );
 7345                Ok(inlay_hints)
 7346            })
 7347        } else {
 7348            let inlay_hints_task = match for_server {
 7349                Some(server_id) => {
 7350                    let server_task = self.request_lsp(
 7351                        buffer.clone(),
 7352                        LanguageServerToQuery::Other(server_id),
 7353                        request,
 7354                        cx,
 7355                    );
 7356                    cx.background_spawn(async move {
 7357                        let mut responses = Vec::new();
 7358                        match server_task.await {
 7359                            Ok(response) => responses.push((server_id, response)),
 7360                            // rust-analyzer likes to error with this when its still loading up
 7361                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7362                            Err(e) => log::error!(
 7363                                "Error handling response for inlay hints request: {e:#}"
 7364                            ),
 7365                        }
 7366                        responses
 7367                    })
 7368                }
 7369                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7370            };
 7371            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7372            cx.background_spawn(async move {
 7373                Ok(inlay_hints_task
 7374                    .await
 7375                    .into_iter()
 7376                    .map(|(server_id, mut new_hints)| {
 7377                        new_hints.retain(|hint| {
 7378                            hint.position.is_valid(&buffer_snapshot)
 7379                                && range.start.is_valid(&buffer_snapshot)
 7380                                && range.end.is_valid(&buffer_snapshot)
 7381                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7382                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7383                        });
 7384                        (server_id, new_hints)
 7385                    })
 7386                    .collect())
 7387            })
 7388        }
 7389    }
 7390
 7391    fn diagnostic_registration_exists(
 7392        &self,
 7393        server_id: LanguageServerId,
 7394        registration_id: &Option<SharedString>,
 7395    ) -> bool {
 7396        let Some(local) = self.as_local() else {
 7397            return false;
 7398        };
 7399        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7400        else {
 7401            return false;
 7402        };
 7403        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7404        registrations.diagnostics.contains_key(&registration_key)
 7405    }
 7406
 7407    pub fn pull_diagnostics_for_buffer(
 7408        &mut self,
 7409        buffer: Entity<Buffer>,
 7410        cx: &mut Context<Self>,
 7411    ) -> Task<anyhow::Result<()>> {
 7412        let diagnostics = self.pull_diagnostics(buffer, cx);
 7413        cx.spawn(async move |lsp_store, cx| {
 7414            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7415                return Ok(());
 7416            };
 7417            lsp_store.update(cx, |lsp_store, cx| {
 7418                if lsp_store.as_local().is_none() {
 7419                    return;
 7420                }
 7421
 7422                let mut unchanged_buffers = HashMap::default();
 7423                let server_diagnostics_updates = diagnostics
 7424                    .into_iter()
 7425                    .filter_map(|diagnostics_set| match diagnostics_set {
 7426                        LspPullDiagnostics::Response {
 7427                            server_id,
 7428                            uri,
 7429                            diagnostics,
 7430                            registration_id,
 7431                        } => Some((server_id, uri, diagnostics, registration_id)),
 7432                        LspPullDiagnostics::Default => None,
 7433                    })
 7434                    .filter(|(server_id, _, _, registration_id)| {
 7435                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7436                    })
 7437                    .fold(
 7438                        HashMap::default(),
 7439                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7440                            let (result_id, diagnostics) = match diagnostics {
 7441                                PulledDiagnostics::Unchanged { result_id } => {
 7442                                    unchanged_buffers
 7443                                        .entry(new_registration_id.clone())
 7444                                        .or_insert_with(HashSet::default)
 7445                                        .insert(uri.clone());
 7446                                    (Some(result_id), Vec::new())
 7447                                }
 7448                                PulledDiagnostics::Changed {
 7449                                    result_id,
 7450                                    diagnostics,
 7451                                } => (result_id, diagnostics),
 7452                            };
 7453                            let disk_based_sources = Cow::Owned(
 7454                                lsp_store
 7455                                    .language_server_adapter_for_id(server_id)
 7456                                    .as_ref()
 7457                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7458                                    .unwrap_or(&[])
 7459                                    .to_vec(),
 7460                            );
 7461                            acc.entry(server_id)
 7462                                .or_insert_with(HashMap::default)
 7463                                .entry(new_registration_id.clone())
 7464                                .or_insert_with(Vec::new)
 7465                                .push(DocumentDiagnosticsUpdate {
 7466                                    server_id,
 7467                                    diagnostics: lsp::PublishDiagnosticsParams {
 7468                                        uri,
 7469                                        diagnostics,
 7470                                        version: None,
 7471                                    },
 7472                                    result_id: result_id.map(SharedString::new),
 7473                                    disk_based_sources,
 7474                                    registration_id: new_registration_id,
 7475                                });
 7476                            acc
 7477                        },
 7478                    );
 7479
 7480                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7481                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7482                        lsp_store
 7483                            .merge_lsp_diagnostics(
 7484                                DiagnosticSourceKind::Pulled,
 7485                                diagnostic_updates,
 7486                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7487                                    DiagnosticSourceKind::Pulled => {
 7488                                        old_diagnostic.registration_id != registration_id
 7489                                            || unchanged_buffers
 7490                                                .get(&old_diagnostic.registration_id)
 7491                                                .is_some_and(|unchanged_buffers| {
 7492                                                    unchanged_buffers.contains(&document_uri)
 7493                                                })
 7494                                    }
 7495                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7496                                        true
 7497                                    }
 7498                                },
 7499                                cx,
 7500                            )
 7501                            .log_err();
 7502                    }
 7503                }
 7504            })
 7505        })
 7506    }
 7507
 7508    pub fn signature_help<T: ToPointUtf16>(
 7509        &mut self,
 7510        buffer: &Entity<Buffer>,
 7511        position: T,
 7512        cx: &mut Context<Self>,
 7513    ) -> Task<Option<Vec<SignatureHelp>>> {
 7514        let position = position.to_point_utf16(buffer.read(cx));
 7515
 7516        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7517            let request = GetSignatureHelp { position };
 7518            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7519                return Task::ready(None);
 7520            }
 7521            let request_timeout = ProjectSettings::get_global(cx)
 7522                .global_lsp_settings
 7523                .get_request_timeout();
 7524            let request_task = client.request_lsp(
 7525                upstream_project_id,
 7526                None,
 7527                request_timeout,
 7528                cx.background_executor().clone(),
 7529                request.to_proto(upstream_project_id, buffer.read(cx)),
 7530            );
 7531            let buffer = buffer.clone();
 7532            cx.spawn(async move |weak_lsp_store, cx| {
 7533                let lsp_store = weak_lsp_store.upgrade()?;
 7534                let signatures = join_all(
 7535                    request_task
 7536                        .await
 7537                        .log_err()
 7538                        .flatten()
 7539                        .map(|response| response.payload)
 7540                        .unwrap_or_default()
 7541                        .into_iter()
 7542                        .map(|response| {
 7543                            let response = GetSignatureHelp { position }.response_from_proto(
 7544                                response.response,
 7545                                lsp_store.clone(),
 7546                                buffer.clone(),
 7547                                cx.clone(),
 7548                            );
 7549                            async move { response.await.log_err().flatten() }
 7550                        }),
 7551                )
 7552                .await
 7553                .into_iter()
 7554                .flatten()
 7555                .collect();
 7556                Some(signatures)
 7557            })
 7558        } else {
 7559            let all_actions_task = self.request_multiple_lsp_locally(
 7560                buffer,
 7561                Some(position),
 7562                GetSignatureHelp { position },
 7563                cx,
 7564            );
 7565            cx.background_spawn(async move {
 7566                Some(
 7567                    all_actions_task
 7568                        .await
 7569                        .into_iter()
 7570                        .flat_map(|(_, actions)| actions)
 7571                        .collect::<Vec<_>>(),
 7572                )
 7573            })
 7574        }
 7575    }
 7576
 7577    pub fn hover(
 7578        &mut self,
 7579        buffer: &Entity<Buffer>,
 7580        position: PointUtf16,
 7581        cx: &mut Context<Self>,
 7582    ) -> Task<Option<Vec<Hover>>> {
 7583        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7584            let request = GetHover { position };
 7585            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7586                return Task::ready(None);
 7587            }
 7588            let request_timeout = ProjectSettings::get_global(cx)
 7589                .global_lsp_settings
 7590                .get_request_timeout();
 7591            let request_task = client.request_lsp(
 7592                upstream_project_id,
 7593                None,
 7594                request_timeout,
 7595                cx.background_executor().clone(),
 7596                request.to_proto(upstream_project_id, buffer.read(cx)),
 7597            );
 7598            let buffer = buffer.clone();
 7599            cx.spawn(async move |weak_lsp_store, cx| {
 7600                let lsp_store = weak_lsp_store.upgrade()?;
 7601                let hovers = join_all(
 7602                    request_task
 7603                        .await
 7604                        .log_err()
 7605                        .flatten()
 7606                        .map(|response| response.payload)
 7607                        .unwrap_or_default()
 7608                        .into_iter()
 7609                        .map(|response| {
 7610                            let response = GetHover { position }.response_from_proto(
 7611                                response.response,
 7612                                lsp_store.clone(),
 7613                                buffer.clone(),
 7614                                cx.clone(),
 7615                            );
 7616                            async move {
 7617                                response
 7618                                    .await
 7619                                    .log_err()
 7620                                    .flatten()
 7621                                    .and_then(remove_empty_hover_blocks)
 7622                            }
 7623                        }),
 7624                )
 7625                .await
 7626                .into_iter()
 7627                .flatten()
 7628                .collect();
 7629                Some(hovers)
 7630            })
 7631        } else {
 7632            let all_actions_task = self.request_multiple_lsp_locally(
 7633                buffer,
 7634                Some(position),
 7635                GetHover { position },
 7636                cx,
 7637            );
 7638            cx.background_spawn(async move {
 7639                Some(
 7640                    all_actions_task
 7641                        .await
 7642                        .into_iter()
 7643                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7644                        .collect::<Vec<Hover>>(),
 7645                )
 7646            })
 7647        }
 7648    }
 7649
 7650    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7651        let language_registry = self.languages.clone();
 7652
 7653        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7654            let request = upstream_client.request(proto::GetProjectSymbols {
 7655                project_id: *project_id,
 7656                query: query.to_string(),
 7657            });
 7658            cx.foreground_executor().spawn(async move {
 7659                let response = request.await?;
 7660                let mut symbols = Vec::new();
 7661                let core_symbols = response
 7662                    .symbols
 7663                    .into_iter()
 7664                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7665                    .collect::<Vec<_>>();
 7666                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7667                    .await;
 7668                Ok(symbols)
 7669            })
 7670        } else if let Some(local) = self.as_local() {
 7671            struct WorkspaceSymbolsResult {
 7672                server_id: LanguageServerId,
 7673                lsp_adapter: Arc<CachedLspAdapter>,
 7674                worktree: WeakEntity<Worktree>,
 7675                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7676            }
 7677
 7678            let mut requests = Vec::new();
 7679            let mut requested_servers = BTreeSet::new();
 7680            let request_timeout = ProjectSettings::get_global(cx)
 7681                .global_lsp_settings
 7682                .get_request_timeout();
 7683
 7684            for (seed, state) in local.language_server_ids.iter() {
 7685                let Some(worktree_handle) = self
 7686                    .worktree_store
 7687                    .read(cx)
 7688                    .worktree_for_id(seed.worktree_id, cx)
 7689                else {
 7690                    continue;
 7691                };
 7692
 7693                let worktree = worktree_handle.read(cx);
 7694                if !worktree.is_visible() {
 7695                    continue;
 7696                }
 7697
 7698                if !requested_servers.insert(state.id) {
 7699                    continue;
 7700                }
 7701
 7702                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7703                    Some(LanguageServerState::Running {
 7704                        adapter, server, ..
 7705                    }) => (adapter.clone(), server),
 7706
 7707                    _ => continue,
 7708                };
 7709
 7710                let supports_workspace_symbol_request =
 7711                    match server.capabilities().workspace_symbol_provider {
 7712                        Some(OneOf::Left(supported)) => supported,
 7713                        Some(OneOf::Right(_)) => true,
 7714                        None => false,
 7715                    };
 7716
 7717                if !supports_workspace_symbol_request {
 7718                    continue;
 7719                }
 7720
 7721                let worktree_handle = worktree_handle.clone();
 7722                let server_id = server.server_id();
 7723                requests.push(
 7724                    server
 7725                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7726                            lsp::WorkspaceSymbolParams {
 7727                                query: query.to_string(),
 7728                                ..Default::default()
 7729                            },
 7730                            request_timeout,
 7731                        )
 7732                        .map(move |response| {
 7733                            let lsp_symbols = response
 7734                                .into_response()
 7735                                .context("workspace symbols request")
 7736                                .log_err()
 7737                                .flatten()
 7738                                .map(|symbol_response| match symbol_response {
 7739                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7740                                        flat_responses
 7741                                            .into_iter()
 7742                                            .map(|lsp_symbol| {
 7743                                                (
 7744                                                    lsp_symbol.name,
 7745                                                    lsp_symbol.kind,
 7746                                                    lsp_symbol.location,
 7747                                                    lsp_symbol.container_name,
 7748                                                )
 7749                                            })
 7750                                            .collect::<Vec<_>>()
 7751                                    }
 7752                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7753                                        nested_responses
 7754                                            .into_iter()
 7755                                            .filter_map(|lsp_symbol| {
 7756                                                let location = match lsp_symbol.location {
 7757                                                    OneOf::Left(location) => location,
 7758                                                    OneOf::Right(_) => {
 7759                                                        log::error!(
 7760                                                            "Unexpected: client capabilities \
 7761                                                            forbid symbol resolutions in \
 7762                                                            workspace.symbol.resolveSupport"
 7763                                                        );
 7764                                                        return None;
 7765                                                    }
 7766                                                };
 7767                                                Some((
 7768                                                    lsp_symbol.name,
 7769                                                    lsp_symbol.kind,
 7770                                                    location,
 7771                                                    lsp_symbol.container_name,
 7772                                                ))
 7773                                            })
 7774                                            .collect::<Vec<_>>()
 7775                                    }
 7776                                })
 7777                                .unwrap_or_default();
 7778
 7779                            WorkspaceSymbolsResult {
 7780                                server_id,
 7781                                lsp_adapter,
 7782                                worktree: worktree_handle.downgrade(),
 7783                                lsp_symbols,
 7784                            }
 7785                        }),
 7786                );
 7787            }
 7788
 7789            cx.spawn(async move |this, cx| {
 7790                let responses = futures::future::join_all(requests).await;
 7791                let this = match this.upgrade() {
 7792                    Some(this) => this,
 7793                    None => return Ok(Vec::new()),
 7794                };
 7795
 7796                let mut symbols = Vec::new();
 7797                for result in responses {
 7798                    let core_symbols = this.update(cx, |this, cx| {
 7799                        result
 7800                            .lsp_symbols
 7801                            .into_iter()
 7802                            .filter_map(
 7803                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7804                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7805                                    let source_worktree = result.worktree.upgrade()?;
 7806                                    let source_worktree_id = source_worktree.read(cx).id();
 7807
 7808                                    let path = if let Some((tree, rel_path)) =
 7809                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7810                                    {
 7811                                        let worktree_id = tree.read(cx).id();
 7812                                        SymbolLocation::InProject(ProjectPath {
 7813                                            worktree_id,
 7814                                            path: rel_path,
 7815                                        })
 7816                                    } else {
 7817                                        SymbolLocation::OutsideProject {
 7818                                            signature: this.symbol_signature(&abs_path),
 7819                                            abs_path: abs_path.into(),
 7820                                        }
 7821                                    };
 7822
 7823                                    Some(CoreSymbol {
 7824                                        source_language_server_id: result.server_id,
 7825                                        language_server_name: result.lsp_adapter.name.clone(),
 7826                                        source_worktree_id,
 7827                                        path,
 7828                                        kind: symbol_kind,
 7829                                        name: collapse_newlines(&symbol_name, ""),
 7830                                        range: range_from_lsp(symbol_location.range),
 7831                                        container_name: container_name
 7832                                            .map(|c| collapse_newlines(&c, "")),
 7833                                    })
 7834                                },
 7835                            )
 7836                            .collect::<Vec<_>>()
 7837                    });
 7838
 7839                    populate_labels_for_symbols(
 7840                        core_symbols,
 7841                        &language_registry,
 7842                        Some(result.lsp_adapter),
 7843                        &mut symbols,
 7844                    )
 7845                    .await;
 7846                }
 7847
 7848                Ok(symbols)
 7849            })
 7850        } else {
 7851            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7852        }
 7853    }
 7854
 7855    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7856        let mut summary = DiagnosticSummary::default();
 7857        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7858            summary.error_count += path_summary.error_count;
 7859            summary.warning_count += path_summary.warning_count;
 7860        }
 7861        summary
 7862    }
 7863
 7864    /// Returns the diagnostic summary for a specific project path.
 7865    pub fn diagnostic_summary_for_path(
 7866        &self,
 7867        project_path: &ProjectPath,
 7868        _: &App,
 7869    ) -> DiagnosticSummary {
 7870        if let Some(summaries) = self
 7871            .diagnostic_summaries
 7872            .get(&project_path.worktree_id)
 7873            .and_then(|map| map.get(&project_path.path))
 7874        {
 7875            let (error_count, warning_count) = summaries.iter().fold(
 7876                (0, 0),
 7877                |(error_count, warning_count), (_language_server_id, summary)| {
 7878                    (
 7879                        error_count + summary.error_count,
 7880                        warning_count + summary.warning_count,
 7881                    )
 7882                },
 7883            );
 7884
 7885            DiagnosticSummary {
 7886                error_count,
 7887                warning_count,
 7888            }
 7889        } else {
 7890            DiagnosticSummary::default()
 7891        }
 7892    }
 7893
 7894    pub fn diagnostic_summaries<'a>(
 7895        &'a self,
 7896        include_ignored: bool,
 7897        cx: &'a App,
 7898    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7899        self.worktree_store
 7900            .read(cx)
 7901            .visible_worktrees(cx)
 7902            .filter_map(|worktree| {
 7903                let worktree = worktree.read(cx);
 7904                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7905            })
 7906            .flat_map(move |(worktree, summaries)| {
 7907                let worktree_id = worktree.id();
 7908                summaries
 7909                    .iter()
 7910                    .filter(move |(path, _)| {
 7911                        include_ignored
 7912                            || worktree
 7913                                .entry_for_path(path.as_ref())
 7914                                .is_some_and(|entry| !entry.is_ignored)
 7915                    })
 7916                    .flat_map(move |(path, summaries)| {
 7917                        summaries.iter().map(move |(server_id, summary)| {
 7918                            (
 7919                                ProjectPath {
 7920                                    worktree_id,
 7921                                    path: path.clone(),
 7922                                },
 7923                                *server_id,
 7924                                *summary,
 7925                            )
 7926                        })
 7927                    })
 7928            })
 7929    }
 7930
 7931    pub fn on_buffer_edited(
 7932        &mut self,
 7933        buffer: Entity<Buffer>,
 7934        cx: &mut Context<Self>,
 7935    ) -> Option<()> {
 7936        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7937            Some(
 7938                self.as_local()?
 7939                    .language_servers_for_buffer(buffer, cx)
 7940                    .map(|i| i.1.clone())
 7941                    .collect(),
 7942            )
 7943        })?;
 7944
 7945        let buffer = buffer.read(cx);
 7946        let file = File::from_dyn(buffer.file())?;
 7947        let abs_path = file.as_local()?.abs_path(cx);
 7948        let uri = lsp::Uri::from_file_path(&abs_path)
 7949            .ok()
 7950            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7951            .log_err()?;
 7952        let next_snapshot = buffer.text_snapshot();
 7953        for language_server in language_servers {
 7954            let language_server = language_server.clone();
 7955
 7956            let buffer_snapshots = self
 7957                .as_local_mut()?
 7958                .buffer_snapshots
 7959                .get_mut(&buffer.remote_id())
 7960                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7961            let previous_snapshot = buffer_snapshots.last()?;
 7962
 7963            let build_incremental_change = || {
 7964                buffer
 7965                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7966                        previous_snapshot.snapshot.version(),
 7967                    )
 7968                    .map(|edit| {
 7969                        let edit_start = edit.new.start.0;
 7970                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7971                        let new_text = next_snapshot
 7972                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7973                            .collect();
 7974                        lsp::TextDocumentContentChangeEvent {
 7975                            range: Some(lsp::Range::new(
 7976                                point_to_lsp(edit_start),
 7977                                point_to_lsp(edit_end),
 7978                            )),
 7979                            range_length: None,
 7980                            text: new_text,
 7981                        }
 7982                    })
 7983                    .collect()
 7984            };
 7985
 7986            let document_sync_kind = language_server
 7987                .capabilities()
 7988                .text_document_sync
 7989                .as_ref()
 7990                .and_then(|sync| match sync {
 7991                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7992                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7993                });
 7994
 7995            let content_changes: Vec<_> = match document_sync_kind {
 7996                Some(lsp::TextDocumentSyncKind::FULL) => {
 7997                    vec![lsp::TextDocumentContentChangeEvent {
 7998                        range: None,
 7999                        range_length: None,
 8000                        text: next_snapshot.text(),
 8001                    }]
 8002                }
 8003                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8004                _ => {
 8005                    #[cfg(any(test, feature = "test-support"))]
 8006                    {
 8007                        build_incremental_change()
 8008                    }
 8009
 8010                    #[cfg(not(any(test, feature = "test-support")))]
 8011                    {
 8012                        continue;
 8013                    }
 8014                }
 8015            };
 8016
 8017            let next_version = previous_snapshot.version + 1;
 8018            buffer_snapshots.push(LspBufferSnapshot {
 8019                version: next_version,
 8020                snapshot: next_snapshot.clone(),
 8021            });
 8022
 8023            language_server
 8024                .notify::<lsp::notification::DidChangeTextDocument>(
 8025                    lsp::DidChangeTextDocumentParams {
 8026                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8027                            uri.clone(),
 8028                            next_version,
 8029                        ),
 8030                        content_changes,
 8031                    },
 8032                )
 8033                .ok();
 8034            self.pull_workspace_diagnostics(language_server.server_id());
 8035        }
 8036
 8037        None
 8038    }
 8039
 8040    pub fn on_buffer_saved(
 8041        &mut self,
 8042        buffer: Entity<Buffer>,
 8043        cx: &mut Context<Self>,
 8044    ) -> Option<()> {
 8045        let file = File::from_dyn(buffer.read(cx).file())?;
 8046        let worktree_id = file.worktree_id(cx);
 8047        let abs_path = file.as_local()?.abs_path(cx);
 8048        let text_document = lsp::TextDocumentIdentifier {
 8049            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8050        };
 8051        let local = self.as_local()?;
 8052
 8053        for server in local.language_servers_for_worktree(worktree_id) {
 8054            if let Some(include_text) = include_text(server.as_ref()) {
 8055                let text = if include_text {
 8056                    Some(buffer.read(cx).text())
 8057                } else {
 8058                    None
 8059                };
 8060                server
 8061                    .notify::<lsp::notification::DidSaveTextDocument>(
 8062                        lsp::DidSaveTextDocumentParams {
 8063                            text_document: text_document.clone(),
 8064                            text,
 8065                        },
 8066                    )
 8067                    .ok();
 8068            }
 8069        }
 8070
 8071        let language_servers = buffer.update(cx, |buffer, cx| {
 8072            local.language_server_ids_for_buffer(buffer, cx)
 8073        });
 8074        for language_server_id in language_servers {
 8075            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8076        }
 8077
 8078        None
 8079    }
 8080
 8081    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8082        maybe!(async move {
 8083            let mut refreshed_servers = HashSet::default();
 8084            let servers = lsp_store
 8085                .update(cx, |lsp_store, cx| {
 8086                    let local = lsp_store.as_local()?;
 8087
 8088                    let servers = local
 8089                        .language_server_ids
 8090                        .iter()
 8091                        .filter_map(|(seed, state)| {
 8092                            let worktree = lsp_store
 8093                                .worktree_store
 8094                                .read(cx)
 8095                                .worktree_for_id(seed.worktree_id, cx);
 8096                            let delegate: Arc<dyn LspAdapterDelegate> =
 8097                                worktree.map(|worktree| {
 8098                                    LocalLspAdapterDelegate::new(
 8099                                        local.languages.clone(),
 8100                                        &local.environment,
 8101                                        cx.weak_entity(),
 8102                                        &worktree,
 8103                                        local.http_client.clone(),
 8104                                        local.fs.clone(),
 8105                                        cx,
 8106                                    )
 8107                                })?;
 8108                            let server_id = state.id;
 8109
 8110                            let states = local.language_servers.get(&server_id)?;
 8111
 8112                            match states {
 8113                                LanguageServerState::Starting { .. } => None,
 8114                                LanguageServerState::Running {
 8115                                    adapter, server, ..
 8116                                } => {
 8117                                    let adapter = adapter.clone();
 8118                                    let server = server.clone();
 8119                                    refreshed_servers.insert(server.name());
 8120                                    let toolchain = seed.toolchain.clone();
 8121                                    Some(cx.spawn(async move |_, cx| {
 8122                                        let settings =
 8123                                            LocalLspStore::workspace_configuration_for_adapter(
 8124                                                adapter.adapter.clone(),
 8125                                                &delegate,
 8126                                                toolchain,
 8127                                                None,
 8128                                                cx,
 8129                                            )
 8130                                            .await
 8131                                            .ok()?;
 8132                                        server
 8133                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8134                                                lsp::DidChangeConfigurationParams { settings },
 8135                                            )
 8136                                            .ok()?;
 8137                                        Some(())
 8138                                    }))
 8139                                }
 8140                            }
 8141                        })
 8142                        .collect::<Vec<_>>();
 8143
 8144                    Some(servers)
 8145                })
 8146                .ok()
 8147                .flatten()?;
 8148
 8149            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8150            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8151            // to stop and unregister its language server wrapper.
 8152            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8153            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8154            let _: Vec<Option<()>> = join_all(servers).await;
 8155
 8156            Some(())
 8157        })
 8158        .await;
 8159    }
 8160
 8161    fn maintain_workspace_config(
 8162        external_refresh_requests: watch::Receiver<()>,
 8163        cx: &mut Context<Self>,
 8164    ) -> Task<Result<()>> {
 8165        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8166        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8167
 8168        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8169            *settings_changed_tx.borrow_mut() = ();
 8170        });
 8171
 8172        let mut joint_future =
 8173            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8174        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8175        // - 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).
 8176        // - 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.
 8177        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8178        // - 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,
 8179        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8180        cx.spawn(async move |this, cx| {
 8181            while let Some(()) = joint_future.next().await {
 8182                this.update(cx, |this, cx| {
 8183                    this.refresh_server_tree(cx);
 8184                })
 8185                .ok();
 8186
 8187                Self::refresh_workspace_configurations(&this, cx).await;
 8188            }
 8189
 8190            drop(settings_observation);
 8191            anyhow::Ok(())
 8192        })
 8193    }
 8194
 8195    pub fn running_language_servers_for_local_buffer<'a>(
 8196        &'a self,
 8197        buffer: &Buffer,
 8198        cx: &mut App,
 8199    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8200        let local = self.as_local();
 8201        let language_server_ids = local
 8202            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8203            .unwrap_or_default();
 8204
 8205        language_server_ids
 8206            .into_iter()
 8207            .filter_map(
 8208                move |server_id| match local?.language_servers.get(&server_id)? {
 8209                    LanguageServerState::Running {
 8210                        adapter, server, ..
 8211                    } => Some((adapter, server)),
 8212                    _ => None,
 8213                },
 8214            )
 8215    }
 8216
 8217    pub fn language_servers_for_local_buffer(
 8218        &self,
 8219        buffer: &Buffer,
 8220        cx: &mut App,
 8221    ) -> Vec<LanguageServerId> {
 8222        let local = self.as_local();
 8223        local
 8224            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8225            .unwrap_or_default()
 8226    }
 8227
 8228    pub fn language_server_for_local_buffer<'a>(
 8229        &'a self,
 8230        buffer: &'a Buffer,
 8231        server_id: LanguageServerId,
 8232        cx: &'a mut App,
 8233    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8234        self.as_local()?
 8235            .language_servers_for_buffer(buffer, cx)
 8236            .find(|(_, s)| s.server_id() == server_id)
 8237    }
 8238
 8239    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8240        self.diagnostic_summaries.remove(&id_to_remove);
 8241        if let Some(local) = self.as_local_mut() {
 8242            let to_remove = local.remove_worktree(id_to_remove, cx);
 8243            for server in to_remove {
 8244                self.language_server_statuses.remove(&server);
 8245            }
 8246        }
 8247    }
 8248
 8249    fn invalidate_diagnostic_summaries_for_removed_entries(
 8250        &mut self,
 8251        worktree_id: WorktreeId,
 8252        changes: &UpdatedEntriesSet,
 8253        cx: &mut Context<Self>,
 8254    ) {
 8255        let Some(summaries_for_tree) = self.diagnostic_summaries.get_mut(&worktree_id) else {
 8256            return;
 8257        };
 8258
 8259        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
 8260        let mut cleared_server_ids: HashSet<LanguageServerId> = HashSet::default();
 8261        let downstream = self.downstream_client.clone();
 8262
 8263        for (path, _, _) in changes
 8264            .iter()
 8265            .filter(|(_, _, change)| *change == PathChange::Removed)
 8266        {
 8267            if let Some(summaries_by_server_id) = summaries_for_tree.remove(path) {
 8268                for (server_id, _) in &summaries_by_server_id {
 8269                    cleared_server_ids.insert(*server_id);
 8270                    if let Some((client, project_id)) = &downstream {
 8271                        client
 8272                            .send(proto::UpdateDiagnosticSummary {
 8273                                project_id: *project_id,
 8274                                worktree_id: worktree_id.to_proto(),
 8275                                summary: Some(proto::DiagnosticSummary {
 8276                                    path: path.as_ref().to_proto(),
 8277                                    language_server_id: server_id.0 as u64,
 8278                                    error_count: 0,
 8279                                    warning_count: 0,
 8280                                }),
 8281                                more_summaries: Vec::new(),
 8282                            })
 8283                            .ok();
 8284                    }
 8285                }
 8286                cleared_paths.push(ProjectPath {
 8287                    worktree_id,
 8288                    path: path.clone(),
 8289                });
 8290            }
 8291        }
 8292
 8293        if !cleared_paths.is_empty() {
 8294            for server_id in cleared_server_ids {
 8295                cx.emit(LspStoreEvent::DiagnosticsUpdated {
 8296                    server_id,
 8297                    paths: cleared_paths.clone(),
 8298                });
 8299            }
 8300        }
 8301    }
 8302
 8303    pub fn shared(
 8304        &mut self,
 8305        project_id: u64,
 8306        downstream_client: AnyProtoClient,
 8307        _: &mut Context<Self>,
 8308    ) {
 8309        self.downstream_client = Some((downstream_client.clone(), project_id));
 8310
 8311        for (server_id, status) in &self.language_server_statuses {
 8312            if let Some(server) = self.language_server_for_id(*server_id) {
 8313                downstream_client
 8314                    .send(proto::StartLanguageServer {
 8315                        project_id,
 8316                        server: Some(proto::LanguageServer {
 8317                            id: server_id.to_proto(),
 8318                            name: status.name.to_string(),
 8319                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8320                        }),
 8321                        capabilities: serde_json::to_string(&server.capabilities())
 8322                            .expect("serializing server LSP capabilities"),
 8323                    })
 8324                    .log_err();
 8325            }
 8326        }
 8327    }
 8328
 8329    pub fn disconnected_from_host(&mut self) {
 8330        self.downstream_client.take();
 8331    }
 8332
 8333    pub fn disconnected_from_ssh_remote(&mut self) {
 8334        if let LspStoreMode::Remote(RemoteLspStore {
 8335            upstream_client, ..
 8336        }) = &mut self.mode
 8337        {
 8338            upstream_client.take();
 8339        }
 8340    }
 8341
 8342    pub(crate) fn set_language_server_statuses_from_proto(
 8343        &mut self,
 8344        project: WeakEntity<Project>,
 8345        language_servers: Vec<proto::LanguageServer>,
 8346        server_capabilities: Vec<String>,
 8347        cx: &mut Context<Self>,
 8348    ) {
 8349        let lsp_logs = cx
 8350            .try_global::<GlobalLogStore>()
 8351            .map(|lsp_store| lsp_store.0.clone());
 8352
 8353        self.language_server_statuses = language_servers
 8354            .into_iter()
 8355            .zip(server_capabilities)
 8356            .map(|(server, server_capabilities)| {
 8357                let server_id = LanguageServerId(server.id as usize);
 8358                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8359                    self.lsp_server_capabilities
 8360                        .insert(server_id, server_capabilities);
 8361                }
 8362
 8363                let name = LanguageServerName::from_proto(server.name);
 8364                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8365
 8366                if let Some(lsp_logs) = &lsp_logs {
 8367                    lsp_logs.update(cx, |lsp_logs, cx| {
 8368                        lsp_logs.add_language_server(
 8369                            // Only remote clients get their language servers set from proto
 8370                            LanguageServerKind::Remote {
 8371                                project: project.clone(),
 8372                            },
 8373                            server_id,
 8374                            Some(name.clone()),
 8375                            worktree,
 8376                            None,
 8377                            cx,
 8378                        );
 8379                    });
 8380                }
 8381
 8382                (
 8383                    server_id,
 8384                    LanguageServerStatus {
 8385                        name,
 8386                        server_version: None,
 8387                        server_readable_version: None,
 8388                        pending_work: Default::default(),
 8389                        has_pending_diagnostic_updates: false,
 8390                        progress_tokens: Default::default(),
 8391                        worktree,
 8392                        binary: None,
 8393                        configuration: None,
 8394                        workspace_folders: BTreeSet::new(),
 8395                        process_id: None,
 8396                    },
 8397                )
 8398            })
 8399            .collect();
 8400    }
 8401
 8402    #[cfg(feature = "test-support")]
 8403    pub fn update_diagnostic_entries(
 8404        &mut self,
 8405        server_id: LanguageServerId,
 8406        abs_path: PathBuf,
 8407        result_id: Option<SharedString>,
 8408        version: Option<i32>,
 8409        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8410        cx: &mut Context<Self>,
 8411    ) -> anyhow::Result<()> {
 8412        self.merge_diagnostic_entries(
 8413            vec![DocumentDiagnosticsUpdate {
 8414                diagnostics: DocumentDiagnostics {
 8415                    diagnostics,
 8416                    document_abs_path: abs_path,
 8417                    version,
 8418                },
 8419                result_id,
 8420                server_id,
 8421                disk_based_sources: Cow::Borrowed(&[]),
 8422                registration_id: None,
 8423            }],
 8424            |_, _, _| false,
 8425            cx,
 8426        )?;
 8427        Ok(())
 8428    }
 8429
 8430    pub fn merge_diagnostic_entries<'a>(
 8431        &mut self,
 8432        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8433        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8434        cx: &mut Context<Self>,
 8435    ) -> anyhow::Result<()> {
 8436        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8437        let mut updated_diagnostics_paths = HashMap::default();
 8438        for mut update in diagnostic_updates {
 8439            let abs_path = &update.diagnostics.document_abs_path;
 8440            let server_id = update.server_id;
 8441            let Some((worktree, relative_path)) =
 8442                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8443            else {
 8444                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8445                return Ok(());
 8446            };
 8447
 8448            let worktree_id = worktree.read(cx).id();
 8449            let project_path = ProjectPath {
 8450                worktree_id,
 8451                path: relative_path,
 8452            };
 8453
 8454            let document_uri = lsp::Uri::from_file_path(abs_path)
 8455                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8456            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8457                let snapshot = buffer_handle.read(cx).snapshot();
 8458                let buffer = buffer_handle.read(cx);
 8459                let reused_diagnostics = buffer
 8460                    .buffer_diagnostics(Some(server_id))
 8461                    .iter()
 8462                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8463                    .map(|v| {
 8464                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8465                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8466                        DiagnosticEntry {
 8467                            range: start..end,
 8468                            diagnostic: v.diagnostic.clone(),
 8469                        }
 8470                    })
 8471                    .collect::<Vec<_>>();
 8472
 8473                self.as_local_mut()
 8474                    .context("cannot merge diagnostics on a remote LspStore")?
 8475                    .update_buffer_diagnostics(
 8476                        &buffer_handle,
 8477                        server_id,
 8478                        Some(update.registration_id),
 8479                        update.result_id,
 8480                        update.diagnostics.version,
 8481                        update.diagnostics.diagnostics.clone(),
 8482                        reused_diagnostics.clone(),
 8483                        cx,
 8484                    )?;
 8485
 8486                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8487            } else if let Some(local) = self.as_local() {
 8488                let reused_diagnostics = local
 8489                    .diagnostics
 8490                    .get(&worktree_id)
 8491                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8492                    .and_then(|diagnostics_by_server_id| {
 8493                        diagnostics_by_server_id
 8494                            .binary_search_by_key(&server_id, |e| e.0)
 8495                            .ok()
 8496                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8497                    })
 8498                    .into_iter()
 8499                    .flatten()
 8500                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8501
 8502                update
 8503                    .diagnostics
 8504                    .diagnostics
 8505                    .extend(reused_diagnostics.cloned());
 8506            }
 8507
 8508            let updated = worktree.update(cx, |worktree, cx| {
 8509                self.update_worktree_diagnostics(
 8510                    worktree.id(),
 8511                    server_id,
 8512                    project_path.path.clone(),
 8513                    update.diagnostics.diagnostics,
 8514                    cx,
 8515                )
 8516            })?;
 8517            match updated {
 8518                ControlFlow::Continue(new_summary) => {
 8519                    if let Some((project_id, new_summary)) = new_summary {
 8520                        match &mut diagnostics_summary {
 8521                            Some(diagnostics_summary) => {
 8522                                diagnostics_summary
 8523                                    .more_summaries
 8524                                    .push(proto::DiagnosticSummary {
 8525                                        path: project_path.path.as_ref().to_proto(),
 8526                                        language_server_id: server_id.0 as u64,
 8527                                        error_count: new_summary.error_count,
 8528                                        warning_count: new_summary.warning_count,
 8529                                    })
 8530                            }
 8531                            None => {
 8532                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8533                                    project_id,
 8534                                    worktree_id: worktree_id.to_proto(),
 8535                                    summary: Some(proto::DiagnosticSummary {
 8536                                        path: project_path.path.as_ref().to_proto(),
 8537                                        language_server_id: server_id.0 as u64,
 8538                                        error_count: new_summary.error_count,
 8539                                        warning_count: new_summary.warning_count,
 8540                                    }),
 8541                                    more_summaries: Vec::new(),
 8542                                })
 8543                            }
 8544                        }
 8545                    }
 8546                    updated_diagnostics_paths
 8547                        .entry(server_id)
 8548                        .or_insert_with(Vec::new)
 8549                        .push(project_path);
 8550                }
 8551                ControlFlow::Break(()) => {}
 8552            }
 8553        }
 8554
 8555        if let Some((diagnostics_summary, (downstream_client, _))) =
 8556            diagnostics_summary.zip(self.downstream_client.as_ref())
 8557        {
 8558            downstream_client.send(diagnostics_summary).log_err();
 8559        }
 8560        for (server_id, paths) in updated_diagnostics_paths {
 8561            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8562        }
 8563        Ok(())
 8564    }
 8565
 8566    fn update_worktree_diagnostics(
 8567        &mut self,
 8568        worktree_id: WorktreeId,
 8569        server_id: LanguageServerId,
 8570        path_in_worktree: Arc<RelPath>,
 8571        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8572        _: &mut Context<Worktree>,
 8573    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8574        let local = match &mut self.mode {
 8575            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8576            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8577        };
 8578
 8579        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8580        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8581        let summaries_by_server_id = summaries_for_tree
 8582            .entry(path_in_worktree.clone())
 8583            .or_default();
 8584
 8585        let old_summary = summaries_by_server_id
 8586            .remove(&server_id)
 8587            .unwrap_or_default();
 8588
 8589        let new_summary = DiagnosticSummary::new(&diagnostics);
 8590        if diagnostics.is_empty() {
 8591            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8592            {
 8593                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8594                    diagnostics_by_server_id.remove(ix);
 8595                }
 8596                if diagnostics_by_server_id.is_empty() {
 8597                    diagnostics_for_tree.remove(&path_in_worktree);
 8598                }
 8599            }
 8600        } else {
 8601            summaries_by_server_id.insert(server_id, new_summary);
 8602            let diagnostics_by_server_id = diagnostics_for_tree
 8603                .entry(path_in_worktree.clone())
 8604                .or_default();
 8605            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8606                Ok(ix) => {
 8607                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8608                }
 8609                Err(ix) => {
 8610                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8611                }
 8612            }
 8613        }
 8614
 8615        if !old_summary.is_empty() || !new_summary.is_empty() {
 8616            if let Some((_, project_id)) = &self.downstream_client {
 8617                Ok(ControlFlow::Continue(Some((
 8618                    *project_id,
 8619                    proto::DiagnosticSummary {
 8620                        path: path_in_worktree.to_proto(),
 8621                        language_server_id: server_id.0 as u64,
 8622                        error_count: new_summary.error_count as u32,
 8623                        warning_count: new_summary.warning_count as u32,
 8624                    },
 8625                ))))
 8626            } else {
 8627                Ok(ControlFlow::Continue(None))
 8628            }
 8629        } else {
 8630            Ok(ControlFlow::Break(()))
 8631        }
 8632    }
 8633
 8634    pub fn open_buffer_for_symbol(
 8635        &mut self,
 8636        symbol: &Symbol,
 8637        cx: &mut Context<Self>,
 8638    ) -> Task<Result<Entity<Buffer>>> {
 8639        if let Some((client, project_id)) = self.upstream_client() {
 8640            let request = client.request(proto::OpenBufferForSymbol {
 8641                project_id,
 8642                symbol: Some(Self::serialize_symbol(symbol)),
 8643            });
 8644            cx.spawn(async move |this, cx| {
 8645                let response = request.await?;
 8646                let buffer_id = BufferId::new(response.buffer_id)?;
 8647                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8648                    .await
 8649            })
 8650        } else if let Some(local) = self.as_local() {
 8651            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8652                seed.worktree_id == symbol.source_worktree_id
 8653                    && state.id == symbol.source_language_server_id
 8654                    && symbol.language_server_name == seed.name
 8655            });
 8656            if !is_valid {
 8657                return Task::ready(Err(anyhow!(
 8658                    "language server for worktree and language not found"
 8659                )));
 8660            };
 8661
 8662            let symbol_abs_path = match &symbol.path {
 8663                SymbolLocation::InProject(project_path) => self
 8664                    .worktree_store
 8665                    .read(cx)
 8666                    .absolutize(&project_path, cx)
 8667                    .context("no such worktree"),
 8668                SymbolLocation::OutsideProject {
 8669                    abs_path,
 8670                    signature: _,
 8671                } => Ok(abs_path.to_path_buf()),
 8672            };
 8673            let symbol_abs_path = match symbol_abs_path {
 8674                Ok(abs_path) => abs_path,
 8675                Err(err) => return Task::ready(Err(err)),
 8676            };
 8677            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8678                uri
 8679            } else {
 8680                return Task::ready(Err(anyhow!("invalid symbol path")));
 8681            };
 8682
 8683            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8684        } else {
 8685            Task::ready(Err(anyhow!("no upstream client or local store")))
 8686        }
 8687    }
 8688
 8689    pub(crate) fn open_local_buffer_via_lsp(
 8690        &mut self,
 8691        abs_path: lsp::Uri,
 8692        language_server_id: LanguageServerId,
 8693        cx: &mut Context<Self>,
 8694    ) -> Task<Result<Entity<Buffer>>> {
 8695        let path_style = self.worktree_store.read(cx).path_style();
 8696        cx.spawn(async move |lsp_store, cx| {
 8697            // Escape percent-encoded string.
 8698            let current_scheme = abs_path.scheme().to_owned();
 8699            // Uri is immutable, so we can't modify the scheme
 8700
 8701            let abs_path = abs_path
 8702                .to_file_path_ext(path_style)
 8703                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8704            let p = abs_path.clone();
 8705            let yarn_worktree = lsp_store
 8706                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8707                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8708                        cx.spawn(async move |this, cx| {
 8709                            let t = this
 8710                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8711                                .ok()?;
 8712                            t.await
 8713                        })
 8714                    }),
 8715                    None => Task::ready(None),
 8716                })?
 8717                .await;
 8718            let (worktree_root_target, known_relative_path) =
 8719                if let Some((zip_root, relative_path)) = yarn_worktree {
 8720                    (zip_root, Some(relative_path))
 8721                } else {
 8722                    (Arc::<Path>::from(abs_path.as_path()), None)
 8723                };
 8724            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8725                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8726                    worktree_store.find_worktree(&worktree_root_target, cx)
 8727                })
 8728            })?;
 8729            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8730                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8731                (result.0, relative_path, None)
 8732            } else {
 8733                let worktree = lsp_store
 8734                    .update(cx, |lsp_store, cx| {
 8735                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8736                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8737                        })
 8738                    })?
 8739                    .await?;
 8740                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8741                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8742                    lsp_store
 8743                        .update(cx, |lsp_store, cx| {
 8744                            if let Some(local) = lsp_store.as_local_mut() {
 8745                                local.register_language_server_for_invisible_worktree(
 8746                                    &worktree,
 8747                                    language_server_id,
 8748                                    cx,
 8749                                )
 8750                            }
 8751                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8752                                Some(status) => status.worktree,
 8753                                None => None,
 8754                            }
 8755                        })
 8756                        .ok()
 8757                        .flatten()
 8758                        .zip(Some(worktree_root.clone()))
 8759                } else {
 8760                    None
 8761                };
 8762                let relative_path = if let Some(known_path) = known_relative_path {
 8763                    known_path
 8764                } else {
 8765                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8766                        .into_arc()
 8767                };
 8768                (worktree, relative_path, source_ws)
 8769            };
 8770            let project_path = ProjectPath {
 8771                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8772                path: relative_path,
 8773            };
 8774            let buffer = lsp_store
 8775                .update(cx, |lsp_store, cx| {
 8776                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8777                        buffer_store.open_buffer(project_path, cx)
 8778                    })
 8779                })?
 8780                .await?;
 8781            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8782            if let Some((source_ws, worktree_root)) = source_ws {
 8783                buffer.update(cx, |buffer, cx| {
 8784                    let settings = WorktreeSettings::get(
 8785                        Some(
 8786                            (&ProjectPath {
 8787                                worktree_id: source_ws,
 8788                                path: Arc::from(RelPath::empty()),
 8789                            })
 8790                                .into(),
 8791                        ),
 8792                        cx,
 8793                    );
 8794                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8795                    if is_read_only {
 8796                        buffer.set_capability(Capability::ReadOnly, cx);
 8797                    }
 8798                });
 8799            }
 8800            Ok(buffer)
 8801        })
 8802    }
 8803
 8804    fn local_lsp_servers_for_buffer(
 8805        &self,
 8806        buffer: &Entity<Buffer>,
 8807        cx: &mut Context<Self>,
 8808    ) -> Vec<LanguageServerId> {
 8809        let Some(local) = self.as_local() else {
 8810            return Vec::new();
 8811        };
 8812
 8813        let snapshot = buffer.read(cx).snapshot();
 8814
 8815        buffer.update(cx, |buffer, cx| {
 8816            local
 8817                .language_servers_for_buffer(buffer, cx)
 8818                .map(|(_, server)| server.server_id())
 8819                .filter(|server_id| {
 8820                    self.as_local().is_none_or(|local| {
 8821                        local
 8822                            .buffers_opened_in_servers
 8823                            .get(&snapshot.remote_id())
 8824                            .is_some_and(|servers| servers.contains(server_id))
 8825                    })
 8826                })
 8827                .collect()
 8828        })
 8829    }
 8830
 8831    fn request_multiple_lsp_locally<P, R>(
 8832        &mut self,
 8833        buffer: &Entity<Buffer>,
 8834        position: Option<P>,
 8835        request: R,
 8836        cx: &mut Context<Self>,
 8837    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8838    where
 8839        P: ToOffset,
 8840        R: LspCommand + Clone,
 8841        <R::LspRequest as lsp::request::Request>::Result: Send,
 8842        <R::LspRequest as lsp::request::Request>::Params: Send,
 8843    {
 8844        let Some(local) = self.as_local() else {
 8845            return Task::ready(Vec::new());
 8846        };
 8847
 8848        let snapshot = buffer.read(cx).snapshot();
 8849        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8850
 8851        let server_ids = buffer.update(cx, |buffer, cx| {
 8852            local
 8853                .language_servers_for_buffer(buffer, cx)
 8854                .filter(|(adapter, _)| {
 8855                    scope
 8856                        .as_ref()
 8857                        .map(|scope| scope.language_allowed(&adapter.name))
 8858                        .unwrap_or(true)
 8859                })
 8860                .map(|(_, server)| server.server_id())
 8861                .filter(|server_id| {
 8862                    self.as_local().is_none_or(|local| {
 8863                        local
 8864                            .buffers_opened_in_servers
 8865                            .get(&snapshot.remote_id())
 8866                            .is_some_and(|servers| servers.contains(server_id))
 8867                    })
 8868                })
 8869                .collect::<Vec<_>>()
 8870        });
 8871
 8872        let mut response_results = server_ids
 8873            .into_iter()
 8874            .map(|server_id| {
 8875                let task = self.request_lsp(
 8876                    buffer.clone(),
 8877                    LanguageServerToQuery::Other(server_id),
 8878                    request.clone(),
 8879                    cx,
 8880                );
 8881                async move { (server_id, task.await) }
 8882            })
 8883            .collect::<FuturesUnordered<_>>();
 8884
 8885        cx.background_spawn(async move {
 8886            let mut responses = Vec::with_capacity(response_results.len());
 8887            while let Some((server_id, response_result)) = response_results.next().await {
 8888                match response_result {
 8889                    Ok(response) => responses.push((server_id, response)),
 8890                    // rust-analyzer likes to error with this when its still loading up
 8891                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8892                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8893                }
 8894            }
 8895            responses
 8896        })
 8897    }
 8898
 8899    async fn handle_lsp_get_completions(
 8900        this: Entity<Self>,
 8901        envelope: TypedEnvelope<proto::GetCompletions>,
 8902        mut cx: AsyncApp,
 8903    ) -> Result<proto::GetCompletionsResponse> {
 8904        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8905
 8906        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8907        let buffer_handle = this.update(&mut cx, |this, cx| {
 8908            this.buffer_store.read(cx).get_existing(buffer_id)
 8909        })?;
 8910        let request = GetCompletions::from_proto(
 8911            envelope.payload,
 8912            this.clone(),
 8913            buffer_handle.clone(),
 8914            cx.clone(),
 8915        )
 8916        .await?;
 8917
 8918        let server_to_query = match request.server_id {
 8919            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8920            None => LanguageServerToQuery::FirstCapable,
 8921        };
 8922
 8923        let response = this
 8924            .update(&mut cx, |this, cx| {
 8925                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8926            })
 8927            .await?;
 8928        this.update(&mut cx, |this, cx| {
 8929            Ok(GetCompletions::response_to_proto(
 8930                response,
 8931                this,
 8932                sender_id,
 8933                &buffer_handle.read(cx).version(),
 8934                cx,
 8935            ))
 8936        })
 8937    }
 8938
 8939    async fn handle_lsp_command<T: LspCommand>(
 8940        this: Entity<Self>,
 8941        envelope: TypedEnvelope<T::ProtoRequest>,
 8942        mut cx: AsyncApp,
 8943    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8944    where
 8945        <T::LspRequest as lsp::request::Request>::Params: Send,
 8946        <T::LspRequest as lsp::request::Request>::Result: Send,
 8947    {
 8948        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8949        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8950        let buffer_handle = this.update(&mut cx, |this, cx| {
 8951            this.buffer_store.read(cx).get_existing(buffer_id)
 8952        })?;
 8953        let request = T::from_proto(
 8954            envelope.payload,
 8955            this.clone(),
 8956            buffer_handle.clone(),
 8957            cx.clone(),
 8958        )
 8959        .await?;
 8960        let response = this
 8961            .update(&mut cx, |this, cx| {
 8962                this.request_lsp(
 8963                    buffer_handle.clone(),
 8964                    LanguageServerToQuery::FirstCapable,
 8965                    request,
 8966                    cx,
 8967                )
 8968            })
 8969            .await?;
 8970        this.update(&mut cx, |this, cx| {
 8971            Ok(T::response_to_proto(
 8972                response,
 8973                this,
 8974                sender_id,
 8975                &buffer_handle.read(cx).version(),
 8976                cx,
 8977            ))
 8978        })
 8979    }
 8980
 8981    async fn handle_lsp_query(
 8982        lsp_store: Entity<Self>,
 8983        envelope: TypedEnvelope<proto::LspQuery>,
 8984        mut cx: AsyncApp,
 8985    ) -> Result<proto::Ack> {
 8986        use proto::lsp_query::Request;
 8987        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8988        let lsp_query = envelope.payload;
 8989        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8990        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8991        match lsp_query.request.context("invalid LSP query request")? {
 8992            Request::GetReferences(get_references) => {
 8993                let position = get_references.position.clone().and_then(deserialize_anchor);
 8994                Self::query_lsp_locally::<GetReferences>(
 8995                    lsp_store,
 8996                    server_id,
 8997                    sender_id,
 8998                    lsp_request_id,
 8999                    get_references,
 9000                    position,
 9001                    &mut cx,
 9002                )
 9003                .await?;
 9004            }
 9005            Request::GetDocumentColor(get_document_color) => {
 9006                Self::query_lsp_locally::<GetDocumentColor>(
 9007                    lsp_store,
 9008                    server_id,
 9009                    sender_id,
 9010                    lsp_request_id,
 9011                    get_document_color,
 9012                    None,
 9013                    &mut cx,
 9014                )
 9015                .await?;
 9016            }
 9017            Request::GetFoldingRanges(get_folding_ranges) => {
 9018                Self::query_lsp_locally::<GetFoldingRanges>(
 9019                    lsp_store,
 9020                    server_id,
 9021                    sender_id,
 9022                    lsp_request_id,
 9023                    get_folding_ranges,
 9024                    None,
 9025                    &mut cx,
 9026                )
 9027                .await?;
 9028            }
 9029            Request::GetDocumentSymbols(get_document_symbols) => {
 9030                Self::query_lsp_locally::<GetDocumentSymbols>(
 9031                    lsp_store,
 9032                    server_id,
 9033                    sender_id,
 9034                    lsp_request_id,
 9035                    get_document_symbols,
 9036                    None,
 9037                    &mut cx,
 9038                )
 9039                .await?;
 9040            }
 9041            Request::GetHover(get_hover) => {
 9042                let position = get_hover.position.clone().and_then(deserialize_anchor);
 9043                Self::query_lsp_locally::<GetHover>(
 9044                    lsp_store,
 9045                    server_id,
 9046                    sender_id,
 9047                    lsp_request_id,
 9048                    get_hover,
 9049                    position,
 9050                    &mut cx,
 9051                )
 9052                .await?;
 9053            }
 9054            Request::GetCodeActions(get_code_actions) => {
 9055                Self::query_lsp_locally::<GetCodeActions>(
 9056                    lsp_store,
 9057                    server_id,
 9058                    sender_id,
 9059                    lsp_request_id,
 9060                    get_code_actions,
 9061                    None,
 9062                    &mut cx,
 9063                )
 9064                .await?;
 9065            }
 9066            Request::GetSignatureHelp(get_signature_help) => {
 9067                let position = get_signature_help
 9068                    .position
 9069                    .clone()
 9070                    .and_then(deserialize_anchor);
 9071                Self::query_lsp_locally::<GetSignatureHelp>(
 9072                    lsp_store,
 9073                    server_id,
 9074                    sender_id,
 9075                    lsp_request_id,
 9076                    get_signature_help,
 9077                    position,
 9078                    &mut cx,
 9079                )
 9080                .await?;
 9081            }
 9082            Request::GetCodeLens(get_code_lens) => {
 9083                Self::query_lsp_locally::<GetCodeLens>(
 9084                    lsp_store,
 9085                    server_id,
 9086                    sender_id,
 9087                    lsp_request_id,
 9088                    get_code_lens,
 9089                    None,
 9090                    &mut cx,
 9091                )
 9092                .await?;
 9093            }
 9094            Request::GetDefinition(get_definition) => {
 9095                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9096                Self::query_lsp_locally::<GetDefinitions>(
 9097                    lsp_store,
 9098                    server_id,
 9099                    sender_id,
 9100                    lsp_request_id,
 9101                    get_definition,
 9102                    position,
 9103                    &mut cx,
 9104                )
 9105                .await?;
 9106            }
 9107            Request::GetDeclaration(get_declaration) => {
 9108                let position = get_declaration
 9109                    .position
 9110                    .clone()
 9111                    .and_then(deserialize_anchor);
 9112                Self::query_lsp_locally::<GetDeclarations>(
 9113                    lsp_store,
 9114                    server_id,
 9115                    sender_id,
 9116                    lsp_request_id,
 9117                    get_declaration,
 9118                    position,
 9119                    &mut cx,
 9120                )
 9121                .await?;
 9122            }
 9123            Request::GetTypeDefinition(get_type_definition) => {
 9124                let position = get_type_definition
 9125                    .position
 9126                    .clone()
 9127                    .and_then(deserialize_anchor);
 9128                Self::query_lsp_locally::<GetTypeDefinitions>(
 9129                    lsp_store,
 9130                    server_id,
 9131                    sender_id,
 9132                    lsp_request_id,
 9133                    get_type_definition,
 9134                    position,
 9135                    &mut cx,
 9136                )
 9137                .await?;
 9138            }
 9139            Request::GetImplementation(get_implementation) => {
 9140                let position = get_implementation
 9141                    .position
 9142                    .clone()
 9143                    .and_then(deserialize_anchor);
 9144                Self::query_lsp_locally::<GetImplementations>(
 9145                    lsp_store,
 9146                    server_id,
 9147                    sender_id,
 9148                    lsp_request_id,
 9149                    get_implementation,
 9150                    position,
 9151                    &mut cx,
 9152                )
 9153                .await?;
 9154            }
 9155            Request::InlayHints(inlay_hints) => {
 9156                let query_start = inlay_hints
 9157                    .start
 9158                    .clone()
 9159                    .and_then(deserialize_anchor)
 9160                    .context("invalid inlay hints range start")?;
 9161                let query_end = inlay_hints
 9162                    .end
 9163                    .clone()
 9164                    .and_then(deserialize_anchor)
 9165                    .context("invalid inlay hints range end")?;
 9166                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9167                    &lsp_store,
 9168                    server_id,
 9169                    lsp_request_id,
 9170                    &inlay_hints,
 9171                    query_start..query_end,
 9172                    &mut cx,
 9173                )
 9174                .await
 9175                .context("preparing inlay hints request")?;
 9176                Self::query_lsp_locally::<InlayHints>(
 9177                    lsp_store,
 9178                    server_id,
 9179                    sender_id,
 9180                    lsp_request_id,
 9181                    inlay_hints,
 9182                    None,
 9183                    &mut cx,
 9184                )
 9185                .await
 9186                .context("querying for inlay hints")?
 9187            }
 9188            //////////////////////////////
 9189            // Below are LSP queries that need to fetch more data,
 9190            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 9191            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9192                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 9193                    &lsp_store,
 9194                    &get_document_diagnostics,
 9195                    &mut cx,
 9196                )
 9197                .await?;
 9198                lsp_store.update(&mut cx, |lsp_store, cx| {
 9199                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9200                    let key = LspKey {
 9201                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9202                        server_queried: server_id,
 9203                    };
 9204                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9205                    ) {
 9206                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9207                            lsp_requests.clear();
 9208                        };
 9209                    }
 9210
 9211                    lsp_data.lsp_requests.entry(key).or_default().insert(
 9212                        lsp_request_id,
 9213                        cx.spawn(async move |lsp_store, cx| {
 9214                            let diagnostics_pull = lsp_store
 9215                                .update(cx, |lsp_store, cx| {
 9216                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9217                                })
 9218                                .ok();
 9219                            if let Some(diagnostics_pull) = diagnostics_pull {
 9220                                match diagnostics_pull.await {
 9221                                    Ok(()) => {}
 9222                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9223                                };
 9224                            }
 9225                        }),
 9226                    );
 9227                });
 9228            }
 9229            Request::SemanticTokens(semantic_tokens) => {
 9230                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 9231                    &lsp_store,
 9232                    &semantic_tokens,
 9233                    &mut cx,
 9234                )
 9235                .await?;
 9236                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9237                lsp_store.update(&mut cx, |lsp_store, cx| {
 9238                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9239                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9240                        let key = LspKey {
 9241                            request_type: TypeId::of::<SemanticTokensFull>(),
 9242                            server_queried: server_id,
 9243                        };
 9244                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9245                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9246                                lsp_requests.clear();
 9247                            };
 9248                        }
 9249
 9250                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9251                            lsp_request_id,
 9252                            cx.spawn(async move |lsp_store, cx| {
 9253                                let tokens_fetch = lsp_store
 9254                                    .update(cx, |lsp_store, cx| {
 9255                                        lsp_store
 9256                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9257                                    })
 9258                                    .ok();
 9259                                if let Some(tokens_fetch) = tokens_fetch {
 9260                                    let new_tokens = tokens_fetch.await;
 9261                                    if let Some(new_tokens) = new_tokens {
 9262                                        lsp_store
 9263                                            .update(cx, |lsp_store, cx| {
 9264                                                let response = new_tokens
 9265                                                    .into_iter()
 9266                                                    .map(|(server_id, response)| {
 9267                                                        (
 9268                                                            server_id.to_proto(),
 9269                                                            SemanticTokensFull::response_to_proto(
 9270                                                                response,
 9271                                                                lsp_store,
 9272                                                                sender_id,
 9273                                                                &buffer_version,
 9274                                                                cx,
 9275                                                            ),
 9276                                                        )
 9277                                                    })
 9278                                                    .collect::<HashMap<_, _>>();
 9279                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9280                                                    project_id,
 9281                                                    lsp_request_id,
 9282                                                    response,
 9283                                                ) {
 9284                                                    Ok(()) => {}
 9285                                                    Err(e) => {
 9286                                                        log::error!(
 9287                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9288                                                        )
 9289                                                    }
 9290                                                }
 9291                                            })
 9292                                            .ok();
 9293                                    }
 9294                                }
 9295                            }),
 9296                        );
 9297                    }
 9298                });
 9299            }
 9300        }
 9301        Ok(proto::Ack {})
 9302    }
 9303
 9304    async fn handle_lsp_query_response(
 9305        lsp_store: Entity<Self>,
 9306        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9307        cx: AsyncApp,
 9308    ) -> Result<()> {
 9309        lsp_store.read_with(&cx, |lsp_store, _| {
 9310            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9311                upstream_client.handle_lsp_response(envelope.clone());
 9312            }
 9313        });
 9314        Ok(())
 9315    }
 9316
 9317    async fn handle_apply_code_action(
 9318        this: Entity<Self>,
 9319        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9320        mut cx: AsyncApp,
 9321    ) -> Result<proto::ApplyCodeActionResponse> {
 9322        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9323        let action =
 9324            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9325        let apply_code_action = this.update(&mut cx, |this, cx| {
 9326            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9327            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9328            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9329        })?;
 9330
 9331        let project_transaction = apply_code_action.await?;
 9332        let project_transaction = this.update(&mut cx, |this, cx| {
 9333            this.buffer_store.update(cx, |buffer_store, cx| {
 9334                buffer_store.serialize_project_transaction_for_peer(
 9335                    project_transaction,
 9336                    sender_id,
 9337                    cx,
 9338                )
 9339            })
 9340        });
 9341        Ok(proto::ApplyCodeActionResponse {
 9342            transaction: Some(project_transaction),
 9343        })
 9344    }
 9345
 9346    async fn handle_register_buffer_with_language_servers(
 9347        this: Entity<Self>,
 9348        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9349        mut cx: AsyncApp,
 9350    ) -> Result<proto::Ack> {
 9351        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9352        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9353        this.update(&mut cx, |this, cx| {
 9354            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9355                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9356                    project_id: upstream_project_id,
 9357                    buffer_id: buffer_id.to_proto(),
 9358                    only_servers: envelope.payload.only_servers,
 9359                });
 9360            }
 9361
 9362            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9363                anyhow::bail!("buffer is not open");
 9364            };
 9365
 9366            let handle = this.register_buffer_with_language_servers(
 9367                &buffer,
 9368                envelope
 9369                    .payload
 9370                    .only_servers
 9371                    .into_iter()
 9372                    .filter_map(|selector| {
 9373                        Some(match selector.selector? {
 9374                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9375                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9376                            }
 9377                            proto::language_server_selector::Selector::Name(name) => {
 9378                                LanguageServerSelector::Name(LanguageServerName(
 9379                                    SharedString::from(name),
 9380                                ))
 9381                            }
 9382                        })
 9383                    })
 9384                    .collect(),
 9385                false,
 9386                cx,
 9387            );
 9388            // Pull diagnostics for the buffer even if it was already registered.
 9389            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9390            // but it's unclear if we need it.
 9391            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9392                .detach();
 9393            this.buffer_store().update(cx, |buffer_store, _| {
 9394                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9395            });
 9396
 9397            Ok(())
 9398        })?;
 9399        Ok(proto::Ack {})
 9400    }
 9401
 9402    async fn handle_rename_project_entry(
 9403        this: Entity<Self>,
 9404        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9405        mut cx: AsyncApp,
 9406    ) -> Result<proto::ProjectEntryResponse> {
 9407        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9408        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9409        let new_path =
 9410            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9411
 9412        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9413            .update(&mut cx, |this, cx| {
 9414                let (worktree, entry) = this
 9415                    .worktree_store
 9416                    .read(cx)
 9417                    .worktree_and_entry_for_id(entry_id, cx)?;
 9418                let new_worktree = this
 9419                    .worktree_store
 9420                    .read(cx)
 9421                    .worktree_for_id(new_worktree_id, cx)?;
 9422                Some((
 9423                    this.worktree_store.clone(),
 9424                    worktree,
 9425                    new_worktree,
 9426                    entry.clone(),
 9427                ))
 9428            })
 9429            .context("worktree not found")?;
 9430        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9431            (worktree.absolutize(&old_entry.path), worktree.id())
 9432        });
 9433        let new_abs_path =
 9434            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9435
 9436        let _transaction = Self::will_rename_entry(
 9437            this.downgrade(),
 9438            old_worktree_id,
 9439            &old_abs_path,
 9440            &new_abs_path,
 9441            old_entry.is_dir(),
 9442            cx.clone(),
 9443        )
 9444        .await;
 9445        let response = WorktreeStore::handle_rename_project_entry(
 9446            worktree_store,
 9447            envelope.payload,
 9448            cx.clone(),
 9449        )
 9450        .await;
 9451        this.read_with(&cx, |this, _| {
 9452            this.did_rename_entry(
 9453                old_worktree_id,
 9454                &old_abs_path,
 9455                &new_abs_path,
 9456                old_entry.is_dir(),
 9457            );
 9458        });
 9459        response
 9460    }
 9461
 9462    async fn handle_update_diagnostic_summary(
 9463        this: Entity<Self>,
 9464        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9465        mut cx: AsyncApp,
 9466    ) -> Result<()> {
 9467        this.update(&mut cx, |lsp_store, cx| {
 9468            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9469            let mut updated_diagnostics_paths = HashMap::default();
 9470            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9471            for message_summary in envelope
 9472                .payload
 9473                .summary
 9474                .into_iter()
 9475                .chain(envelope.payload.more_summaries)
 9476            {
 9477                let project_path = ProjectPath {
 9478                    worktree_id,
 9479                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9480                };
 9481                let path = project_path.path.clone();
 9482                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9483                let summary = DiagnosticSummary {
 9484                    error_count: message_summary.error_count as usize,
 9485                    warning_count: message_summary.warning_count as usize,
 9486                };
 9487
 9488                if summary.is_empty() {
 9489                    if let Some(worktree_summaries) =
 9490                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9491                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9492                    {
 9493                        summaries.remove(&server_id);
 9494                        if summaries.is_empty() {
 9495                            worktree_summaries.remove(&path);
 9496                        }
 9497                    }
 9498                } else {
 9499                    lsp_store
 9500                        .diagnostic_summaries
 9501                        .entry(worktree_id)
 9502                        .or_default()
 9503                        .entry(path)
 9504                        .or_default()
 9505                        .insert(server_id, summary);
 9506                }
 9507
 9508                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9509                    match &mut diagnostics_summary {
 9510                        Some(diagnostics_summary) => {
 9511                            diagnostics_summary
 9512                                .more_summaries
 9513                                .push(proto::DiagnosticSummary {
 9514                                    path: project_path.path.as_ref().to_proto(),
 9515                                    language_server_id: server_id.0 as u64,
 9516                                    error_count: summary.error_count as u32,
 9517                                    warning_count: summary.warning_count as u32,
 9518                                })
 9519                        }
 9520                        None => {
 9521                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9522                                project_id: *project_id,
 9523                                worktree_id: worktree_id.to_proto(),
 9524                                summary: Some(proto::DiagnosticSummary {
 9525                                    path: project_path.path.as_ref().to_proto(),
 9526                                    language_server_id: server_id.0 as u64,
 9527                                    error_count: summary.error_count as u32,
 9528                                    warning_count: summary.warning_count as u32,
 9529                                }),
 9530                                more_summaries: Vec::new(),
 9531                            })
 9532                        }
 9533                    }
 9534                }
 9535                updated_diagnostics_paths
 9536                    .entry(server_id)
 9537                    .or_insert_with(Vec::new)
 9538                    .push(project_path);
 9539            }
 9540
 9541            if let Some((diagnostics_summary, (downstream_client, _))) =
 9542                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9543            {
 9544                downstream_client.send(diagnostics_summary).log_err();
 9545            }
 9546            for (server_id, paths) in updated_diagnostics_paths {
 9547                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9548            }
 9549            Ok(())
 9550        })
 9551    }
 9552
 9553    async fn handle_start_language_server(
 9554        lsp_store: Entity<Self>,
 9555        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9556        mut cx: AsyncApp,
 9557    ) -> Result<()> {
 9558        let server = envelope.payload.server.context("invalid server")?;
 9559        let server_capabilities =
 9560            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9561                .with_context(|| {
 9562                    format!(
 9563                        "incorrect server capabilities {}",
 9564                        envelope.payload.capabilities
 9565                    )
 9566                })?;
 9567        lsp_store.update(&mut cx, |lsp_store, cx| {
 9568            let server_id = LanguageServerId(server.id as usize);
 9569            let server_name = LanguageServerName::from_proto(server.name.clone());
 9570            lsp_store
 9571                .lsp_server_capabilities
 9572                .insert(server_id, server_capabilities);
 9573            lsp_store.language_server_statuses.insert(
 9574                server_id,
 9575                LanguageServerStatus {
 9576                    name: server_name.clone(),
 9577                    server_version: None,
 9578                    server_readable_version: None,
 9579                    pending_work: Default::default(),
 9580                    has_pending_diagnostic_updates: false,
 9581                    progress_tokens: Default::default(),
 9582                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9583                    binary: None,
 9584                    configuration: None,
 9585                    workspace_folders: BTreeSet::new(),
 9586                    process_id: None,
 9587                },
 9588            );
 9589            cx.emit(LspStoreEvent::LanguageServerAdded(
 9590                server_id,
 9591                server_name,
 9592                server.worktree_id.map(WorktreeId::from_proto),
 9593            ));
 9594            cx.notify();
 9595        });
 9596        Ok(())
 9597    }
 9598
 9599    async fn handle_update_language_server(
 9600        lsp_store: Entity<Self>,
 9601        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9602        mut cx: AsyncApp,
 9603    ) -> Result<()> {
 9604        lsp_store.update(&mut cx, |lsp_store, cx| {
 9605            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9606
 9607            match envelope.payload.variant.context("invalid variant")? {
 9608                proto::update_language_server::Variant::WorkStart(payload) => {
 9609                    lsp_store.on_lsp_work_start(
 9610                        language_server_id,
 9611                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9612                            .context("invalid progress token value")?,
 9613                        LanguageServerProgress {
 9614                            title: payload.title,
 9615                            is_disk_based_diagnostics_progress: false,
 9616                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9617                            message: payload.message,
 9618                            percentage: payload.percentage.map(|p| p as usize),
 9619                            last_update_at: cx.background_executor().now(),
 9620                        },
 9621                        cx,
 9622                    );
 9623                }
 9624                proto::update_language_server::Variant::WorkProgress(payload) => {
 9625                    lsp_store.on_lsp_work_progress(
 9626                        language_server_id,
 9627                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9628                            .context("invalid progress token value")?,
 9629                        LanguageServerProgress {
 9630                            title: None,
 9631                            is_disk_based_diagnostics_progress: false,
 9632                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9633                            message: payload.message,
 9634                            percentage: payload.percentage.map(|p| p as usize),
 9635                            last_update_at: cx.background_executor().now(),
 9636                        },
 9637                        cx,
 9638                    );
 9639                }
 9640
 9641                proto::update_language_server::Variant::WorkEnd(payload) => {
 9642                    lsp_store.on_lsp_work_end(
 9643                        language_server_id,
 9644                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9645                            .context("invalid progress token value")?,
 9646                        cx,
 9647                    );
 9648                }
 9649
 9650                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9651                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9652                }
 9653
 9654                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9655                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9656                }
 9657
 9658                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9659                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9660                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9661                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9662                        language_server_id,
 9663                        name: envelope
 9664                            .payload
 9665                            .server_name
 9666                            .map(SharedString::new)
 9667                            .map(LanguageServerName),
 9668                        message: non_lsp,
 9669                    });
 9670                }
 9671            }
 9672
 9673            Ok(())
 9674        })
 9675    }
 9676
 9677    async fn handle_language_server_log(
 9678        this: Entity<Self>,
 9679        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9680        mut cx: AsyncApp,
 9681    ) -> Result<()> {
 9682        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9683        let log_type = envelope
 9684            .payload
 9685            .log_type
 9686            .map(LanguageServerLogType::from_proto)
 9687            .context("invalid language server log type")?;
 9688
 9689        let message = envelope.payload.message;
 9690
 9691        this.update(&mut cx, |_, cx| {
 9692            cx.emit(LspStoreEvent::LanguageServerLog(
 9693                language_server_id,
 9694                log_type,
 9695                message,
 9696            ));
 9697        });
 9698        Ok(())
 9699    }
 9700
 9701    async fn handle_lsp_ext_cancel_flycheck(
 9702        lsp_store: Entity<Self>,
 9703        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9704        cx: AsyncApp,
 9705    ) -> Result<proto::Ack> {
 9706        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9707        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9708            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9709                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9710            } else {
 9711                None
 9712            }
 9713        });
 9714        if let Some(task) = task {
 9715            task.context("handling lsp ext cancel flycheck")?;
 9716        }
 9717
 9718        Ok(proto::Ack {})
 9719    }
 9720
 9721    async fn handle_lsp_ext_run_flycheck(
 9722        lsp_store: Entity<Self>,
 9723        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9724        mut cx: AsyncApp,
 9725    ) -> Result<proto::Ack> {
 9726        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9727        lsp_store.update(&mut cx, |lsp_store, cx| {
 9728            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9729                let text_document = if envelope.payload.current_file_only {
 9730                    let buffer_id = envelope
 9731                        .payload
 9732                        .buffer_id
 9733                        .map(|id| BufferId::new(id))
 9734                        .transpose()?;
 9735                    buffer_id
 9736                        .and_then(|buffer_id| {
 9737                            lsp_store
 9738                                .buffer_store()
 9739                                .read(cx)
 9740                                .get(buffer_id)
 9741                                .and_then(|buffer| {
 9742                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9743                                })
 9744                                .map(|path| make_text_document_identifier(&path))
 9745                        })
 9746                        .transpose()?
 9747                } else {
 9748                    None
 9749                };
 9750                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9751                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9752                )?;
 9753            }
 9754            anyhow::Ok(())
 9755        })?;
 9756
 9757        Ok(proto::Ack {})
 9758    }
 9759
 9760    async fn handle_lsp_ext_clear_flycheck(
 9761        lsp_store: Entity<Self>,
 9762        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9763        cx: AsyncApp,
 9764    ) -> Result<proto::Ack> {
 9765        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9766        lsp_store.read_with(&cx, |lsp_store, _| {
 9767            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9768                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9769            } else {
 9770                None
 9771            }
 9772        });
 9773
 9774        Ok(proto::Ack {})
 9775    }
 9776
 9777    pub fn disk_based_diagnostics_started(
 9778        &mut self,
 9779        language_server_id: LanguageServerId,
 9780        cx: &mut Context<Self>,
 9781    ) {
 9782        if let Some(language_server_status) =
 9783            self.language_server_statuses.get_mut(&language_server_id)
 9784        {
 9785            language_server_status.has_pending_diagnostic_updates = true;
 9786        }
 9787
 9788        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9789        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9790            language_server_id,
 9791            name: self
 9792                .language_server_adapter_for_id(language_server_id)
 9793                .map(|adapter| adapter.name()),
 9794            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9795                Default::default(),
 9796            ),
 9797        })
 9798    }
 9799
 9800    pub fn disk_based_diagnostics_finished(
 9801        &mut self,
 9802        language_server_id: LanguageServerId,
 9803        cx: &mut Context<Self>,
 9804    ) {
 9805        if let Some(language_server_status) =
 9806            self.language_server_statuses.get_mut(&language_server_id)
 9807        {
 9808            language_server_status.has_pending_diagnostic_updates = false;
 9809        }
 9810
 9811        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9812        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9813            language_server_id,
 9814            name: self
 9815                .language_server_adapter_for_id(language_server_id)
 9816                .map(|adapter| adapter.name()),
 9817            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9818                Default::default(),
 9819            ),
 9820        })
 9821    }
 9822
 9823    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9824    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9825    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9826    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9827    // the language server might take some time to publish diagnostics.
 9828    fn simulate_disk_based_diagnostics_events_if_needed(
 9829        &mut self,
 9830        language_server_id: LanguageServerId,
 9831        cx: &mut Context<Self>,
 9832    ) {
 9833        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9834
 9835        let Some(LanguageServerState::Running {
 9836            simulate_disk_based_diagnostics_completion,
 9837            adapter,
 9838            ..
 9839        }) = self
 9840            .as_local_mut()
 9841            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9842        else {
 9843            return;
 9844        };
 9845
 9846        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9847            return;
 9848        }
 9849
 9850        let prev_task =
 9851            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9852                cx.background_executor()
 9853                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9854                    .await;
 9855
 9856                this.update(cx, |this, cx| {
 9857                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9858
 9859                    if let Some(LanguageServerState::Running {
 9860                        simulate_disk_based_diagnostics_completion,
 9861                        ..
 9862                    }) = this.as_local_mut().and_then(|local_store| {
 9863                        local_store.language_servers.get_mut(&language_server_id)
 9864                    }) {
 9865                        *simulate_disk_based_diagnostics_completion = None;
 9866                    }
 9867                })
 9868                .ok();
 9869            }));
 9870
 9871        if prev_task.is_none() {
 9872            self.disk_based_diagnostics_started(language_server_id, cx);
 9873        }
 9874    }
 9875
 9876    pub fn language_server_statuses(
 9877        &self,
 9878    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9879        self.language_server_statuses
 9880            .iter()
 9881            .map(|(key, value)| (*key, value))
 9882    }
 9883
 9884    pub(super) fn did_rename_entry(
 9885        &self,
 9886        worktree_id: WorktreeId,
 9887        old_path: &Path,
 9888        new_path: &Path,
 9889        is_dir: bool,
 9890    ) {
 9891        maybe!({
 9892            let local_store = self.as_local()?;
 9893
 9894            let old_uri = lsp::Uri::from_file_path(old_path)
 9895                .ok()
 9896                .map(|uri| uri.to_string())?;
 9897            let new_uri = lsp::Uri::from_file_path(new_path)
 9898                .ok()
 9899                .map(|uri| uri.to_string())?;
 9900
 9901            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9902                let Some(filter) = local_store
 9903                    .language_server_paths_watched_for_rename
 9904                    .get(&language_server.server_id())
 9905                else {
 9906                    continue;
 9907                };
 9908
 9909                if filter.should_send_did_rename(&old_uri, is_dir) {
 9910                    language_server
 9911                        .notify::<DidRenameFiles>(RenameFilesParams {
 9912                            files: vec![FileRename {
 9913                                old_uri: old_uri.clone(),
 9914                                new_uri: new_uri.clone(),
 9915                            }],
 9916                        })
 9917                        .ok();
 9918                }
 9919            }
 9920            Some(())
 9921        });
 9922    }
 9923
 9924    pub(super) fn will_rename_entry(
 9925        this: WeakEntity<Self>,
 9926        worktree_id: WorktreeId,
 9927        old_path: &Path,
 9928        new_path: &Path,
 9929        is_dir: bool,
 9930        cx: AsyncApp,
 9931    ) -> Task<ProjectTransaction> {
 9932        let old_uri = lsp::Uri::from_file_path(old_path)
 9933            .ok()
 9934            .map(|uri| uri.to_string());
 9935        let new_uri = lsp::Uri::from_file_path(new_path)
 9936            .ok()
 9937            .map(|uri| uri.to_string());
 9938        cx.spawn(async move |cx| {
 9939            let mut tasks = vec![];
 9940            this.update(cx, |this, cx| {
 9941                let local_store = this.as_local()?;
 9942                let old_uri = old_uri?;
 9943                let new_uri = new_uri?;
 9944                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9945                    let Some(filter) = local_store
 9946                        .language_server_paths_watched_for_rename
 9947                        .get(&language_server.server_id())
 9948                    else {
 9949                        continue;
 9950                    };
 9951
 9952                    if !filter.should_send_will_rename(&old_uri, is_dir) {
 9953                        continue;
 9954                    }
 9955                    let request_timeout = ProjectSettings::get_global(cx)
 9956                        .global_lsp_settings
 9957                        .get_request_timeout();
 9958
 9959                    let apply_edit = cx.spawn({
 9960                        let old_uri = old_uri.clone();
 9961                        let new_uri = new_uri.clone();
 9962                        let language_server = language_server.clone();
 9963                        async move |this, cx| {
 9964                            let edit = language_server
 9965                                .request::<WillRenameFiles>(
 9966                                    RenameFilesParams {
 9967                                        files: vec![FileRename { old_uri, new_uri }],
 9968                                    },
 9969                                    request_timeout,
 9970                                )
 9971                                .await
 9972                                .into_response()
 9973                                .context("will rename files")
 9974                                .log_err()
 9975                                .flatten()?;
 9976
 9977                            LocalLspStore::deserialize_workspace_edit(
 9978                                this.upgrade()?,
 9979                                edit,
 9980                                false,
 9981                                language_server.clone(),
 9982                                cx,
 9983                            )
 9984                            .await
 9985                            .ok()
 9986                        }
 9987                    });
 9988                    tasks.push(apply_edit);
 9989                }
 9990                Some(())
 9991            })
 9992            .ok()
 9993            .flatten();
 9994            let mut merged_transaction = ProjectTransaction::default();
 9995            for task in tasks {
 9996                // Await on tasks sequentially so that the order of application of edits is deterministic
 9997                // (at least with regards to the order of registration of language servers)
 9998                if let Some(transaction) = task.await {
 9999                    for (buffer, buffer_transaction) in transaction.0 {
10000                        merged_transaction.0.insert(buffer, buffer_transaction);
10001                    }
10002                }
10003            }
10004            merged_transaction
10005        })
10006    }
10007
10008    fn lsp_notify_abs_paths_changed(
10009        &mut self,
10010        server_id: LanguageServerId,
10011        changes: Vec<PathEvent>,
10012    ) {
10013        maybe!({
10014            let server = self.language_server_for_id(server_id)?;
10015            let changes = changes
10016                .into_iter()
10017                .filter_map(|event| {
10018                    let typ = match event.kind? {
10019                        PathEventKind::Created => lsp::FileChangeType::CREATED,
10020                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
10021                        PathEventKind::Changed | PathEventKind::Rescan => {
10022                            lsp::FileChangeType::CHANGED
10023                        }
10024                    };
10025                    Some(lsp::FileEvent {
10026                        uri: file_path_to_lsp_url(&event.path).log_err()?,
10027                        typ,
10028                    })
10029                })
10030                .collect::<Vec<_>>();
10031            if !changes.is_empty() {
10032                server
10033                    .notify::<lsp::notification::DidChangeWatchedFiles>(
10034                        lsp::DidChangeWatchedFilesParams { changes },
10035                    )
10036                    .ok();
10037            }
10038            Some(())
10039        });
10040    }
10041
10042    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
10043        self.as_local()?.language_server_for_id(id)
10044    }
10045
10046    fn on_lsp_progress(
10047        &mut self,
10048        progress_params: lsp::ProgressParams,
10049        language_server_id: LanguageServerId,
10050        disk_based_diagnostics_progress_token: Option<String>,
10051        cx: &mut Context<Self>,
10052    ) {
10053        match progress_params.value {
10054            lsp::ProgressParamsValue::WorkDone(progress) => {
10055                self.handle_work_done_progress(
10056                    progress,
10057                    language_server_id,
10058                    disk_based_diagnostics_progress_token,
10059                    ProgressToken::from_lsp(progress_params.token),
10060                    cx,
10061                );
10062            }
10063            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
10064                let registration_id = match progress_params.token {
10065                    lsp::NumberOrString::Number(_) => None,
10066                    lsp::NumberOrString::String(token) => token
10067                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
10068                        .map(|(_, id)| id.to_owned()),
10069                };
10070                if let Some(LanguageServerState::Running {
10071                    workspace_diagnostics_refresh_tasks,
10072                    ..
10073                }) = self
10074                    .as_local_mut()
10075                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
10076                    && let Some(workspace_diagnostics) =
10077                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
10078                {
10079                    workspace_diagnostics.progress_tx.try_send(()).ok();
10080                    self.apply_workspace_diagnostic_report(
10081                        language_server_id,
10082                        report,
10083                        registration_id.map(SharedString::from),
10084                        cx,
10085                    )
10086                }
10087            }
10088        }
10089    }
10090
10091    fn handle_work_done_progress(
10092        &mut self,
10093        progress: lsp::WorkDoneProgress,
10094        language_server_id: LanguageServerId,
10095        disk_based_diagnostics_progress_token: Option<String>,
10096        token: ProgressToken,
10097        cx: &mut Context<Self>,
10098    ) {
10099        let language_server_status =
10100            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10101                status
10102            } else {
10103                return;
10104            };
10105
10106        if !language_server_status.progress_tokens.contains(&token) {
10107            return;
10108        }
10109
10110        let is_disk_based_diagnostics_progress =
10111            if let (Some(disk_based_token), ProgressToken::String(token)) =
10112                (&disk_based_diagnostics_progress_token, &token)
10113            {
10114                token.starts_with(disk_based_token)
10115            } else {
10116                false
10117            };
10118
10119        match progress {
10120            lsp::WorkDoneProgress::Begin(report) => {
10121                if is_disk_based_diagnostics_progress {
10122                    self.disk_based_diagnostics_started(language_server_id, cx);
10123                }
10124                self.on_lsp_work_start(
10125                    language_server_id,
10126                    token.clone(),
10127                    LanguageServerProgress {
10128                        title: Some(report.title),
10129                        is_disk_based_diagnostics_progress,
10130                        is_cancellable: report.cancellable.unwrap_or(false),
10131                        message: report.message.clone(),
10132                        percentage: report.percentage.map(|p| p as usize),
10133                        last_update_at: cx.background_executor().now(),
10134                    },
10135                    cx,
10136                );
10137            }
10138            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10139                language_server_id,
10140                token,
10141                LanguageServerProgress {
10142                    title: None,
10143                    is_disk_based_diagnostics_progress,
10144                    is_cancellable: report.cancellable.unwrap_or(false),
10145                    message: report.message,
10146                    percentage: report.percentage.map(|p| p as usize),
10147                    last_update_at: cx.background_executor().now(),
10148                },
10149                cx,
10150            ),
10151            lsp::WorkDoneProgress::End(_) => {
10152                language_server_status.progress_tokens.remove(&token);
10153                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10154                if is_disk_based_diagnostics_progress {
10155                    self.disk_based_diagnostics_finished(language_server_id, cx);
10156                }
10157            }
10158        }
10159    }
10160
10161    fn on_lsp_work_start(
10162        &mut self,
10163        language_server_id: LanguageServerId,
10164        token: ProgressToken,
10165        progress: LanguageServerProgress,
10166        cx: &mut Context<Self>,
10167    ) {
10168        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10169            status.pending_work.insert(token.clone(), progress.clone());
10170            cx.notify();
10171        }
10172        cx.emit(LspStoreEvent::LanguageServerUpdate {
10173            language_server_id,
10174            name: self
10175                .language_server_adapter_for_id(language_server_id)
10176                .map(|adapter| adapter.name()),
10177            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10178                token: Some(token.to_proto()),
10179                title: progress.title,
10180                message: progress.message,
10181                percentage: progress.percentage.map(|p| p as u32),
10182                is_cancellable: Some(progress.is_cancellable),
10183            }),
10184        })
10185    }
10186
10187    fn on_lsp_work_progress(
10188        &mut self,
10189        language_server_id: LanguageServerId,
10190        token: ProgressToken,
10191        progress: LanguageServerProgress,
10192        cx: &mut Context<Self>,
10193    ) {
10194        let mut did_update = false;
10195        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10196            match status.pending_work.entry(token.clone()) {
10197                btree_map::Entry::Vacant(entry) => {
10198                    entry.insert(progress.clone());
10199                    did_update = true;
10200                }
10201                btree_map::Entry::Occupied(mut entry) => {
10202                    let entry = entry.get_mut();
10203                    if (progress.last_update_at - entry.last_update_at)
10204                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10205                    {
10206                        entry.last_update_at = progress.last_update_at;
10207                        if progress.message.is_some() {
10208                            entry.message = progress.message.clone();
10209                        }
10210                        if progress.percentage.is_some() {
10211                            entry.percentage = progress.percentage;
10212                        }
10213                        if progress.is_cancellable != entry.is_cancellable {
10214                            entry.is_cancellable = progress.is_cancellable;
10215                        }
10216                        did_update = true;
10217                    }
10218                }
10219            }
10220        }
10221
10222        if did_update {
10223            cx.emit(LspStoreEvent::LanguageServerUpdate {
10224                language_server_id,
10225                name: self
10226                    .language_server_adapter_for_id(language_server_id)
10227                    .map(|adapter| adapter.name()),
10228                message: proto::update_language_server::Variant::WorkProgress(
10229                    proto::LspWorkProgress {
10230                        token: Some(token.to_proto()),
10231                        message: progress.message,
10232                        percentage: progress.percentage.map(|p| p as u32),
10233                        is_cancellable: Some(progress.is_cancellable),
10234                    },
10235                ),
10236            })
10237        }
10238    }
10239
10240    fn on_lsp_work_end(
10241        &mut self,
10242        language_server_id: LanguageServerId,
10243        token: ProgressToken,
10244        cx: &mut Context<Self>,
10245    ) {
10246        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10247            if let Some(work) = status.pending_work.remove(&token)
10248                && !work.is_disk_based_diagnostics_progress
10249            {
10250                cx.emit(LspStoreEvent::RefreshInlayHints {
10251                    server_id: language_server_id,
10252                    request_id: None,
10253                });
10254            }
10255            cx.notify();
10256        }
10257
10258        cx.emit(LspStoreEvent::LanguageServerUpdate {
10259            language_server_id,
10260            name: self
10261                .language_server_adapter_for_id(language_server_id)
10262                .map(|adapter| adapter.name()),
10263            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10264                token: Some(token.to_proto()),
10265            }),
10266        })
10267    }
10268
10269    pub async fn handle_resolve_completion_documentation(
10270        this: Entity<Self>,
10271        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10272        mut cx: AsyncApp,
10273    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10274        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10275
10276        let completion = this
10277            .read_with(&cx, |this, cx| {
10278                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10279                let server = this
10280                    .language_server_for_id(id)
10281                    .with_context(|| format!("No language server {id}"))?;
10282
10283                let request_timeout = ProjectSettings::get_global(cx)
10284                    .global_lsp_settings
10285                    .get_request_timeout();
10286
10287                anyhow::Ok(cx.background_spawn(async move {
10288                    let can_resolve = server
10289                        .capabilities()
10290                        .completion_provider
10291                        .as_ref()
10292                        .and_then(|options| options.resolve_provider)
10293                        .unwrap_or(false);
10294                    if can_resolve {
10295                        server
10296                            .request::<lsp::request::ResolveCompletionItem>(
10297                                lsp_completion,
10298                                request_timeout,
10299                            )
10300                            .await
10301                            .into_response()
10302                            .context("resolve completion item")
10303                    } else {
10304                        anyhow::Ok(lsp_completion)
10305                    }
10306                }))
10307            })?
10308            .await?;
10309
10310        let mut documentation_is_markdown = false;
10311        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10312        let documentation = match completion.documentation {
10313            Some(lsp::Documentation::String(text)) => text,
10314
10315            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10316                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10317                value
10318            }
10319
10320            _ => String::new(),
10321        };
10322
10323        // If we have a new buffer_id, that means we're talking to a new client
10324        // and want to check for new text_edits in the completion too.
10325        let mut old_replace_start = None;
10326        let mut old_replace_end = None;
10327        let mut old_insert_start = None;
10328        let mut old_insert_end = None;
10329        let mut new_text = String::default();
10330        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10331            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10332                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10333                anyhow::Ok(buffer.read(cx).snapshot())
10334            })?;
10335
10336            if let Some(text_edit) = completion.text_edit.as_ref() {
10337                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10338
10339                if let Some(mut edit) = edit {
10340                    LineEnding::normalize(&mut edit.new_text);
10341
10342                    new_text = edit.new_text;
10343                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10344                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10345                    if let Some(insert_range) = edit.insert_range {
10346                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10347                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10348                    }
10349                }
10350            }
10351        }
10352
10353        Ok(proto::ResolveCompletionDocumentationResponse {
10354            documentation,
10355            documentation_is_markdown,
10356            old_replace_start,
10357            old_replace_end,
10358            new_text,
10359            lsp_completion,
10360            old_insert_start,
10361            old_insert_end,
10362        })
10363    }
10364
10365    async fn handle_on_type_formatting(
10366        this: Entity<Self>,
10367        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10368        mut cx: AsyncApp,
10369    ) -> Result<proto::OnTypeFormattingResponse> {
10370        let on_type_formatting = this.update(&mut cx, |this, cx| {
10371            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10372            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10373            let position = envelope
10374                .payload
10375                .position
10376                .and_then(deserialize_anchor)
10377                .context("invalid position")?;
10378            anyhow::Ok(this.apply_on_type_formatting(
10379                buffer,
10380                position,
10381                envelope.payload.trigger.clone(),
10382                cx,
10383            ))
10384        })?;
10385
10386        let transaction = on_type_formatting
10387            .await?
10388            .as_ref()
10389            .map(language::proto::serialize_transaction);
10390        Ok(proto::OnTypeFormattingResponse { transaction })
10391    }
10392
10393    async fn handle_pull_workspace_diagnostics(
10394        lsp_store: Entity<Self>,
10395        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10396        mut cx: AsyncApp,
10397    ) -> Result<proto::Ack> {
10398        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10399        lsp_store.update(&mut cx, |lsp_store, _| {
10400            lsp_store.pull_workspace_diagnostics(server_id);
10401        });
10402        Ok(proto::Ack {})
10403    }
10404
10405    async fn handle_open_buffer_for_symbol(
10406        this: Entity<Self>,
10407        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10408        mut cx: AsyncApp,
10409    ) -> Result<proto::OpenBufferForSymbolResponse> {
10410        let peer_id = envelope.original_sender_id().unwrap_or_default();
10411        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10412        let symbol = Self::deserialize_symbol(symbol)?;
10413        this.read_with(&cx, |this, _| {
10414            if let SymbolLocation::OutsideProject {
10415                abs_path,
10416                signature,
10417            } = &symbol.path
10418            {
10419                let new_signature = this.symbol_signature(&abs_path);
10420                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10421            }
10422            Ok(())
10423        })?;
10424        let buffer = this
10425            .update(&mut cx, |this, cx| {
10426                this.open_buffer_for_symbol(
10427                    &Symbol {
10428                        language_server_name: symbol.language_server_name,
10429                        source_worktree_id: symbol.source_worktree_id,
10430                        source_language_server_id: symbol.source_language_server_id,
10431                        path: symbol.path,
10432                        name: symbol.name,
10433                        kind: symbol.kind,
10434                        range: symbol.range,
10435                        label: CodeLabel::default(),
10436                        container_name: symbol.container_name,
10437                    },
10438                    cx,
10439                )
10440            })
10441            .await?;
10442
10443        this.update(&mut cx, |this, cx| {
10444            let is_private = buffer
10445                .read(cx)
10446                .file()
10447                .map(|f| f.is_private())
10448                .unwrap_or_default();
10449            if is_private {
10450                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10451            } else {
10452                this.buffer_store
10453                    .update(cx, |buffer_store, cx| {
10454                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10455                    })
10456                    .detach_and_log_err(cx);
10457                let buffer_id = buffer.read(cx).remote_id().to_proto();
10458                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10459            }
10460        })
10461    }
10462
10463    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10464        let mut hasher = Sha256::new();
10465        hasher.update(abs_path.to_string_lossy().as_bytes());
10466        hasher.update(self.nonce.to_be_bytes());
10467        hasher.finalize().as_slice().try_into().unwrap()
10468    }
10469
10470    pub async fn handle_get_project_symbols(
10471        this: Entity<Self>,
10472        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10473        mut cx: AsyncApp,
10474    ) -> Result<proto::GetProjectSymbolsResponse> {
10475        let symbols = this
10476            .update(&mut cx, |this, cx| {
10477                this.symbols(&envelope.payload.query, cx)
10478            })
10479            .await?;
10480
10481        Ok(proto::GetProjectSymbolsResponse {
10482            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10483        })
10484    }
10485
10486    pub async fn handle_restart_language_servers(
10487        this: Entity<Self>,
10488        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10489        mut cx: AsyncApp,
10490    ) -> Result<proto::Ack> {
10491        this.update(&mut cx, |lsp_store, cx| {
10492            let buffers =
10493                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10494            lsp_store.restart_language_servers_for_buffers(
10495                buffers,
10496                envelope
10497                    .payload
10498                    .only_servers
10499                    .into_iter()
10500                    .filter_map(|selector| {
10501                        Some(match selector.selector? {
10502                            proto::language_server_selector::Selector::ServerId(server_id) => {
10503                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10504                            }
10505                            proto::language_server_selector::Selector::Name(name) => {
10506                                LanguageServerSelector::Name(LanguageServerName(
10507                                    SharedString::from(name),
10508                                ))
10509                            }
10510                        })
10511                    })
10512                    .collect(),
10513                cx,
10514            );
10515        });
10516
10517        Ok(proto::Ack {})
10518    }
10519
10520    pub async fn handle_stop_language_servers(
10521        lsp_store: Entity<Self>,
10522        envelope: TypedEnvelope<proto::StopLanguageServers>,
10523        mut cx: AsyncApp,
10524    ) -> Result<proto::Ack> {
10525        lsp_store.update(&mut cx, |lsp_store, cx| {
10526            if envelope.payload.all
10527                && envelope.payload.also_servers.is_empty()
10528                && envelope.payload.buffer_ids.is_empty()
10529            {
10530                lsp_store.stop_all_language_servers(cx);
10531            } else {
10532                let buffers =
10533                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10534                lsp_store
10535                    .stop_language_servers_for_buffers(
10536                        buffers,
10537                        envelope
10538                            .payload
10539                            .also_servers
10540                            .into_iter()
10541                            .filter_map(|selector| {
10542                                Some(match selector.selector? {
10543                                    proto::language_server_selector::Selector::ServerId(
10544                                        server_id,
10545                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10546                                        server_id,
10547                                    )),
10548                                    proto::language_server_selector::Selector::Name(name) => {
10549                                        LanguageServerSelector::Name(LanguageServerName(
10550                                            SharedString::from(name),
10551                                        ))
10552                                    }
10553                                })
10554                            })
10555                            .collect(),
10556                        cx,
10557                    )
10558                    .detach_and_log_err(cx);
10559            }
10560        });
10561
10562        Ok(proto::Ack {})
10563    }
10564
10565    pub async fn handle_cancel_language_server_work(
10566        lsp_store: Entity<Self>,
10567        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10568        mut cx: AsyncApp,
10569    ) -> Result<proto::Ack> {
10570        lsp_store.update(&mut cx, |lsp_store, cx| {
10571            if let Some(work) = envelope.payload.work {
10572                match work {
10573                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10574                        let buffers =
10575                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10576                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10577                    }
10578                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10579                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10580                        let token = work
10581                            .token
10582                            .map(|token| {
10583                                ProgressToken::from_proto(token)
10584                                    .context("invalid work progress token")
10585                            })
10586                            .transpose()?;
10587                        lsp_store.cancel_language_server_work(server_id, token, cx);
10588                    }
10589                }
10590            }
10591            anyhow::Ok(())
10592        })?;
10593
10594        Ok(proto::Ack {})
10595    }
10596
10597    fn buffer_ids_to_buffers(
10598        &mut self,
10599        buffer_ids: impl Iterator<Item = u64>,
10600        cx: &mut Context<Self>,
10601    ) -> Vec<Entity<Buffer>> {
10602        buffer_ids
10603            .into_iter()
10604            .flat_map(|buffer_id| {
10605                self.buffer_store
10606                    .read(cx)
10607                    .get(BufferId::new(buffer_id).log_err()?)
10608            })
10609            .collect::<Vec<_>>()
10610    }
10611
10612    async fn handle_apply_additional_edits_for_completion(
10613        this: Entity<Self>,
10614        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10615        mut cx: AsyncApp,
10616    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10617        let (buffer, completion, all_commit_ranges) = this.update(&mut cx, |this, cx| {
10618            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10619            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10620            let completion = Self::deserialize_completion(
10621                envelope.payload.completion.context("invalid completion")?,
10622            )?;
10623            let all_commit_ranges = envelope
10624                .payload
10625                .all_commit_ranges
10626                .into_iter()
10627                .map(language::proto::deserialize_anchor_range)
10628                .collect::<Result<Vec<_>, _>>()?;
10629            anyhow::Ok((buffer, completion, all_commit_ranges))
10630        })?;
10631
10632        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10633            this.apply_additional_edits_for_completion(
10634                buffer,
10635                Rc::new(RefCell::new(Box::new([Completion {
10636                    replace_range: completion.replace_range,
10637                    new_text: completion.new_text,
10638                    source: completion.source,
10639                    documentation: None,
10640                    label: CodeLabel::default(),
10641                    match_start: None,
10642                    snippet_deduplication_key: None,
10643                    insert_text_mode: None,
10644                    icon_path: None,
10645                    confirm: None,
10646                }]))),
10647                0,
10648                false,
10649                all_commit_ranges,
10650                cx,
10651            )
10652        });
10653
10654        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10655            transaction: apply_additional_edits
10656                .await?
10657                .as_ref()
10658                .map(language::proto::serialize_transaction),
10659        })
10660    }
10661
10662    pub fn last_formatting_failure(&self) -> Option<&str> {
10663        self.last_formatting_failure.as_deref()
10664    }
10665
10666    pub fn reset_last_formatting_failure(&mut self) {
10667        self.last_formatting_failure = None;
10668    }
10669
10670    pub fn environment_for_buffer(
10671        &self,
10672        buffer: &Entity<Buffer>,
10673        cx: &mut Context<Self>,
10674    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10675        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10676            environment.update(cx, |env, cx| {
10677                env.buffer_environment(buffer, &self.worktree_store, cx)
10678            })
10679        } else {
10680            Task::ready(None).shared()
10681        }
10682    }
10683
10684    pub fn format(
10685        &mut self,
10686        buffers: HashSet<Entity<Buffer>>,
10687        target: LspFormatTarget,
10688        push_to_history: bool,
10689        trigger: FormatTrigger,
10690        cx: &mut Context<Self>,
10691    ) -> Task<anyhow::Result<ProjectTransaction>> {
10692        let logger = zlog::scoped!("format");
10693        if self.as_local().is_some() {
10694            zlog::trace!(logger => "Formatting locally");
10695            let logger = zlog::scoped!(logger => "local");
10696            let buffers = buffers
10697                .into_iter()
10698                .map(|buffer_handle| {
10699                    let buffer = buffer_handle.read(cx);
10700                    let buffer_abs_path = File::from_dyn(buffer.file())
10701                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10702
10703                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10704                })
10705                .collect::<Vec<_>>();
10706
10707            cx.spawn(async move |lsp_store, cx| {
10708                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10709
10710                for (handle, abs_path, id) in buffers {
10711                    let env = lsp_store
10712                        .update(cx, |lsp_store, cx| {
10713                            lsp_store.environment_for_buffer(&handle, cx)
10714                        })?
10715                        .await;
10716
10717                    let ranges = match &target {
10718                        LspFormatTarget::Buffers => None,
10719                        LspFormatTarget::Ranges(ranges) => {
10720                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10721                        }
10722                    };
10723
10724                    formattable_buffers.push(FormattableBuffer {
10725                        handle,
10726                        abs_path,
10727                        env,
10728                        ranges,
10729                    });
10730                }
10731                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10732
10733                let format_timer = zlog::time!(logger => "Formatting buffers");
10734                let result = LocalLspStore::format_locally(
10735                    lsp_store.clone(),
10736                    formattable_buffers,
10737                    push_to_history,
10738                    trigger,
10739                    logger,
10740                    cx,
10741                )
10742                .await;
10743                format_timer.end();
10744
10745                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10746
10747                lsp_store.update(cx, |lsp_store, _| {
10748                    lsp_store.update_last_formatting_failure(&result);
10749                })?;
10750
10751                result
10752            })
10753        } else if let Some((client, project_id)) = self.upstream_client() {
10754            zlog::trace!(logger => "Formatting remotely");
10755            let logger = zlog::scoped!(logger => "remote");
10756
10757            let buffer_ranges = match &target {
10758                LspFormatTarget::Buffers => Vec::new(),
10759                LspFormatTarget::Ranges(ranges) => ranges
10760                    .iter()
10761                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10762                        buffer_id: buffer_id.to_proto(),
10763                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10764                    })
10765                    .collect(),
10766            };
10767
10768            let buffer_store = self.buffer_store();
10769            cx.spawn(async move |lsp_store, cx| {
10770                zlog::trace!(logger => "Sending remote format request");
10771                let request_timer = zlog::time!(logger => "remote format request");
10772                let result = client
10773                    .request(proto::FormatBuffers {
10774                        project_id,
10775                        trigger: trigger as i32,
10776                        buffer_ids: buffers
10777                            .iter()
10778                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10779                            .collect(),
10780                        buffer_ranges,
10781                    })
10782                    .await
10783                    .and_then(|result| result.transaction.context("missing transaction"));
10784                request_timer.end();
10785
10786                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10787
10788                lsp_store.update(cx, |lsp_store, _| {
10789                    lsp_store.update_last_formatting_failure(&result);
10790                })?;
10791
10792                let transaction_response = result?;
10793                let _timer = zlog::time!(logger => "deserializing project transaction");
10794                buffer_store
10795                    .update(cx, |buffer_store, cx| {
10796                        buffer_store.deserialize_project_transaction(
10797                            transaction_response,
10798                            push_to_history,
10799                            cx,
10800                        )
10801                    })
10802                    .await
10803            })
10804        } else {
10805            zlog::trace!(logger => "Not formatting");
10806            Task::ready(Ok(ProjectTransaction::default()))
10807        }
10808    }
10809
10810    async fn handle_format_buffers(
10811        this: Entity<Self>,
10812        envelope: TypedEnvelope<proto::FormatBuffers>,
10813        mut cx: AsyncApp,
10814    ) -> Result<proto::FormatBuffersResponse> {
10815        let sender_id = envelope.original_sender_id().unwrap_or_default();
10816        let format = this.update(&mut cx, |this, cx| {
10817            let mut buffers = HashSet::default();
10818            for buffer_id in &envelope.payload.buffer_ids {
10819                let buffer_id = BufferId::new(*buffer_id)?;
10820                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10821            }
10822
10823            let target = if envelope.payload.buffer_ranges.is_empty() {
10824                LspFormatTarget::Buffers
10825            } else {
10826                let mut ranges_map = BTreeMap::new();
10827                for buffer_range in &envelope.payload.buffer_ranges {
10828                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10829                    let ranges: Result<Vec<_>> = buffer_range
10830                        .ranges
10831                        .iter()
10832                        .map(|range| {
10833                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10834                        })
10835                        .collect();
10836                    ranges_map.insert(buffer_id, ranges?);
10837                }
10838                LspFormatTarget::Ranges(ranges_map)
10839            };
10840
10841            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10842            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10843        })?;
10844
10845        let project_transaction = format.await?;
10846        let project_transaction = this.update(&mut cx, |this, cx| {
10847            this.buffer_store.update(cx, |buffer_store, cx| {
10848                buffer_store.serialize_project_transaction_for_peer(
10849                    project_transaction,
10850                    sender_id,
10851                    cx,
10852                )
10853            })
10854        });
10855        Ok(proto::FormatBuffersResponse {
10856            transaction: Some(project_transaction),
10857        })
10858    }
10859
10860    async fn handle_apply_code_action_kind(
10861        this: Entity<Self>,
10862        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10863        mut cx: AsyncApp,
10864    ) -> Result<proto::ApplyCodeActionKindResponse> {
10865        let sender_id = envelope.original_sender_id().unwrap_or_default();
10866        let format = this.update(&mut cx, |this, cx| {
10867            let mut buffers = HashSet::default();
10868            for buffer_id in &envelope.payload.buffer_ids {
10869                let buffer_id = BufferId::new(*buffer_id)?;
10870                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10871            }
10872            let kind = match envelope.payload.kind.as_str() {
10873                "" => CodeActionKind::EMPTY,
10874                "quickfix" => CodeActionKind::QUICKFIX,
10875                "refactor" => CodeActionKind::REFACTOR,
10876                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10877                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10878                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10879                "source" => CodeActionKind::SOURCE,
10880                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10881                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10882                _ => anyhow::bail!(
10883                    "Invalid code action kind {}",
10884                    envelope.payload.kind.as_str()
10885                ),
10886            };
10887            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10888        })?;
10889
10890        let project_transaction = format.await?;
10891        let project_transaction = this.update(&mut cx, |this, cx| {
10892            this.buffer_store.update(cx, |buffer_store, cx| {
10893                buffer_store.serialize_project_transaction_for_peer(
10894                    project_transaction,
10895                    sender_id,
10896                    cx,
10897                )
10898            })
10899        });
10900        Ok(proto::ApplyCodeActionKindResponse {
10901            transaction: Some(project_transaction),
10902        })
10903    }
10904
10905    async fn shutdown_language_server(
10906        server_state: Option<LanguageServerState>,
10907        name: LanguageServerName,
10908        cx: &mut AsyncApp,
10909    ) {
10910        let server = match server_state {
10911            Some(LanguageServerState::Starting { startup, .. }) => {
10912                let mut timer = cx
10913                    .background_executor()
10914                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10915                    .fuse();
10916
10917                select! {
10918                    server = startup.fuse() => server,
10919                    () = timer => {
10920                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10921                        None
10922                    },
10923                }
10924            }
10925
10926            Some(LanguageServerState::Running { server, .. }) => Some(server),
10927
10928            None => None,
10929        };
10930
10931        let Some(server) = server else { return };
10932        if let Some(shutdown) = server.shutdown() {
10933            shutdown.await;
10934        }
10935    }
10936
10937    // Returns a list of all of the worktrees which no longer have a language server and the root path
10938    // for the stopped server
10939    fn stop_local_language_server(
10940        &mut self,
10941        server_id: LanguageServerId,
10942        cx: &mut Context<Self>,
10943    ) -> Task<()> {
10944        let local = match &mut self.mode {
10945            LspStoreMode::Local(local) => local,
10946            _ => {
10947                return Task::ready(());
10948            }
10949        };
10950
10951        // Remove this server ID from all entries in the given worktree.
10952        local
10953            .language_server_ids
10954            .retain(|_, state| state.id != server_id);
10955        self.buffer_store.update(cx, |buffer_store, cx| {
10956            for buffer in buffer_store.buffers() {
10957                buffer.update(cx, |buffer, cx| {
10958                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10959                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10960                });
10961            }
10962        });
10963
10964        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
10965        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10966            summaries.retain(|path, summaries_by_server_id| {
10967                if summaries_by_server_id.remove(&server_id).is_some() {
10968                    if let Some((client, project_id)) = self.downstream_client.clone() {
10969                        client
10970                            .send(proto::UpdateDiagnosticSummary {
10971                                project_id,
10972                                worktree_id: worktree_id.to_proto(),
10973                                summary: Some(proto::DiagnosticSummary {
10974                                    path: path.as_ref().to_proto(),
10975                                    language_server_id: server_id.0 as u64,
10976                                    error_count: 0,
10977                                    warning_count: 0,
10978                                }),
10979                                more_summaries: Vec::new(),
10980                            })
10981                            .log_err();
10982                    }
10983                    cleared_paths.push(ProjectPath {
10984                        worktree_id: *worktree_id,
10985                        path: path.clone(),
10986                    });
10987                    !summaries_by_server_id.is_empty()
10988                } else {
10989                    true
10990                }
10991            });
10992        }
10993        if !cleared_paths.is_empty() {
10994            cx.emit(LspStoreEvent::DiagnosticsUpdated {
10995                server_id,
10996                paths: cleared_paths,
10997            });
10998        }
10999
11000        let local = self.as_local_mut().unwrap();
11001        for diagnostics in local.diagnostics.values_mut() {
11002            diagnostics.retain(|_, diagnostics_by_server_id| {
11003                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
11004                    diagnostics_by_server_id.remove(ix);
11005                    !diagnostics_by_server_id.is_empty()
11006                } else {
11007                    true
11008                }
11009            });
11010        }
11011        local.language_server_watched_paths.remove(&server_id);
11012
11013        let server_state = local.language_servers.remove(&server_id);
11014        self.cleanup_lsp_data(server_id);
11015        let name = self
11016            .language_server_statuses
11017            .remove(&server_id)
11018            .map(|status| status.name)
11019            .or_else(|| {
11020                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
11021                    Some(adapter.name())
11022                } else {
11023                    None
11024                }
11025            });
11026
11027        if let Some(name) = name {
11028            log::info!("stopping language server {name}");
11029            self.languages
11030                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
11031            cx.notify();
11032
11033            return cx.spawn(async move |lsp_store, cx| {
11034                Self::shutdown_language_server(server_state, name.clone(), cx).await;
11035                lsp_store
11036                    .update(cx, |lsp_store, cx| {
11037                        lsp_store
11038                            .languages
11039                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
11040                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11041                        cx.notify();
11042                    })
11043                    .ok();
11044            });
11045        }
11046
11047        if server_state.is_some() {
11048            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11049        }
11050        Task::ready(())
11051    }
11052
11053    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
11054        self.shutdown_all_language_servers(cx).detach();
11055    }
11056
11057    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
11058        if let Some((client, project_id)) = self.upstream_client() {
11059            let request = client.request(proto::StopLanguageServers {
11060                project_id,
11061                buffer_ids: Vec::new(),
11062                also_servers: Vec::new(),
11063                all: true,
11064            });
11065            cx.background_spawn(async move {
11066                request.await.ok();
11067            })
11068        } else {
11069            let Some(local) = self.as_local_mut() else {
11070                return Task::ready(());
11071            };
11072            let language_servers_to_stop = local
11073                .language_server_ids
11074                .values()
11075                .map(|state| state.id)
11076                .collect();
11077            local.lsp_tree.remove_nodes(&language_servers_to_stop);
11078            let tasks = language_servers_to_stop
11079                .into_iter()
11080                .map(|server| self.stop_local_language_server(server, cx))
11081                .collect::<Vec<_>>();
11082            cx.background_spawn(async move {
11083                futures::future::join_all(tasks).await;
11084            })
11085        }
11086    }
11087
11088    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
11089        let buffers = self.buffer_store.read(cx).buffers().collect();
11090        self.restart_language_servers_for_buffers(buffers, HashSet::default(), cx);
11091    }
11092
11093    pub fn restart_language_servers_for_buffers(
11094        &mut self,
11095        buffers: Vec<Entity<Buffer>>,
11096        only_restart_servers: HashSet<LanguageServerSelector>,
11097        cx: &mut Context<Self>,
11098    ) {
11099        if let Some((client, project_id)) = self.upstream_client() {
11100            let request = client.request(proto::RestartLanguageServers {
11101                project_id,
11102                buffer_ids: buffers
11103                    .into_iter()
11104                    .map(|b| b.read(cx).remote_id().to_proto())
11105                    .collect(),
11106                only_servers: only_restart_servers
11107                    .into_iter()
11108                    .map(|selector| {
11109                        let selector = match selector {
11110                            LanguageServerSelector::Id(language_server_id) => {
11111                                proto::language_server_selector::Selector::ServerId(
11112                                    language_server_id.to_proto(),
11113                                )
11114                            }
11115                            LanguageServerSelector::Name(language_server_name) => {
11116                                proto::language_server_selector::Selector::Name(
11117                                    language_server_name.to_string(),
11118                                )
11119                            }
11120                        };
11121                        proto::LanguageServerSelector {
11122                            selector: Some(selector),
11123                        }
11124                    })
11125                    .collect(),
11126                all: false,
11127            });
11128            cx.background_spawn(request).detach_and_log_err(cx);
11129        } else {
11130            let stop_task = if only_restart_servers.is_empty() {
11131                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11132            } else {
11133                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11134            };
11135            cx.spawn(async move |lsp_store, cx| {
11136                stop_task.await;
11137                lsp_store.update(cx, |lsp_store, cx| {
11138                    for buffer in buffers {
11139                        lsp_store.register_buffer_with_language_servers(
11140                            &buffer,
11141                            only_restart_servers.clone(),
11142                            true,
11143                            cx,
11144                        );
11145                    }
11146                })
11147            })
11148            .detach();
11149        }
11150    }
11151
11152    pub fn stop_language_servers_for_buffers(
11153        &mut self,
11154        buffers: Vec<Entity<Buffer>>,
11155        also_stop_servers: HashSet<LanguageServerSelector>,
11156        cx: &mut Context<Self>,
11157    ) -> Task<Result<()>> {
11158        if let Some((client, project_id)) = self.upstream_client() {
11159            let request = client.request(proto::StopLanguageServers {
11160                project_id,
11161                buffer_ids: buffers
11162                    .into_iter()
11163                    .map(|b| b.read(cx).remote_id().to_proto())
11164                    .collect(),
11165                also_servers: also_stop_servers
11166                    .into_iter()
11167                    .map(|selector| {
11168                        let selector = match selector {
11169                            LanguageServerSelector::Id(language_server_id) => {
11170                                proto::language_server_selector::Selector::ServerId(
11171                                    language_server_id.to_proto(),
11172                                )
11173                            }
11174                            LanguageServerSelector::Name(language_server_name) => {
11175                                proto::language_server_selector::Selector::Name(
11176                                    language_server_name.to_string(),
11177                                )
11178                            }
11179                        };
11180                        proto::LanguageServerSelector {
11181                            selector: Some(selector),
11182                        }
11183                    })
11184                    .collect(),
11185                all: false,
11186            });
11187            cx.background_spawn(async move {
11188                let _ = request.await?;
11189                Ok(())
11190            })
11191        } else {
11192            let task =
11193                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11194            cx.background_spawn(async move {
11195                task.await;
11196                Ok(())
11197            })
11198        }
11199    }
11200
11201    fn stop_local_language_servers_for_buffers(
11202        &mut self,
11203        buffers: &[Entity<Buffer>],
11204        also_stop_servers: HashSet<LanguageServerSelector>,
11205        cx: &mut Context<Self>,
11206    ) -> Task<()> {
11207        let Some(local) = self.as_local_mut() else {
11208            return Task::ready(());
11209        };
11210        let mut language_server_names_to_stop = BTreeSet::default();
11211        let mut language_servers_to_stop = also_stop_servers
11212            .into_iter()
11213            .flat_map(|selector| match selector {
11214                LanguageServerSelector::Id(id) => Some(id),
11215                LanguageServerSelector::Name(name) => {
11216                    language_server_names_to_stop.insert(name);
11217                    None
11218                }
11219            })
11220            .collect::<BTreeSet<_>>();
11221
11222        let mut covered_worktrees = HashSet::default();
11223        for buffer in buffers {
11224            buffer.update(cx, |buffer, cx| {
11225                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11226                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11227                    && covered_worktrees.insert(worktree_id)
11228                {
11229                    language_server_names_to_stop.retain(|name| {
11230                        let old_ids_count = language_servers_to_stop.len();
11231                        let all_language_servers_with_this_name = local
11232                            .language_server_ids
11233                            .iter()
11234                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11235                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11236                        old_ids_count == language_servers_to_stop.len()
11237                    });
11238                }
11239            });
11240        }
11241        for name in language_server_names_to_stop {
11242            language_servers_to_stop.extend(
11243                local
11244                    .language_server_ids
11245                    .iter()
11246                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11247            );
11248        }
11249
11250        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11251        let tasks = language_servers_to_stop
11252            .into_iter()
11253            .map(|server| self.stop_local_language_server(server, cx))
11254            .collect::<Vec<_>>();
11255
11256        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11257    }
11258
11259    #[cfg(any(test, feature = "test-support"))]
11260    pub fn update_diagnostics(
11261        &mut self,
11262        server_id: LanguageServerId,
11263        diagnostics: lsp::PublishDiagnosticsParams,
11264        result_id: Option<SharedString>,
11265        source_kind: DiagnosticSourceKind,
11266        disk_based_sources: &[String],
11267        cx: &mut Context<Self>,
11268    ) -> Result<()> {
11269        self.merge_lsp_diagnostics(
11270            source_kind,
11271            vec![DocumentDiagnosticsUpdate {
11272                diagnostics,
11273                result_id,
11274                server_id,
11275                disk_based_sources: Cow::Borrowed(disk_based_sources),
11276                registration_id: None,
11277            }],
11278            |_, _, _| false,
11279            cx,
11280        )
11281    }
11282
11283    pub fn merge_lsp_diagnostics(
11284        &mut self,
11285        source_kind: DiagnosticSourceKind,
11286        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11287        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11288        cx: &mut Context<Self>,
11289    ) -> Result<()> {
11290        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11291        let updates = lsp_diagnostics
11292            .into_iter()
11293            .filter_map(|update| {
11294                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11295                Some(DocumentDiagnosticsUpdate {
11296                    diagnostics: self.lsp_to_document_diagnostics(
11297                        abs_path,
11298                        source_kind,
11299                        update.server_id,
11300                        update.diagnostics,
11301                        &update.disk_based_sources,
11302                        update.registration_id.clone(),
11303                    ),
11304                    result_id: update.result_id,
11305                    server_id: update.server_id,
11306                    disk_based_sources: update.disk_based_sources,
11307                    registration_id: update.registration_id,
11308                })
11309            })
11310            .collect();
11311        self.merge_diagnostic_entries(updates, merge, cx)?;
11312        Ok(())
11313    }
11314
11315    fn lsp_to_document_diagnostics(
11316        &mut self,
11317        document_abs_path: PathBuf,
11318        source_kind: DiagnosticSourceKind,
11319        server_id: LanguageServerId,
11320        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11321        disk_based_sources: &[String],
11322        registration_id: Option<SharedString>,
11323    ) -> DocumentDiagnostics {
11324        let mut diagnostics = Vec::default();
11325        let mut primary_diagnostic_group_ids = HashMap::default();
11326        let mut sources_by_group_id = HashMap::default();
11327        let mut supporting_diagnostics = HashMap::default();
11328
11329        let adapter = self.language_server_adapter_for_id(server_id);
11330
11331        // Ensure that primary diagnostics are always the most severe
11332        lsp_diagnostics
11333            .diagnostics
11334            .sort_by_key(|item| item.severity);
11335
11336        for diagnostic in &lsp_diagnostics.diagnostics {
11337            let source = diagnostic.source.as_ref();
11338            let range = range_from_lsp(diagnostic.range);
11339            let is_supporting = diagnostic
11340                .related_information
11341                .as_ref()
11342                .is_some_and(|infos| {
11343                    infos.iter().any(|info| {
11344                        primary_diagnostic_group_ids.contains_key(&(
11345                            source,
11346                            diagnostic.code.clone(),
11347                            range_from_lsp(info.location.range),
11348                        ))
11349                    })
11350                });
11351
11352            let is_unnecessary = diagnostic
11353                .tags
11354                .as_ref()
11355                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11356
11357            let underline = self
11358                .language_server_adapter_for_id(server_id)
11359                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11360
11361            if is_supporting {
11362                supporting_diagnostics.insert(
11363                    (source, diagnostic.code.clone(), range),
11364                    (diagnostic.severity, is_unnecessary),
11365                );
11366            } else {
11367                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11368                let is_disk_based =
11369                    source.is_some_and(|source| disk_based_sources.contains(source));
11370
11371                sources_by_group_id.insert(group_id, source);
11372                primary_diagnostic_group_ids
11373                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11374
11375                diagnostics.push(DiagnosticEntry {
11376                    range,
11377                    diagnostic: Diagnostic {
11378                        source: diagnostic.source.clone(),
11379                        source_kind,
11380                        code: diagnostic.code.clone(),
11381                        code_description: diagnostic
11382                            .code_description
11383                            .as_ref()
11384                            .and_then(|d| d.href.clone()),
11385                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11386                        markdown: adapter.as_ref().and_then(|adapter| {
11387                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11388                        }),
11389                        message: diagnostic.message.trim().to_string(),
11390                        group_id,
11391                        is_primary: true,
11392                        is_disk_based,
11393                        is_unnecessary,
11394                        underline,
11395                        data: diagnostic.data.clone(),
11396                        registration_id: registration_id.clone(),
11397                    },
11398                });
11399                if let Some(infos) = &diagnostic.related_information {
11400                    for info in infos {
11401                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11402                            let range = range_from_lsp(info.location.range);
11403                            diagnostics.push(DiagnosticEntry {
11404                                range,
11405                                diagnostic: Diagnostic {
11406                                    source: diagnostic.source.clone(),
11407                                    source_kind,
11408                                    code: diagnostic.code.clone(),
11409                                    code_description: diagnostic
11410                                        .code_description
11411                                        .as_ref()
11412                                        .and_then(|d| d.href.clone()),
11413                                    severity: DiagnosticSeverity::INFORMATION,
11414                                    markdown: adapter.as_ref().and_then(|adapter| {
11415                                        adapter.diagnostic_message_to_markdown(&info.message)
11416                                    }),
11417                                    message: info.message.trim().to_string(),
11418                                    group_id,
11419                                    is_primary: false,
11420                                    is_disk_based,
11421                                    is_unnecessary: false,
11422                                    underline,
11423                                    data: diagnostic.data.clone(),
11424                                    registration_id: registration_id.clone(),
11425                                },
11426                            });
11427                        }
11428                    }
11429                }
11430            }
11431        }
11432
11433        for entry in &mut diagnostics {
11434            let diagnostic = &mut entry.diagnostic;
11435            if !diagnostic.is_primary {
11436                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11437                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11438                    source,
11439                    diagnostic.code.clone(),
11440                    entry.range.clone(),
11441                )) {
11442                    if let Some(severity) = severity {
11443                        diagnostic.severity = severity;
11444                    }
11445                    diagnostic.is_unnecessary = is_unnecessary;
11446                }
11447            }
11448        }
11449
11450        DocumentDiagnostics {
11451            diagnostics,
11452            document_abs_path,
11453            version: lsp_diagnostics.version,
11454        }
11455    }
11456
11457    fn insert_newly_running_language_server(
11458        &mut self,
11459        adapter: Arc<CachedLspAdapter>,
11460        language_server: Arc<LanguageServer>,
11461        server_id: LanguageServerId,
11462        key: LanguageServerSeed,
11463        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11464        cx: &mut Context<Self>,
11465    ) {
11466        let Some(local) = self.as_local_mut() else {
11467            return;
11468        };
11469        // If the language server for this key doesn't match the server id, don't store the
11470        // server. Which will cause it to be dropped, killing the process
11471        if local
11472            .language_server_ids
11473            .get(&key)
11474            .map(|state| state.id != server_id)
11475            .unwrap_or(false)
11476        {
11477            return;
11478        }
11479
11480        // Update language_servers collection with Running variant of LanguageServerState
11481        // indicating that the server is up and running and ready
11482        let workspace_folders = workspace_folders.lock().clone();
11483        language_server.set_workspace_folders(workspace_folders);
11484
11485        let workspace_diagnostics_refresh_tasks = language_server
11486            .capabilities()
11487            .diagnostic_provider
11488            .and_then(|provider| {
11489                local
11490                    .language_server_dynamic_registrations
11491                    .entry(server_id)
11492                    .or_default()
11493                    .diagnostics
11494                    .entry(None)
11495                    .or_insert(provider.clone());
11496                let workspace_refresher =
11497                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11498
11499                Some((None, workspace_refresher))
11500            })
11501            .into_iter()
11502            .collect();
11503        local.language_servers.insert(
11504            server_id,
11505            LanguageServerState::Running {
11506                workspace_diagnostics_refresh_tasks,
11507                adapter: adapter.clone(),
11508                server: language_server.clone(),
11509                simulate_disk_based_diagnostics_completion: None,
11510            },
11511        );
11512        local
11513            .languages
11514            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11515        if let Some(file_ops_caps) = language_server
11516            .capabilities()
11517            .workspace
11518            .as_ref()
11519            .and_then(|ws| ws.file_operations.as_ref())
11520        {
11521            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11522            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11523            if did_rename_caps.or(will_rename_caps).is_some() {
11524                let watcher = RenamePathsWatchedForServer::default()
11525                    .with_did_rename_patterns(did_rename_caps)
11526                    .with_will_rename_patterns(will_rename_caps);
11527                local
11528                    .language_server_paths_watched_for_rename
11529                    .insert(server_id, watcher);
11530            }
11531        }
11532
11533        self.language_server_statuses.insert(
11534            server_id,
11535            LanguageServerStatus {
11536                name: language_server.name(),
11537                server_version: language_server.version(),
11538                server_readable_version: language_server.readable_version(),
11539                pending_work: Default::default(),
11540                has_pending_diagnostic_updates: false,
11541                progress_tokens: Default::default(),
11542                worktree: Some(key.worktree_id),
11543                binary: Some(language_server.binary().clone()),
11544                configuration: Some(language_server.configuration().clone()),
11545                workspace_folders: language_server.workspace_folders(),
11546                process_id: language_server.process_id(),
11547            },
11548        );
11549
11550        cx.emit(LspStoreEvent::LanguageServerAdded(
11551            server_id,
11552            language_server.name(),
11553            Some(key.worktree_id),
11554        ));
11555
11556        let server_capabilities = language_server.capabilities();
11557        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11558            downstream_client
11559                .send(proto::StartLanguageServer {
11560                    project_id: *project_id,
11561                    server: Some(proto::LanguageServer {
11562                        id: server_id.to_proto(),
11563                        name: language_server.name().to_string(),
11564                        worktree_id: Some(key.worktree_id.to_proto()),
11565                    }),
11566                    capabilities: serde_json::to_string(&server_capabilities)
11567                        .expect("serializing server LSP capabilities"),
11568                })
11569                .log_err();
11570        }
11571        self.lsp_server_capabilities
11572            .insert(server_id, server_capabilities);
11573
11574        // Tell the language server about every open buffer in the worktree that matches the language.
11575        // Also check for buffers in worktrees that reused this server
11576        let mut worktrees_using_server = vec![key.worktree_id];
11577        if let Some(local) = self.as_local() {
11578            // Find all worktrees that have this server in their language server tree
11579            for (worktree_id, servers) in &local.lsp_tree.instances {
11580                if *worktree_id != key.worktree_id {
11581                    for server_map in servers.roots.values() {
11582                        if server_map
11583                            .values()
11584                            .any(|(node, _)| node.id() == Some(server_id))
11585                        {
11586                            worktrees_using_server.push(*worktree_id);
11587                        }
11588                    }
11589                }
11590            }
11591        }
11592
11593        let mut buffer_paths_registered = Vec::new();
11594        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11595            let mut lsp_adapters = HashMap::default();
11596            for buffer_handle in buffer_store.buffers() {
11597                let buffer = buffer_handle.read(cx);
11598                let file = match File::from_dyn(buffer.file()) {
11599                    Some(file) => file,
11600                    None => continue,
11601                };
11602                let language = match buffer.language() {
11603                    Some(language) => language,
11604                    None => continue,
11605                };
11606
11607                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11608                    || !lsp_adapters
11609                        .entry(language.name())
11610                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11611                        .iter()
11612                        .any(|a| a.name == key.name)
11613                {
11614                    continue;
11615                }
11616                // didOpen
11617                let file = match file.as_local() {
11618                    Some(file) => file,
11619                    None => continue,
11620                };
11621
11622                let local = self.as_local_mut().unwrap();
11623
11624                let buffer_id = buffer.remote_id();
11625                if local.registered_buffers.contains_key(&buffer_id) {
11626                    let abs_path = file.abs_path(cx);
11627                    let uri = match lsp::Uri::from_file_path(&abs_path) {
11628                        Ok(uri) => uri,
11629                        Err(()) => {
11630                            log::error!("failed to convert path to URI: {:?}", abs_path);
11631                            continue;
11632                        }
11633                    };
11634
11635                    let versions = local
11636                        .buffer_snapshots
11637                        .entry(buffer_id)
11638                        .or_default()
11639                        .entry(server_id)
11640                        .and_modify(|_| {
11641                            assert!(
11642                            false,
11643                            "There should not be an existing snapshot for a newly inserted buffer"
11644                        )
11645                        })
11646                        .or_insert_with(|| {
11647                            vec![LspBufferSnapshot {
11648                                version: 0,
11649                                snapshot: buffer.text_snapshot(),
11650                            }]
11651                        });
11652
11653                    let snapshot = versions.last().unwrap();
11654                    let version = snapshot.version;
11655                    let initial_snapshot = &snapshot.snapshot;
11656                    language_server.register_buffer(
11657                        uri,
11658                        adapter.language_id(&language.name()),
11659                        version,
11660                        initial_snapshot.text(),
11661                    );
11662                    buffer_paths_registered.push((buffer_id, abs_path));
11663                    local
11664                        .buffers_opened_in_servers
11665                        .entry(buffer_id)
11666                        .or_default()
11667                        .insert(server_id);
11668                }
11669                buffer_handle.update(cx, |buffer, cx| {
11670                    buffer.set_completion_triggers(
11671                        server_id,
11672                        language_server
11673                            .capabilities()
11674                            .completion_provider
11675                            .as_ref()
11676                            .and_then(|provider| {
11677                                provider
11678                                    .trigger_characters
11679                                    .as_ref()
11680                                    .map(|characters| characters.iter().cloned().collect())
11681                            })
11682                            .unwrap_or_default(),
11683                        cx,
11684                    )
11685                });
11686            }
11687        });
11688
11689        for (buffer_id, abs_path) in buffer_paths_registered {
11690            cx.emit(LspStoreEvent::LanguageServerUpdate {
11691                language_server_id: server_id,
11692                name: Some(adapter.name()),
11693                message: proto::update_language_server::Variant::RegisteredForBuffer(
11694                    proto::RegisteredForBuffer {
11695                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11696                        buffer_id: buffer_id.to_proto(),
11697                    },
11698                ),
11699            });
11700        }
11701
11702        cx.notify();
11703    }
11704
11705    pub fn language_servers_running_disk_based_diagnostics(
11706        &self,
11707    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11708        self.language_server_statuses
11709            .iter()
11710            .filter_map(|(id, status)| {
11711                if status.has_pending_diagnostic_updates {
11712                    Some(*id)
11713                } else {
11714                    None
11715                }
11716            })
11717    }
11718
11719    pub(crate) fn cancel_language_server_work_for_buffers(
11720        &mut self,
11721        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11722        cx: &mut Context<Self>,
11723    ) {
11724        if let Some((client, project_id)) = self.upstream_client() {
11725            let request = client.request(proto::CancelLanguageServerWork {
11726                project_id,
11727                work: Some(proto::cancel_language_server_work::Work::Buffers(
11728                    proto::cancel_language_server_work::Buffers {
11729                        buffer_ids: buffers
11730                            .into_iter()
11731                            .map(|b| b.read(cx).remote_id().to_proto())
11732                            .collect(),
11733                    },
11734                )),
11735            });
11736            cx.background_spawn(request).detach_and_log_err(cx);
11737        } else if let Some(local) = self.as_local() {
11738            let servers = buffers
11739                .into_iter()
11740                .flat_map(|buffer| {
11741                    buffer.update(cx, |buffer, cx| {
11742                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11743                    })
11744                })
11745                .collect::<HashSet<_>>();
11746            for server_id in servers {
11747                self.cancel_language_server_work(server_id, None, cx);
11748            }
11749        }
11750    }
11751
11752    pub(crate) fn cancel_language_server_work(
11753        &mut self,
11754        server_id: LanguageServerId,
11755        token_to_cancel: Option<ProgressToken>,
11756        cx: &mut Context<Self>,
11757    ) {
11758        if let Some(local) = self.as_local() {
11759            let status = self.language_server_statuses.get(&server_id);
11760            let server = local.language_servers.get(&server_id);
11761            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11762            {
11763                for (token, progress) in &status.pending_work {
11764                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11765                        && token != token_to_cancel
11766                    {
11767                        continue;
11768                    }
11769                    if progress.is_cancellable {
11770                        server
11771                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11772                                WorkDoneProgressCancelParams {
11773                                    token: token.to_lsp(),
11774                                },
11775                            )
11776                            .ok();
11777                    }
11778                }
11779            }
11780        } else if let Some((client, project_id)) = self.upstream_client() {
11781            let request = client.request(proto::CancelLanguageServerWork {
11782                project_id,
11783                work: Some(
11784                    proto::cancel_language_server_work::Work::LanguageServerWork(
11785                        proto::cancel_language_server_work::LanguageServerWork {
11786                            language_server_id: server_id.to_proto(),
11787                            token: token_to_cancel.map(|token| token.to_proto()),
11788                        },
11789                    ),
11790                ),
11791            });
11792            cx.background_spawn(request).detach_and_log_err(cx);
11793        }
11794    }
11795
11796    fn register_supplementary_language_server(
11797        &mut self,
11798        id: LanguageServerId,
11799        name: LanguageServerName,
11800        server: Arc<LanguageServer>,
11801        cx: &mut Context<Self>,
11802    ) {
11803        if let Some(local) = self.as_local_mut() {
11804            local
11805                .supplementary_language_servers
11806                .insert(id, (name.clone(), server));
11807            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11808        }
11809    }
11810
11811    fn unregister_supplementary_language_server(
11812        &mut self,
11813        id: LanguageServerId,
11814        cx: &mut Context<Self>,
11815    ) {
11816        if let Some(local) = self.as_local_mut() {
11817            local.supplementary_language_servers.remove(&id);
11818            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11819        }
11820    }
11821
11822    pub(crate) fn supplementary_language_servers(
11823        &self,
11824    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11825        self.as_local().into_iter().flat_map(|local| {
11826            local
11827                .supplementary_language_servers
11828                .iter()
11829                .map(|(id, (name, _))| (*id, name.clone()))
11830        })
11831    }
11832
11833    pub fn language_server_adapter_for_id(
11834        &self,
11835        id: LanguageServerId,
11836    ) -> Option<Arc<CachedLspAdapter>> {
11837        self.as_local()
11838            .and_then(|local| local.language_servers.get(&id))
11839            .and_then(|language_server_state| match language_server_state {
11840                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11841                _ => None,
11842            })
11843    }
11844
11845    pub(super) fn update_local_worktree_language_servers(
11846        &mut self,
11847        worktree_handle: &Entity<Worktree>,
11848        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11849        cx: &mut Context<Self>,
11850    ) {
11851        if changes.is_empty() {
11852            return;
11853        }
11854
11855        let Some(local) = self.as_local() else { return };
11856
11857        local.prettier_store.update(cx, |prettier_store, cx| {
11858            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11859        });
11860
11861        let worktree_id = worktree_handle.read(cx).id();
11862        let mut language_server_ids = local
11863            .language_server_ids
11864            .iter()
11865            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11866            .collect::<Vec<_>>();
11867        language_server_ids.sort();
11868        language_server_ids.dedup();
11869
11870        // let abs_path = worktree_handle.read(cx).abs_path();
11871        for server_id in &language_server_ids {
11872            if let Some(LanguageServerState::Running { server, .. }) =
11873                local.language_servers.get(server_id)
11874                && let Some(watched_paths) = local
11875                    .language_server_watched_paths
11876                    .get(server_id)
11877                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11878            {
11879                let params = lsp::DidChangeWatchedFilesParams {
11880                    changes: changes
11881                        .iter()
11882                        .filter_map(|(path, _, change)| {
11883                            if !watched_paths.is_match(path.as_std_path()) {
11884                                return None;
11885                            }
11886                            let typ = match change {
11887                                PathChange::Loaded => return None,
11888                                PathChange::Added => lsp::FileChangeType::CREATED,
11889                                PathChange::Removed => lsp::FileChangeType::DELETED,
11890                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11891                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11892                            };
11893                            let uri = lsp::Uri::from_file_path(
11894                                worktree_handle.read(cx).absolutize(&path),
11895                            )
11896                            .ok()?;
11897                            Some(lsp::FileEvent { uri, typ })
11898                        })
11899                        .collect(),
11900                };
11901                if !params.changes.is_empty() {
11902                    server
11903                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11904                        .ok();
11905                }
11906            }
11907        }
11908        for (path, _, _) in changes {
11909            if let Some(file_name) = path.file_name()
11910                && local.watched_manifest_filenames.contains(file_name)
11911            {
11912                self.request_workspace_config_refresh();
11913                break;
11914            }
11915        }
11916    }
11917
11918    pub fn wait_for_remote_buffer(
11919        &mut self,
11920        id: BufferId,
11921        cx: &mut Context<Self>,
11922    ) -> Task<Result<Entity<Buffer>>> {
11923        self.buffer_store.update(cx, |buffer_store, cx| {
11924            buffer_store.wait_for_remote_buffer(id, cx)
11925        })
11926    }
11927
11928    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11929        let mut result = proto::Symbol {
11930            language_server_name: symbol.language_server_name.0.to_string(),
11931            source_worktree_id: symbol.source_worktree_id.to_proto(),
11932            language_server_id: symbol.source_language_server_id.to_proto(),
11933            name: symbol.name.clone(),
11934            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11935            start: Some(proto::PointUtf16 {
11936                row: symbol.range.start.0.row,
11937                column: symbol.range.start.0.column,
11938            }),
11939            end: Some(proto::PointUtf16 {
11940                row: symbol.range.end.0.row,
11941                column: symbol.range.end.0.column,
11942            }),
11943            worktree_id: Default::default(),
11944            path: Default::default(),
11945            signature: Default::default(),
11946            container_name: symbol.container_name.clone(),
11947        };
11948        match &symbol.path {
11949            SymbolLocation::InProject(path) => {
11950                result.worktree_id = path.worktree_id.to_proto();
11951                result.path = path.path.to_proto();
11952            }
11953            SymbolLocation::OutsideProject {
11954                abs_path,
11955                signature,
11956            } => {
11957                result.path = abs_path.to_string_lossy().into_owned();
11958                result.signature = signature.to_vec();
11959            }
11960        }
11961        result
11962    }
11963
11964    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11965        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11966        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11967        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11968
11969        let path = if serialized_symbol.signature.is_empty() {
11970            SymbolLocation::InProject(ProjectPath {
11971                worktree_id,
11972                path: RelPath::from_proto(&serialized_symbol.path)
11973                    .context("invalid symbol path")?,
11974            })
11975        } else {
11976            SymbolLocation::OutsideProject {
11977                abs_path: Path::new(&serialized_symbol.path).into(),
11978                signature: serialized_symbol
11979                    .signature
11980                    .try_into()
11981                    .map_err(|_| anyhow!("invalid signature"))?,
11982            }
11983        };
11984
11985        let start = serialized_symbol.start.context("invalid start")?;
11986        let end = serialized_symbol.end.context("invalid end")?;
11987        Ok(CoreSymbol {
11988            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11989            source_worktree_id,
11990            source_language_server_id: LanguageServerId::from_proto(
11991                serialized_symbol.language_server_id,
11992            ),
11993            path,
11994            name: serialized_symbol.name,
11995            range: Unclipped(PointUtf16::new(start.row, start.column))
11996                ..Unclipped(PointUtf16::new(end.row, end.column)),
11997            kind,
11998            container_name: serialized_symbol.container_name,
11999        })
12000    }
12001
12002    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
12003        let mut serialized_completion = proto::Completion {
12004            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
12005            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
12006            new_text: completion.new_text.clone(),
12007            ..proto::Completion::default()
12008        };
12009        match &completion.source {
12010            CompletionSource::Lsp {
12011                insert_range,
12012                server_id,
12013                lsp_completion,
12014                lsp_defaults,
12015                resolved,
12016            } => {
12017                let (old_insert_start, old_insert_end) = insert_range
12018                    .as_ref()
12019                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
12020                    .unzip();
12021
12022                serialized_completion.old_insert_start = old_insert_start;
12023                serialized_completion.old_insert_end = old_insert_end;
12024                serialized_completion.source = proto::completion::Source::Lsp as i32;
12025                serialized_completion.server_id = server_id.0 as u64;
12026                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
12027                serialized_completion.lsp_defaults = lsp_defaults
12028                    .as_deref()
12029                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
12030                serialized_completion.resolved = *resolved;
12031            }
12032            CompletionSource::BufferWord {
12033                word_range,
12034                resolved,
12035            } => {
12036                serialized_completion.source = proto::completion::Source::BufferWord as i32;
12037                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
12038                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
12039                serialized_completion.resolved = *resolved;
12040            }
12041            CompletionSource::Custom => {
12042                serialized_completion.source = proto::completion::Source::Custom as i32;
12043                serialized_completion.resolved = true;
12044            }
12045            CompletionSource::Dap { sort_text } => {
12046                serialized_completion.source = proto::completion::Source::Dap as i32;
12047                serialized_completion.sort_text = Some(sort_text.clone());
12048            }
12049        }
12050
12051        serialized_completion
12052    }
12053
12054    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
12055        let old_replace_start = completion
12056            .old_replace_start
12057            .and_then(deserialize_anchor)
12058            .context("invalid old start")?;
12059        let old_replace_end = completion
12060            .old_replace_end
12061            .and_then(deserialize_anchor)
12062            .context("invalid old end")?;
12063        let insert_range = {
12064            match completion.old_insert_start.zip(completion.old_insert_end) {
12065                Some((start, end)) => {
12066                    let start = deserialize_anchor(start).context("invalid insert old start")?;
12067                    let end = deserialize_anchor(end).context("invalid insert old end")?;
12068                    Some(start..end)
12069                }
12070                None => None,
12071            }
12072        };
12073        Ok(CoreCompletion {
12074            replace_range: old_replace_start..old_replace_end,
12075            new_text: completion.new_text,
12076            source: match proto::completion::Source::from_i32(completion.source) {
12077                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
12078                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
12079                    insert_range,
12080                    server_id: LanguageServerId::from_proto(completion.server_id),
12081                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
12082                    lsp_defaults: completion
12083                        .lsp_defaults
12084                        .as_deref()
12085                        .map(serde_json::from_slice)
12086                        .transpose()?,
12087                    resolved: completion.resolved,
12088                },
12089                Some(proto::completion::Source::BufferWord) => {
12090                    let word_range = completion
12091                        .buffer_word_start
12092                        .and_then(deserialize_anchor)
12093                        .context("invalid buffer word start")?
12094                        ..completion
12095                            .buffer_word_end
12096                            .and_then(deserialize_anchor)
12097                            .context("invalid buffer word end")?;
12098                    CompletionSource::BufferWord {
12099                        word_range,
12100                        resolved: completion.resolved,
12101                    }
12102                }
12103                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12104                    sort_text: completion
12105                        .sort_text
12106                        .context("expected sort text to exist")?,
12107                },
12108                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12109            },
12110        })
12111    }
12112
12113    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12114        let (kind, lsp_action) = match &action.lsp_action {
12115            LspAction::Action(code_action) => (
12116                proto::code_action::Kind::Action as i32,
12117                serde_json::to_vec(code_action).unwrap(),
12118            ),
12119            LspAction::Command(command) => (
12120                proto::code_action::Kind::Command as i32,
12121                serde_json::to_vec(command).unwrap(),
12122            ),
12123            LspAction::CodeLens(code_lens) => (
12124                proto::code_action::Kind::CodeLens as i32,
12125                serde_json::to_vec(code_lens).unwrap(),
12126            ),
12127        };
12128
12129        proto::CodeAction {
12130            server_id: action.server_id.0 as u64,
12131            start: Some(serialize_anchor(&action.range.start)),
12132            end: Some(serialize_anchor(&action.range.end)),
12133            lsp_action,
12134            kind,
12135            resolved: action.resolved,
12136        }
12137    }
12138
12139    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12140        let start = action
12141            .start
12142            .and_then(deserialize_anchor)
12143            .context("invalid start")?;
12144        let end = action
12145            .end
12146            .and_then(deserialize_anchor)
12147            .context("invalid end")?;
12148        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12149            Some(proto::code_action::Kind::Action) => {
12150                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12151            }
12152            Some(proto::code_action::Kind::Command) => {
12153                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12154            }
12155            Some(proto::code_action::Kind::CodeLens) => {
12156                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12157            }
12158            None => anyhow::bail!("Unknown action kind {}", action.kind),
12159        };
12160        Ok(CodeAction {
12161            server_id: LanguageServerId(action.server_id as usize),
12162            range: start..end,
12163            resolved: action.resolved,
12164            lsp_action,
12165        })
12166    }
12167
12168    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12169        match &formatting_result {
12170            Ok(_) => self.last_formatting_failure = None,
12171            Err(error) => {
12172                let error_string = format!("{error:#}");
12173                log::error!("Formatting failed: {error_string}");
12174                self.last_formatting_failure
12175                    .replace(error_string.lines().join(" "));
12176            }
12177        }
12178    }
12179
12180    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12181        self.lsp_server_capabilities.remove(&for_server);
12182        self.semantic_token_config.remove_server_data(for_server);
12183        for lsp_data in self.lsp_data.values_mut() {
12184            lsp_data.remove_server_data(for_server);
12185        }
12186        if let Some(local) = self.as_local_mut() {
12187            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12188            local
12189                .workspace_pull_diagnostics_result_ids
12190                .remove(&for_server);
12191            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12192                buffer_servers.remove(&for_server);
12193            }
12194        }
12195    }
12196
12197    pub fn result_id_for_buffer_pull(
12198        &self,
12199        server_id: LanguageServerId,
12200        buffer_id: BufferId,
12201        registration_id: &Option<SharedString>,
12202        cx: &App,
12203    ) -> Option<SharedString> {
12204        let abs_path = self
12205            .buffer_store
12206            .read(cx)
12207            .get(buffer_id)
12208            .and_then(|b| File::from_dyn(b.read(cx).file()))
12209            .map(|f| f.abs_path(cx))?;
12210        self.as_local()?
12211            .buffer_pull_diagnostics_result_ids
12212            .get(&server_id)?
12213            .get(registration_id)?
12214            .get(&abs_path)?
12215            .clone()
12216    }
12217
12218    /// Gets all result_ids for a workspace diagnostics pull request.
12219    /// 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.
12220    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12221    pub fn result_ids_for_workspace_refresh(
12222        &self,
12223        server_id: LanguageServerId,
12224        registration_id: &Option<SharedString>,
12225    ) -> HashMap<PathBuf, SharedString> {
12226        let Some(local) = self.as_local() else {
12227            return HashMap::default();
12228        };
12229        local
12230            .workspace_pull_diagnostics_result_ids
12231            .get(&server_id)
12232            .into_iter()
12233            .filter_map(|diagnostics| diagnostics.get(registration_id))
12234            .flatten()
12235            .filter_map(|(abs_path, result_id)| {
12236                let result_id = local
12237                    .buffer_pull_diagnostics_result_ids
12238                    .get(&server_id)
12239                    .and_then(|buffer_ids_result_ids| {
12240                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12241                    })
12242                    .cloned()
12243                    .flatten()
12244                    .or_else(|| result_id.clone())?;
12245                Some((abs_path.clone(), result_id))
12246            })
12247            .collect()
12248    }
12249
12250    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12251        if let Some(LanguageServerState::Running {
12252            workspace_diagnostics_refresh_tasks,
12253            ..
12254        }) = self
12255            .as_local_mut()
12256            .and_then(|local| local.language_servers.get_mut(&server_id))
12257        {
12258            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12259                diagnostics.refresh_tx.try_send(()).ok();
12260            }
12261        }
12262    }
12263
12264    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12265    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12266    /// which requires refreshing both workspace and document diagnostics.
12267    pub fn pull_document_diagnostics_for_server(
12268        &mut self,
12269        server_id: LanguageServerId,
12270        source_buffer_id: Option<BufferId>,
12271        cx: &mut Context<Self>,
12272    ) -> Shared<Task<()>> {
12273        let Some(local) = self.as_local_mut() else {
12274            return Task::ready(()).shared();
12275        };
12276        let mut buffers_to_refresh = HashSet::default();
12277        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12278            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12279                buffers_to_refresh.insert(*buffer_id);
12280            }
12281        }
12282
12283        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12284    }
12285
12286    pub fn pull_document_diagnostics_for_buffer_edit(
12287        &mut self,
12288        buffer_id: BufferId,
12289        cx: &mut Context<Self>,
12290    ) {
12291        let Some(local) = self.as_local_mut() else {
12292            return;
12293        };
12294        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12295        else {
12296            return;
12297        };
12298        for server_id in languages_servers {
12299            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12300        }
12301    }
12302
12303    fn apply_workspace_diagnostic_report(
12304        &mut self,
12305        server_id: LanguageServerId,
12306        report: lsp::WorkspaceDiagnosticReportResult,
12307        registration_id: Option<SharedString>,
12308        cx: &mut Context<Self>,
12309    ) {
12310        let mut workspace_diagnostics =
12311            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12312                report,
12313                server_id,
12314                registration_id,
12315            );
12316        workspace_diagnostics.retain(|d| match &d.diagnostics {
12317            LspPullDiagnostics::Response {
12318                server_id,
12319                registration_id,
12320                ..
12321            } => self.diagnostic_registration_exists(*server_id, registration_id),
12322            LspPullDiagnostics::Default => false,
12323        });
12324        let mut unchanged_buffers = HashMap::default();
12325        let workspace_diagnostics_updates = workspace_diagnostics
12326            .into_iter()
12327            .filter_map(
12328                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12329                    LspPullDiagnostics::Response {
12330                        server_id,
12331                        uri,
12332                        diagnostics,
12333                        registration_id,
12334                    } => Some((
12335                        server_id,
12336                        uri,
12337                        diagnostics,
12338                        workspace_diagnostics.version,
12339                        registration_id,
12340                    )),
12341                    LspPullDiagnostics::Default => None,
12342                },
12343            )
12344            .fold(
12345                HashMap::default(),
12346                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12347                    let (result_id, diagnostics) = match diagnostics {
12348                        PulledDiagnostics::Unchanged { result_id } => {
12349                            unchanged_buffers
12350                                .entry(new_registration_id.clone())
12351                                .or_insert_with(HashSet::default)
12352                                .insert(uri.clone());
12353                            (Some(result_id), Vec::new())
12354                        }
12355                        PulledDiagnostics::Changed {
12356                            result_id,
12357                            diagnostics,
12358                        } => (result_id, diagnostics),
12359                    };
12360                    let disk_based_sources = Cow::Owned(
12361                        self.language_server_adapter_for_id(server_id)
12362                            .as_ref()
12363                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12364                            .unwrap_or(&[])
12365                            .to_vec(),
12366                    );
12367
12368                    let Some(abs_path) = uri.to_file_path().ok() else {
12369                        return acc;
12370                    };
12371                    let Some((worktree, relative_path)) =
12372                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12373                    else {
12374                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12375                        return acc;
12376                    };
12377                    let worktree_id = worktree.read(cx).id();
12378                    let project_path = ProjectPath {
12379                        worktree_id,
12380                        path: relative_path,
12381                    };
12382                    if let Some(local_lsp_store) = self.as_local_mut() {
12383                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12384                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12385                    }
12386                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12387                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12388                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12389                        acc.entry(server_id)
12390                            .or_insert_with(HashMap::default)
12391                            .entry(new_registration_id.clone())
12392                            .or_insert_with(Vec::new)
12393                            .push(DocumentDiagnosticsUpdate {
12394                                server_id,
12395                                diagnostics: lsp::PublishDiagnosticsParams {
12396                                    uri,
12397                                    diagnostics,
12398                                    version,
12399                                },
12400                                result_id: result_id.map(SharedString::new),
12401                                disk_based_sources,
12402                                registration_id: new_registration_id,
12403                            });
12404                    }
12405                    acc
12406                },
12407            );
12408
12409        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12410            for (registration_id, diagnostic_updates) in diagnostic_updates {
12411                self.merge_lsp_diagnostics(
12412                    DiagnosticSourceKind::Pulled,
12413                    diagnostic_updates,
12414                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12415                        DiagnosticSourceKind::Pulled => {
12416                            old_diagnostic.registration_id != registration_id
12417                                || unchanged_buffers
12418                                    .get(&old_diagnostic.registration_id)
12419                                    .is_some_and(|unchanged_buffers| {
12420                                        unchanged_buffers.contains(&document_uri)
12421                                    })
12422                        }
12423                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12424                    },
12425                    cx,
12426                )
12427                .log_err();
12428            }
12429        }
12430    }
12431
12432    fn register_server_capabilities(
12433        &mut self,
12434        server_id: LanguageServerId,
12435        params: lsp::RegistrationParams,
12436        cx: &mut Context<Self>,
12437    ) -> anyhow::Result<()> {
12438        let server = self
12439            .language_server_for_id(server_id)
12440            .with_context(|| format!("no server {server_id} found"))?;
12441        for reg in params.registrations {
12442            match reg.method.as_str() {
12443                "workspace/didChangeWatchedFiles" => {
12444                    if let Some(options) = reg.register_options {
12445                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12446                            let caps = serde_json::from_value(options)?;
12447                            local_lsp_store
12448                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12449                            true
12450                        } else {
12451                            false
12452                        };
12453                        if notify {
12454                            notify_server_capabilities_updated(&server, cx);
12455                        }
12456                    }
12457                }
12458                "workspace/didChangeConfiguration" => {
12459                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12460                }
12461                "workspace/didChangeWorkspaceFolders" => {
12462                    // In this case register options is an empty object, we can ignore it
12463                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12464                        supported: Some(true),
12465                        change_notifications: Some(OneOf::Right(reg.id)),
12466                    };
12467                    server.update_capabilities(|capabilities| {
12468                        capabilities
12469                            .workspace
12470                            .get_or_insert_default()
12471                            .workspace_folders = Some(caps);
12472                    });
12473                    notify_server_capabilities_updated(&server, cx);
12474                }
12475                "workspace/symbol" => {
12476                    let options = parse_register_capabilities(reg)?;
12477                    server.update_capabilities(|capabilities| {
12478                        capabilities.workspace_symbol_provider = Some(options);
12479                    });
12480                    notify_server_capabilities_updated(&server, cx);
12481                }
12482                "workspace/fileOperations" => {
12483                    if let Some(options) = reg.register_options {
12484                        let caps = serde_json::from_value(options)?;
12485                        server.update_capabilities(|capabilities| {
12486                            capabilities
12487                                .workspace
12488                                .get_or_insert_default()
12489                                .file_operations = Some(caps);
12490                        });
12491                        notify_server_capabilities_updated(&server, cx);
12492                    }
12493                }
12494                "workspace/executeCommand" => {
12495                    if let Some(options) = reg.register_options {
12496                        let options = serde_json::from_value(options)?;
12497                        server.update_capabilities(|capabilities| {
12498                            capabilities.execute_command_provider = Some(options);
12499                        });
12500                        notify_server_capabilities_updated(&server, cx);
12501                    }
12502                }
12503                "textDocument/rangeFormatting" => {
12504                    let options = parse_register_capabilities(reg)?;
12505                    server.update_capabilities(|capabilities| {
12506                        capabilities.document_range_formatting_provider = Some(options);
12507                    });
12508                    notify_server_capabilities_updated(&server, cx);
12509                }
12510                "textDocument/onTypeFormatting" => {
12511                    if let Some(options) = reg
12512                        .register_options
12513                        .map(serde_json::from_value)
12514                        .transpose()?
12515                    {
12516                        server.update_capabilities(|capabilities| {
12517                            capabilities.document_on_type_formatting_provider = Some(options);
12518                        });
12519                        notify_server_capabilities_updated(&server, cx);
12520                    }
12521                }
12522                "textDocument/formatting" => {
12523                    let options = parse_register_capabilities(reg)?;
12524                    server.update_capabilities(|capabilities| {
12525                        capabilities.document_formatting_provider = Some(options);
12526                    });
12527                    notify_server_capabilities_updated(&server, cx);
12528                }
12529                "textDocument/rename" => {
12530                    let options = parse_register_capabilities(reg)?;
12531                    server.update_capabilities(|capabilities| {
12532                        capabilities.rename_provider = Some(options);
12533                    });
12534                    notify_server_capabilities_updated(&server, cx);
12535                }
12536                "textDocument/inlayHint" => {
12537                    let options = parse_register_capabilities(reg)?;
12538                    server.update_capabilities(|capabilities| {
12539                        capabilities.inlay_hint_provider = Some(options);
12540                    });
12541                    notify_server_capabilities_updated(&server, cx);
12542                }
12543                "textDocument/documentSymbol" => {
12544                    let options = parse_register_capabilities(reg)?;
12545                    server.update_capabilities(|capabilities| {
12546                        capabilities.document_symbol_provider = Some(options);
12547                    });
12548                    notify_server_capabilities_updated(&server, cx);
12549                }
12550                "textDocument/codeAction" => {
12551                    let options = parse_register_capabilities(reg)?;
12552                    let provider = match options {
12553                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12554                        OneOf::Right(caps) => caps,
12555                    };
12556                    server.update_capabilities(|capabilities| {
12557                        capabilities.code_action_provider = Some(provider);
12558                    });
12559                    notify_server_capabilities_updated(&server, cx);
12560                }
12561                "textDocument/definition" => {
12562                    let options = parse_register_capabilities(reg)?;
12563                    server.update_capabilities(|capabilities| {
12564                        capabilities.definition_provider = Some(options);
12565                    });
12566                    notify_server_capabilities_updated(&server, cx);
12567                }
12568                "textDocument/completion" => {
12569                    if let Some(caps) = reg
12570                        .register_options
12571                        .map(serde_json::from_value::<CompletionOptions>)
12572                        .transpose()?
12573                    {
12574                        server.update_capabilities(|capabilities| {
12575                            capabilities.completion_provider = Some(caps.clone());
12576                        });
12577
12578                        if let Some(local) = self.as_local() {
12579                            let mut buffers_with_language_server = Vec::new();
12580                            for handle in self.buffer_store.read(cx).buffers() {
12581                                let buffer_id = handle.read(cx).remote_id();
12582                                if local
12583                                    .buffers_opened_in_servers
12584                                    .get(&buffer_id)
12585                                    .filter(|s| s.contains(&server_id))
12586                                    .is_some()
12587                                {
12588                                    buffers_with_language_server.push(handle);
12589                                }
12590                            }
12591                            let triggers = caps
12592                                .trigger_characters
12593                                .unwrap_or_default()
12594                                .into_iter()
12595                                .collect::<BTreeSet<_>>();
12596                            for handle in buffers_with_language_server {
12597                                let triggers = triggers.clone();
12598                                let _ = handle.update(cx, move |buffer, cx| {
12599                                    buffer.set_completion_triggers(server_id, triggers, cx);
12600                                });
12601                            }
12602                        }
12603                        notify_server_capabilities_updated(&server, cx);
12604                    }
12605                }
12606                "textDocument/hover" => {
12607                    let options = parse_register_capabilities(reg)?;
12608                    let provider = match options {
12609                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12610                        OneOf::Right(caps) => caps,
12611                    };
12612                    server.update_capabilities(|capabilities| {
12613                        capabilities.hover_provider = Some(provider);
12614                    });
12615                    notify_server_capabilities_updated(&server, cx);
12616                }
12617                "textDocument/signatureHelp" => {
12618                    if let Some(caps) = reg
12619                        .register_options
12620                        .map(serde_json::from_value)
12621                        .transpose()?
12622                    {
12623                        server.update_capabilities(|capabilities| {
12624                            capabilities.signature_help_provider = Some(caps);
12625                        });
12626                        notify_server_capabilities_updated(&server, cx);
12627                    }
12628                }
12629                "textDocument/didChange" => {
12630                    if let Some(sync_kind) = reg
12631                        .register_options
12632                        .and_then(|opts| opts.get("syncKind").cloned())
12633                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12634                        .transpose()?
12635                    {
12636                        server.update_capabilities(|capabilities| {
12637                            let mut sync_options =
12638                                Self::take_text_document_sync_options(capabilities);
12639                            sync_options.change = Some(sync_kind);
12640                            capabilities.text_document_sync =
12641                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12642                        });
12643                        notify_server_capabilities_updated(&server, cx);
12644                    }
12645                }
12646                "textDocument/didSave" => {
12647                    if let Some(include_text) = reg
12648                        .register_options
12649                        .map(|opts| {
12650                            let transpose = opts
12651                                .get("includeText")
12652                                .cloned()
12653                                .map(serde_json::from_value::<Option<bool>>)
12654                                .transpose();
12655                            match transpose {
12656                                Ok(value) => Ok(value.flatten()),
12657                                Err(e) => Err(e),
12658                            }
12659                        })
12660                        .transpose()?
12661                    {
12662                        server.update_capabilities(|capabilities| {
12663                            let mut sync_options =
12664                                Self::take_text_document_sync_options(capabilities);
12665                            sync_options.save =
12666                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12667                                    include_text,
12668                                }));
12669                            capabilities.text_document_sync =
12670                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12671                        });
12672                        notify_server_capabilities_updated(&server, cx);
12673                    }
12674                }
12675                "textDocument/codeLens" => {
12676                    if let Some(caps) = reg
12677                        .register_options
12678                        .map(serde_json::from_value)
12679                        .transpose()?
12680                    {
12681                        server.update_capabilities(|capabilities| {
12682                            capabilities.code_lens_provider = Some(caps);
12683                        });
12684                        notify_server_capabilities_updated(&server, cx);
12685                    }
12686                }
12687                "textDocument/diagnostic" => {
12688                    if let Some(caps) = reg
12689                        .register_options
12690                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12691                        .transpose()?
12692                    {
12693                        let local = self
12694                            .as_local_mut()
12695                            .context("Expected LSP Store to be local")?;
12696                        let state = local
12697                            .language_servers
12698                            .get_mut(&server_id)
12699                            .context("Could not obtain Language Servers state")?;
12700                        local
12701                            .language_server_dynamic_registrations
12702                            .entry(server_id)
12703                            .or_default()
12704                            .diagnostics
12705                            .insert(Some(reg.id.clone()), caps.clone());
12706
12707                        let supports_workspace_diagnostics =
12708                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12709                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12710                                    diagnostic_options.workspace_diagnostics
12711                                }
12712                                DiagnosticServerCapabilities::RegistrationOptions(
12713                                    diagnostic_registration_options,
12714                                ) => {
12715                                    diagnostic_registration_options
12716                                        .diagnostic_options
12717                                        .workspace_diagnostics
12718                                }
12719                            };
12720
12721                        if supports_workspace_diagnostics(&caps) {
12722                            if let LanguageServerState::Running {
12723                                workspace_diagnostics_refresh_tasks,
12724                                ..
12725                            } = state
12726                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12727                                    Some(reg.id.clone()),
12728                                    caps.clone(),
12729                                    server.clone(),
12730                                    cx,
12731                                )
12732                            {
12733                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12734                            }
12735                        }
12736
12737                        server.update_capabilities(|capabilities| {
12738                            capabilities.diagnostic_provider = Some(caps);
12739                        });
12740
12741                        notify_server_capabilities_updated(&server, cx);
12742
12743                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12744                    }
12745                }
12746                "textDocument/documentColor" => {
12747                    let options = parse_register_capabilities(reg)?;
12748                    let provider = match options {
12749                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12750                        OneOf::Right(caps) => caps,
12751                    };
12752                    server.update_capabilities(|capabilities| {
12753                        capabilities.color_provider = Some(provider);
12754                    });
12755                    notify_server_capabilities_updated(&server, cx);
12756                }
12757                "textDocument/foldingRange" => {
12758                    let options = parse_register_capabilities(reg)?;
12759                    let provider = match options {
12760                        OneOf::Left(value) => lsp::FoldingRangeProviderCapability::Simple(value),
12761                        OneOf::Right(caps) => caps,
12762                    };
12763                    server.update_capabilities(|capabilities| {
12764                        capabilities.folding_range_provider = Some(provider);
12765                    });
12766                    notify_server_capabilities_updated(&server, cx);
12767                }
12768                _ => log::warn!("unhandled capability registration: {reg:?}"),
12769            }
12770        }
12771
12772        Ok(())
12773    }
12774
12775    fn unregister_server_capabilities(
12776        &mut self,
12777        server_id: LanguageServerId,
12778        params: lsp::UnregistrationParams,
12779        cx: &mut Context<Self>,
12780    ) -> anyhow::Result<()> {
12781        let server = self
12782            .language_server_for_id(server_id)
12783            .with_context(|| format!("no server {server_id} found"))?;
12784        for unreg in params.unregisterations.iter() {
12785            match unreg.method.as_str() {
12786                "workspace/didChangeWatchedFiles" => {
12787                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12788                        local_lsp_store
12789                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12790                        true
12791                    } else {
12792                        false
12793                    };
12794                    if notify {
12795                        notify_server_capabilities_updated(&server, cx);
12796                    }
12797                }
12798                "workspace/didChangeConfiguration" => {
12799                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12800                }
12801                "workspace/didChangeWorkspaceFolders" => {
12802                    server.update_capabilities(|capabilities| {
12803                        capabilities
12804                            .workspace
12805                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12806                                workspace_folders: None,
12807                                file_operations: None,
12808                            })
12809                            .workspace_folders = None;
12810                    });
12811                    notify_server_capabilities_updated(&server, cx);
12812                }
12813                "workspace/symbol" => {
12814                    server.update_capabilities(|capabilities| {
12815                        capabilities.workspace_symbol_provider = None
12816                    });
12817                    notify_server_capabilities_updated(&server, cx);
12818                }
12819                "workspace/fileOperations" => {
12820                    server.update_capabilities(|capabilities| {
12821                        capabilities
12822                            .workspace
12823                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12824                                workspace_folders: None,
12825                                file_operations: None,
12826                            })
12827                            .file_operations = None;
12828                    });
12829                    notify_server_capabilities_updated(&server, cx);
12830                }
12831                "workspace/executeCommand" => {
12832                    server.update_capabilities(|capabilities| {
12833                        capabilities.execute_command_provider = None;
12834                    });
12835                    notify_server_capabilities_updated(&server, cx);
12836                }
12837                "textDocument/rangeFormatting" => {
12838                    server.update_capabilities(|capabilities| {
12839                        capabilities.document_range_formatting_provider = None
12840                    });
12841                    notify_server_capabilities_updated(&server, cx);
12842                }
12843                "textDocument/onTypeFormatting" => {
12844                    server.update_capabilities(|capabilities| {
12845                        capabilities.document_on_type_formatting_provider = None;
12846                    });
12847                    notify_server_capabilities_updated(&server, cx);
12848                }
12849                "textDocument/formatting" => {
12850                    server.update_capabilities(|capabilities| {
12851                        capabilities.document_formatting_provider = None;
12852                    });
12853                    notify_server_capabilities_updated(&server, cx);
12854                }
12855                "textDocument/rename" => {
12856                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12857                    notify_server_capabilities_updated(&server, cx);
12858                }
12859                "textDocument/codeAction" => {
12860                    server.update_capabilities(|capabilities| {
12861                        capabilities.code_action_provider = None;
12862                    });
12863                    notify_server_capabilities_updated(&server, cx);
12864                }
12865                "textDocument/definition" => {
12866                    server.update_capabilities(|capabilities| {
12867                        capabilities.definition_provider = None;
12868                    });
12869                    notify_server_capabilities_updated(&server, cx);
12870                }
12871                "textDocument/completion" => {
12872                    server.update_capabilities(|capabilities| {
12873                        capabilities.completion_provider = None;
12874                    });
12875                    notify_server_capabilities_updated(&server, cx);
12876                }
12877                "textDocument/hover" => {
12878                    server.update_capabilities(|capabilities| {
12879                        capabilities.hover_provider = None;
12880                    });
12881                    notify_server_capabilities_updated(&server, cx);
12882                }
12883                "textDocument/signatureHelp" => {
12884                    server.update_capabilities(|capabilities| {
12885                        capabilities.signature_help_provider = None;
12886                    });
12887                    notify_server_capabilities_updated(&server, cx);
12888                }
12889                "textDocument/didChange" => {
12890                    server.update_capabilities(|capabilities| {
12891                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12892                        sync_options.change = None;
12893                        capabilities.text_document_sync =
12894                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12895                    });
12896                    notify_server_capabilities_updated(&server, cx);
12897                }
12898                "textDocument/didSave" => {
12899                    server.update_capabilities(|capabilities| {
12900                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12901                        sync_options.save = None;
12902                        capabilities.text_document_sync =
12903                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12904                    });
12905                    notify_server_capabilities_updated(&server, cx);
12906                }
12907                "textDocument/codeLens" => {
12908                    server.update_capabilities(|capabilities| {
12909                        capabilities.code_lens_provider = None;
12910                    });
12911                    notify_server_capabilities_updated(&server, cx);
12912                }
12913                "textDocument/diagnostic" => {
12914                    let local = self
12915                        .as_local_mut()
12916                        .context("Expected LSP Store to be local")?;
12917
12918                    let state = local
12919                        .language_servers
12920                        .get_mut(&server_id)
12921                        .context("Could not obtain Language Servers state")?;
12922                    let registrations = local
12923                        .language_server_dynamic_registrations
12924                        .get_mut(&server_id)
12925                        .with_context(|| {
12926                            format!("Expected dynamic registration to exist for server {server_id}")
12927                        })?;
12928                    registrations.diagnostics
12929                        .remove(&Some(unreg.id.clone()))
12930                        .with_context(|| format!(
12931                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12932                            unreg.id)
12933                        )?;
12934                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12935
12936                    if let LanguageServerState::Running {
12937                        workspace_diagnostics_refresh_tasks,
12938                        ..
12939                    } = state
12940                    {
12941                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12942                    }
12943
12944                    self.clear_unregistered_diagnostics(
12945                        server_id,
12946                        SharedString::from(unreg.id.clone()),
12947                        cx,
12948                    )?;
12949
12950                    if removed_last_diagnostic_provider {
12951                        server.update_capabilities(|capabilities| {
12952                            debug_assert!(capabilities.diagnostic_provider.is_some());
12953                            capabilities.diagnostic_provider = None;
12954                        });
12955                    }
12956
12957                    notify_server_capabilities_updated(&server, cx);
12958                }
12959                "textDocument/documentColor" => {
12960                    server.update_capabilities(|capabilities| {
12961                        capabilities.color_provider = None;
12962                    });
12963                    notify_server_capabilities_updated(&server, cx);
12964                }
12965                "textDocument/foldingRange" => {
12966                    server.update_capabilities(|capabilities| {
12967                        capabilities.folding_range_provider = None;
12968                    });
12969                    notify_server_capabilities_updated(&server, cx);
12970                }
12971                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12972            }
12973        }
12974
12975        Ok(())
12976    }
12977
12978    fn clear_unregistered_diagnostics(
12979        &mut self,
12980        server_id: LanguageServerId,
12981        cleared_registration_id: SharedString,
12982        cx: &mut Context<Self>,
12983    ) -> anyhow::Result<()> {
12984        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12985
12986        self.buffer_store.update(cx, |buffer_store, cx| {
12987            for buffer_handle in buffer_store.buffers() {
12988                let buffer = buffer_handle.read(cx);
12989                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12990                let Some(abs_path) = abs_path else {
12991                    continue;
12992                };
12993                affected_abs_paths.insert(abs_path);
12994            }
12995        });
12996
12997        let local = self.as_local().context("Expected LSP Store to be local")?;
12998        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12999            let Some(worktree) = self
13000                .worktree_store
13001                .read(cx)
13002                .worktree_for_id(*worktree_id, cx)
13003            else {
13004                continue;
13005            };
13006
13007            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
13008                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
13009                    let has_matching_registration =
13010                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
13011                            entry.diagnostic.registration_id.as_ref()
13012                                == Some(&cleared_registration_id)
13013                        });
13014                    if has_matching_registration {
13015                        let abs_path = worktree.read(cx).absolutize(rel_path);
13016                        affected_abs_paths.insert(abs_path);
13017                    }
13018                }
13019            }
13020        }
13021
13022        if affected_abs_paths.is_empty() {
13023            return Ok(());
13024        }
13025
13026        // Send a fake diagnostic update which clears the state for the registration ID
13027        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
13028            affected_abs_paths
13029                .into_iter()
13030                .map(|abs_path| DocumentDiagnosticsUpdate {
13031                    diagnostics: DocumentDiagnostics {
13032                        diagnostics: Vec::new(),
13033                        document_abs_path: abs_path,
13034                        version: None,
13035                    },
13036                    result_id: None,
13037                    registration_id: Some(cleared_registration_id.clone()),
13038                    server_id,
13039                    disk_based_sources: Cow::Borrowed(&[]),
13040                })
13041                .collect();
13042
13043        let merge_registration_id = cleared_registration_id.clone();
13044        self.merge_diagnostic_entries(
13045            clears,
13046            move |_, diagnostic, _| {
13047                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
13048                    diagnostic.registration_id != Some(merge_registration_id.clone())
13049                } else {
13050                    true
13051                }
13052            },
13053            cx,
13054        )?;
13055
13056        Ok(())
13057    }
13058
13059    async fn deduplicate_range_based_lsp_requests<T>(
13060        lsp_store: &Entity<Self>,
13061        server_id: Option<LanguageServerId>,
13062        lsp_request_id: LspRequestId,
13063        proto_request: &T::ProtoRequest,
13064        range: Range<Anchor>,
13065        cx: &mut AsyncApp,
13066    ) -> Result<()>
13067    where
13068        T: LspCommand,
13069        T::ProtoRequest: proto::LspRequestMessage,
13070    {
13071        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13072        let version = deserialize_version(proto_request.buffer_version());
13073        let buffer = lsp_store.update(cx, |this, cx| {
13074            this.buffer_store.read(cx).get_existing(buffer_id)
13075        })?;
13076        buffer
13077            .update(cx, |buffer, _| buffer.wait_for_version(version))
13078            .await?;
13079        lsp_store.update(cx, |lsp_store, cx| {
13080            let buffer_snapshot = buffer.read(cx).snapshot();
13081            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13082            let chunks_queried_for = lsp_data
13083                .inlay_hints
13084                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
13085                .collect::<Vec<_>>();
13086            match chunks_queried_for.as_slice() {
13087                &[chunk] => {
13088                    let key = LspKey {
13089                        request_type: TypeId::of::<T>(),
13090                        server_queried: server_id,
13091                    };
13092                    let previous_request = lsp_data
13093                        .chunk_lsp_requests
13094                        .entry(key)
13095                        .or_default()
13096                        .insert(chunk, lsp_request_id);
13097                    if let Some((previous_request, running_requests)) =
13098                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13099                    {
13100                        running_requests.remove(&previous_request);
13101                    }
13102                }
13103                _ambiguous_chunks => {
13104                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13105                    // there, a buffer version-based check will be performed and outdated requests discarded.
13106                }
13107            }
13108            anyhow::Ok(())
13109        })?;
13110
13111        Ok(())
13112    }
13113
13114    async fn query_lsp_locally<T>(
13115        lsp_store: Entity<Self>,
13116        for_server_id: Option<LanguageServerId>,
13117        sender_id: proto::PeerId,
13118        lsp_request_id: LspRequestId,
13119        proto_request: T::ProtoRequest,
13120        position: Option<Anchor>,
13121        cx: &mut AsyncApp,
13122    ) -> Result<()>
13123    where
13124        T: LspCommand + Clone,
13125        T::ProtoRequest: proto::LspRequestMessage,
13126        <T::ProtoRequest as proto::RequestMessage>::Response:
13127            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13128    {
13129        let (buffer_version, buffer) =
13130            Self::wait_for_buffer_version::<T>(&lsp_store, &proto_request, cx).await?;
13131        let request =
13132            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13133        let key = LspKey {
13134            request_type: TypeId::of::<T>(),
13135            server_queried: for_server_id,
13136        };
13137        lsp_store.update(cx, |lsp_store, cx| {
13138            let request_task = match for_server_id {
13139                Some(server_id) => {
13140                    let server_task = lsp_store.request_lsp(
13141                        buffer.clone(),
13142                        LanguageServerToQuery::Other(server_id),
13143                        request.clone(),
13144                        cx,
13145                    );
13146                    cx.background_spawn(async move {
13147                        let mut responses = Vec::new();
13148                        match server_task.await {
13149                            Ok(response) => responses.push((server_id, response)),
13150                            // rust-analyzer likes to error with this when its still loading up
13151                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13152                            Err(e) => log::error!(
13153                                "Error handling response for request {request:?}: {e:#}"
13154                            ),
13155                        }
13156                        responses
13157                    })
13158                }
13159                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13160            };
13161            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13162            if T::ProtoRequest::stop_previous_requests() {
13163                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13164                    lsp_requests.clear();
13165                }
13166            }
13167            lsp_data.lsp_requests.entry(key).or_default().insert(
13168                lsp_request_id,
13169                cx.spawn(async move |lsp_store, cx| {
13170                    let response = request_task.await;
13171                    lsp_store
13172                        .update(cx, |lsp_store, cx| {
13173                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13174                            {
13175                                let response = response
13176                                    .into_iter()
13177                                    .map(|(server_id, response)| {
13178                                        (
13179                                            server_id.to_proto(),
13180                                            T::response_to_proto(
13181                                                response,
13182                                                lsp_store,
13183                                                sender_id,
13184                                                &buffer_version,
13185                                                cx,
13186                                            )
13187                                            .into(),
13188                                        )
13189                                    })
13190                                    .collect::<HashMap<_, _>>();
13191                                match client.send_lsp_response::<T::ProtoRequest>(
13192                                    project_id,
13193                                    lsp_request_id,
13194                                    response,
13195                                ) {
13196                                    Ok(()) => {}
13197                                    Err(e) => {
13198                                        log::error!("Failed to send LSP response: {e:#}",)
13199                                    }
13200                                }
13201                            }
13202                        })
13203                        .ok();
13204                }),
13205            );
13206        });
13207        Ok(())
13208    }
13209
13210    async fn wait_for_buffer_version<T>(
13211        lsp_store: &Entity<Self>,
13212        proto_request: &T::ProtoRequest,
13213        cx: &mut AsyncApp,
13214    ) -> Result<(Global, Entity<Buffer>)>
13215    where
13216        T: LspCommand,
13217        T::ProtoRequest: proto::LspRequestMessage,
13218    {
13219        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13220        let version = deserialize_version(proto_request.buffer_version());
13221        let buffer = lsp_store.update(cx, |this, cx| {
13222            this.buffer_store.read(cx).get_existing(buffer_id)
13223        })?;
13224        buffer
13225            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13226            .await?;
13227        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13228        Ok((buffer_version, buffer))
13229    }
13230
13231    fn take_text_document_sync_options(
13232        capabilities: &mut lsp::ServerCapabilities,
13233    ) -> lsp::TextDocumentSyncOptions {
13234        match capabilities.text_document_sync.take() {
13235            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13236            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13237                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13238                sync_options.change = Some(sync_kind);
13239                sync_options
13240            }
13241            None => lsp::TextDocumentSyncOptions::default(),
13242        }
13243    }
13244
13245    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13246        self.downstream_client.clone()
13247    }
13248
13249    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13250        self.worktree_store.clone()
13251    }
13252
13253    /// Gets what's stored in the LSP data for the given buffer.
13254    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13255        self.lsp_data.get_mut(&buffer_id)
13256    }
13257
13258    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13259    /// new [`BufferLspData`] will be created to replace the previous state.
13260    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13261        let (buffer_id, buffer_version) =
13262            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13263        let lsp_data = self
13264            .lsp_data
13265            .entry(buffer_id)
13266            .or_insert_with(|| BufferLspData::new(buffer, cx));
13267        if buffer_version.changed_since(&lsp_data.buffer_version) {
13268            // To send delta requests for semantic tokens, the previous tokens
13269            // need to be kept between buffer changes.
13270            let semantic_tokens = lsp_data.semantic_tokens.take();
13271            *lsp_data = BufferLspData::new(buffer, cx);
13272            lsp_data.semantic_tokens = semantic_tokens;
13273        }
13274        lsp_data
13275    }
13276}
13277
13278// Registration with registerOptions as null, should fallback to true.
13279// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13280fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13281    reg: lsp::Registration,
13282) -> Result<OneOf<bool, T>> {
13283    Ok(match reg.register_options {
13284        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13285        None => OneOf::Left(true),
13286    })
13287}
13288
13289fn subscribe_to_binary_statuses(
13290    languages: &Arc<LanguageRegistry>,
13291    cx: &mut Context<'_, LspStore>,
13292) -> Task<()> {
13293    let mut server_statuses = languages.language_server_binary_statuses();
13294    cx.spawn(async move |lsp_store, cx| {
13295        while let Some((server_name, binary_status)) = server_statuses.next().await {
13296            if lsp_store
13297                .update(cx, |_, cx| {
13298                    let mut message = None;
13299                    let binary_status = match binary_status {
13300                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13301                        BinaryStatus::CheckingForUpdate => {
13302                            proto::ServerBinaryStatus::CheckingForUpdate
13303                        }
13304                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13305                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13306                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13307                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13308                        BinaryStatus::Failed { error } => {
13309                            message = Some(error);
13310                            proto::ServerBinaryStatus::Failed
13311                        }
13312                    };
13313                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13314                        // Binary updates are about the binary that might not have any language server id at that point.
13315                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13316                        language_server_id: LanguageServerId(0),
13317                        name: Some(server_name),
13318                        message: proto::update_language_server::Variant::StatusUpdate(
13319                            proto::StatusUpdate {
13320                                message,
13321                                status: Some(proto::status_update::Status::Binary(
13322                                    binary_status as i32,
13323                                )),
13324                            },
13325                        ),
13326                    });
13327                })
13328                .is_err()
13329            {
13330                break;
13331            }
13332        }
13333    })
13334}
13335
13336fn lsp_workspace_diagnostics_refresh(
13337    registration_id: Option<String>,
13338    options: DiagnosticServerCapabilities,
13339    server: Arc<LanguageServer>,
13340    cx: &mut Context<'_, LspStore>,
13341) -> Option<WorkspaceRefreshTask> {
13342    let identifier = workspace_diagnostic_identifier(&options)?;
13343    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13344
13345    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13346    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13347    refresh_tx.try_send(()).ok();
13348
13349    let request_timeout = ProjectSettings::get_global(cx)
13350        .global_lsp_settings
13351        .get_request_timeout();
13352
13353    // 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.
13354    // This allows users to increase the duration if need be
13355    let timeout = if request_timeout != Duration::ZERO {
13356        request_timeout.max(DEFAULT_LSP_REQUEST_TIMEOUT)
13357    } else {
13358        request_timeout
13359    };
13360
13361    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13362        let mut attempts = 0;
13363        let max_attempts = 50;
13364        let mut requests = 0;
13365
13366        loop {
13367            let Some(()) = refresh_rx.recv().await else {
13368                return;
13369            };
13370
13371            'request: loop {
13372                requests += 1;
13373                if attempts > max_attempts {
13374                    log::error!(
13375                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13376                    );
13377                    return;
13378                }
13379                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13380                cx.background_executor()
13381                    .timer(Duration::from_millis(backoff_millis))
13382                    .await;
13383                attempts += 1;
13384
13385                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13386                    lsp_store
13387                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13388                        .into_iter()
13389                        .filter_map(|(abs_path, result_id)| {
13390                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13391                            Some(lsp::PreviousResultId {
13392                                uri,
13393                                value: result_id.to_string(),
13394                            })
13395                        })
13396                        .collect()
13397                }) else {
13398                    return;
13399                };
13400
13401                let token = if let Some(registration_id) = &registration_id {
13402                    format!(
13403                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13404                        server.server_id(),
13405                    )
13406                } else {
13407                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13408                };
13409
13410                progress_rx.try_recv().ok();
13411                let timer = server.request_timer(timeout).fuse();
13412                let progress = pin!(progress_rx.recv().fuse());
13413                let response_result = server
13414                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13415                        lsp::WorkspaceDiagnosticParams {
13416                            previous_result_ids,
13417                            identifier: identifier.clone(),
13418                            work_done_progress_params: Default::default(),
13419                            partial_result_params: lsp::PartialResultParams {
13420                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13421                            },
13422                        },
13423                        select(timer, progress).then(|either| match either {
13424                            Either::Left((message, ..)) => ready(message).left_future(),
13425                            Either::Right(..) => pending::<String>().right_future(),
13426                        }),
13427                    )
13428                    .await;
13429
13430                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13431                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13432                match response_result {
13433                    ConnectionResult::Timeout => {
13434                        log::error!("Timeout during workspace diagnostics pull");
13435                        continue 'request;
13436                    }
13437                    ConnectionResult::ConnectionReset => {
13438                        log::error!("Server closed a workspace diagnostics pull request");
13439                        continue 'request;
13440                    }
13441                    ConnectionResult::Result(Err(e)) => {
13442                        log::error!("Error during workspace diagnostics pull: {e:#}");
13443                        break 'request;
13444                    }
13445                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13446                        attempts = 0;
13447                        if lsp_store
13448                            .update(cx, |lsp_store, cx| {
13449                                lsp_store.apply_workspace_diagnostic_report(
13450                                    server.server_id(),
13451                                    pulled_diagnostics,
13452                                    registration_id_shared.clone(),
13453                                    cx,
13454                                )
13455                            })
13456                            .is_err()
13457                        {
13458                            return;
13459                        }
13460                        break 'request;
13461                    }
13462                }
13463            }
13464        }
13465    });
13466
13467    Some(WorkspaceRefreshTask {
13468        refresh_tx,
13469        progress_tx,
13470        task: workspace_query_language_server,
13471    })
13472}
13473
13474fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<SharedString> {
13475    match &options {
13476        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => diagnostic_options
13477            .identifier
13478            .as_deref()
13479            .map(SharedString::new),
13480        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13481            let diagnostic_options = &registration_options.diagnostic_options;
13482            diagnostic_options
13483                .identifier
13484                .as_deref()
13485                .map(SharedString::new)
13486        }
13487    }
13488}
13489
13490fn workspace_diagnostic_identifier(
13491    options: &DiagnosticServerCapabilities,
13492) -> Option<Option<String>> {
13493    match &options {
13494        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13495            if !diagnostic_options.workspace_diagnostics {
13496                return None;
13497            }
13498            Some(diagnostic_options.identifier.clone())
13499        }
13500        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13501            let diagnostic_options = &registration_options.diagnostic_options;
13502            if !diagnostic_options.workspace_diagnostics {
13503                return None;
13504            }
13505            Some(diagnostic_options.identifier.clone())
13506        }
13507    }
13508}
13509
13510fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13511    let CompletionSource::BufferWord {
13512        word_range,
13513        resolved,
13514    } = &mut completion.source
13515    else {
13516        return;
13517    };
13518    if *resolved {
13519        return;
13520    }
13521
13522    if completion.new_text
13523        != snapshot
13524            .text_for_range(word_range.clone())
13525            .collect::<String>()
13526    {
13527        return;
13528    }
13529
13530    let mut offset = 0;
13531    for chunk in snapshot.chunks(
13532        word_range.clone(),
13533        LanguageAwareStyling {
13534            tree_sitter: true,
13535            diagnostics: true,
13536        },
13537    ) {
13538        let end_offset = offset + chunk.text.len();
13539        if let Some(highlight_id) = chunk.syntax_highlight_id {
13540            completion
13541                .label
13542                .runs
13543                .push((offset..end_offset, highlight_id));
13544        }
13545        offset = end_offset;
13546    }
13547    *resolved = true;
13548}
13549
13550impl EventEmitter<LspStoreEvent> for LspStore {}
13551
13552fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13553    hover
13554        .contents
13555        .retain(|hover_block| !hover_block.text.trim().is_empty());
13556    if hover.contents.is_empty() {
13557        None
13558    } else {
13559        Some(hover)
13560    }
13561}
13562
13563async fn populate_labels_for_completions(
13564    new_completions: Vec<CoreCompletion>,
13565    language: Option<Arc<Language>>,
13566    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13567) -> Vec<Completion> {
13568    let lsp_completions = new_completions
13569        .iter()
13570        .filter_map(|new_completion| {
13571            new_completion
13572                .source
13573                .lsp_completion(true)
13574                .map(|lsp_completion| lsp_completion.into_owned())
13575        })
13576        .collect::<Vec<_>>();
13577
13578    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13579        lsp_adapter
13580            .labels_for_completions(&lsp_completions, language)
13581            .await
13582            .log_err()
13583            .unwrap_or_default()
13584    } else {
13585        Vec::new()
13586    }
13587    .into_iter()
13588    .fuse();
13589
13590    let mut completions = Vec::new();
13591    for completion in new_completions {
13592        match completion.source.lsp_completion(true) {
13593            Some(lsp_completion) => {
13594                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13595
13596                let mut label = labels.next().flatten().unwrap_or_else(|| {
13597                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13598                });
13599                ensure_uniform_list_compatible_label(&mut label);
13600                completions.push(Completion {
13601                    label,
13602                    documentation,
13603                    replace_range: completion.replace_range,
13604                    new_text: completion.new_text,
13605                    insert_text_mode: lsp_completion.insert_text_mode,
13606                    source: completion.source,
13607                    icon_path: None,
13608                    confirm: None,
13609                    match_start: None,
13610                    snippet_deduplication_key: None,
13611                });
13612            }
13613            None => {
13614                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13615                ensure_uniform_list_compatible_label(&mut label);
13616                completions.push(Completion {
13617                    label,
13618                    documentation: None,
13619                    replace_range: completion.replace_range,
13620                    new_text: completion.new_text,
13621                    source: completion.source,
13622                    insert_text_mode: None,
13623                    icon_path: None,
13624                    confirm: None,
13625                    match_start: None,
13626                    snippet_deduplication_key: None,
13627                });
13628            }
13629        }
13630    }
13631    completions
13632}
13633
13634#[derive(Debug)]
13635pub enum LanguageServerToQuery {
13636    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13637    FirstCapable,
13638    /// Query a specific language server.
13639    Other(LanguageServerId),
13640}
13641
13642#[derive(Default)]
13643struct RenamePathsWatchedForServer {
13644    did_rename: Vec<RenameActionPredicate>,
13645    will_rename: Vec<RenameActionPredicate>,
13646}
13647
13648impl RenamePathsWatchedForServer {
13649    fn with_did_rename_patterns(
13650        mut self,
13651        did_rename: Option<&FileOperationRegistrationOptions>,
13652    ) -> Self {
13653        if let Some(did_rename) = did_rename {
13654            self.did_rename = did_rename
13655                .filters
13656                .iter()
13657                .filter_map(|filter| filter.try_into().log_err())
13658                .collect();
13659        }
13660        self
13661    }
13662    fn with_will_rename_patterns(
13663        mut self,
13664        will_rename: Option<&FileOperationRegistrationOptions>,
13665    ) -> Self {
13666        if let Some(will_rename) = will_rename {
13667            self.will_rename = will_rename
13668                .filters
13669                .iter()
13670                .filter_map(|filter| filter.try_into().log_err())
13671                .collect();
13672        }
13673        self
13674    }
13675
13676    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13677        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13678    }
13679    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13680        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13681    }
13682}
13683
13684impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13685    type Error = globset::Error;
13686    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13687        Ok(Self {
13688            kind: ops.pattern.matches.clone(),
13689            glob: GlobBuilder::new(&ops.pattern.glob)
13690                .case_insensitive(
13691                    ops.pattern
13692                        .options
13693                        .as_ref()
13694                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13695                )
13696                .build()?
13697                .compile_matcher(),
13698        })
13699    }
13700}
13701struct RenameActionPredicate {
13702    glob: GlobMatcher,
13703    kind: Option<FileOperationPatternKind>,
13704}
13705
13706impl RenameActionPredicate {
13707    // Returns true if language server should be notified
13708    fn eval(&self, path: &str, is_dir: bool) -> bool {
13709        self.kind.as_ref().is_none_or(|kind| {
13710            let expected_kind = if is_dir {
13711                FileOperationPatternKind::Folder
13712            } else {
13713                FileOperationPatternKind::File
13714            };
13715            kind == &expected_kind
13716        }) && self.glob.is_match(path)
13717    }
13718}
13719
13720#[derive(Default)]
13721struct LanguageServerWatchedPaths {
13722    worktree_paths: HashMap<WorktreeId, GlobSet>,
13723    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13724}
13725
13726#[derive(Default)]
13727struct LanguageServerWatchedPathsBuilder {
13728    worktree_paths: HashMap<WorktreeId, GlobSet>,
13729    abs_paths: HashMap<Arc<Path>, GlobSet>,
13730}
13731
13732impl LanguageServerWatchedPathsBuilder {
13733    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13734        self.worktree_paths.insert(worktree_id, glob_set);
13735    }
13736    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13737        self.abs_paths.insert(path, glob_set);
13738    }
13739    fn build(
13740        self,
13741        fs: Arc<dyn Fs>,
13742        language_server_id: LanguageServerId,
13743        cx: &mut Context<LspStore>,
13744    ) -> LanguageServerWatchedPaths {
13745        let lsp_store = cx.weak_entity();
13746
13747        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13748        let abs_paths = self
13749            .abs_paths
13750            .into_iter()
13751            .map(|(abs_path, globset)| {
13752                let task = cx.spawn({
13753                    let abs_path = abs_path.clone();
13754                    let fs = fs.clone();
13755
13756                    let lsp_store = lsp_store.clone();
13757                    async move |_, cx| {
13758                        maybe!(async move {
13759                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13760                            while let Some(update) = push_updates.0.next().await {
13761                                let action = lsp_store
13762                                    .update(cx, |this, _| {
13763                                        let Some(local) = this.as_local() else {
13764                                            return ControlFlow::Break(());
13765                                        };
13766                                        let Some(watcher) = local
13767                                            .language_server_watched_paths
13768                                            .get(&language_server_id)
13769                                        else {
13770                                            return ControlFlow::Break(());
13771                                        };
13772                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13773                                            "Watched abs path is not registered with a watcher",
13774                                        );
13775                                        let matching_entries = update
13776                                            .into_iter()
13777                                            .filter(|event| globs.is_match(&event.path))
13778                                            .collect::<Vec<_>>();
13779                                        this.lsp_notify_abs_paths_changed(
13780                                            language_server_id,
13781                                            matching_entries,
13782                                        );
13783                                        ControlFlow::Continue(())
13784                                    })
13785                                    .ok()?;
13786
13787                                if action.is_break() {
13788                                    break;
13789                                }
13790                            }
13791                            Some(())
13792                        })
13793                        .await;
13794                    }
13795                });
13796                (abs_path, (globset, task))
13797            })
13798            .collect();
13799        LanguageServerWatchedPaths {
13800            worktree_paths: self.worktree_paths,
13801            abs_paths,
13802        }
13803    }
13804}
13805
13806struct LspBufferSnapshot {
13807    version: i32,
13808    snapshot: TextBufferSnapshot,
13809}
13810
13811/// A prompt requested by LSP server.
13812#[derive(Clone, Debug)]
13813pub struct LanguageServerPromptRequest {
13814    pub id: usize,
13815    pub level: PromptLevel,
13816    pub message: String,
13817    pub actions: Vec<MessageActionItem>,
13818    pub lsp_name: String,
13819    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13820}
13821
13822impl LanguageServerPromptRequest {
13823    pub fn new(
13824        level: PromptLevel,
13825        message: String,
13826        actions: Vec<MessageActionItem>,
13827        lsp_name: String,
13828        response_channel: smol::channel::Sender<MessageActionItem>,
13829    ) -> Self {
13830        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13831        LanguageServerPromptRequest {
13832            id,
13833            level,
13834            message,
13835            actions,
13836            lsp_name,
13837            response_channel,
13838        }
13839    }
13840    pub async fn respond(self, index: usize) -> Option<()> {
13841        if let Some(response) = self.actions.into_iter().nth(index) {
13842            self.response_channel.send(response).await.ok()
13843        } else {
13844            None
13845        }
13846    }
13847
13848    #[cfg(any(test, feature = "test-support"))]
13849    pub fn test(
13850        level: PromptLevel,
13851        message: String,
13852        actions: Vec<MessageActionItem>,
13853        lsp_name: String,
13854    ) -> Self {
13855        let (tx, _rx) = smol::channel::unbounded();
13856        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13857    }
13858}
13859impl PartialEq for LanguageServerPromptRequest {
13860    fn eq(&self, other: &Self) -> bool {
13861        self.message == other.message && self.actions == other.actions
13862    }
13863}
13864
13865#[derive(Clone, Debug, PartialEq)]
13866pub enum LanguageServerLogType {
13867    Log(MessageType),
13868    Trace { verbose_info: Option<String> },
13869    Rpc { received: bool },
13870}
13871
13872impl LanguageServerLogType {
13873    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13874        match self {
13875            Self::Log(log_type) => {
13876                use proto::log_message::LogLevel;
13877                let level = match *log_type {
13878                    MessageType::ERROR => LogLevel::Error,
13879                    MessageType::WARNING => LogLevel::Warning,
13880                    MessageType::INFO => LogLevel::Info,
13881                    MessageType::LOG => LogLevel::Log,
13882                    other => {
13883                        log::warn!("Unknown lsp log message type: {other:?}");
13884                        LogLevel::Log
13885                    }
13886                };
13887                proto::language_server_log::LogType::Log(proto::LogMessage {
13888                    level: level as i32,
13889                })
13890            }
13891            Self::Trace { verbose_info } => {
13892                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13893                    verbose_info: verbose_info.to_owned(),
13894                })
13895            }
13896            Self::Rpc { received } => {
13897                let kind = if *received {
13898                    proto::rpc_message::Kind::Received
13899                } else {
13900                    proto::rpc_message::Kind::Sent
13901                };
13902                let kind = kind as i32;
13903                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13904            }
13905        }
13906    }
13907
13908    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13909        use proto::log_message::LogLevel;
13910        use proto::rpc_message;
13911        match log_type {
13912            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13913                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13914                    LogLevel::Error => MessageType::ERROR,
13915                    LogLevel::Warning => MessageType::WARNING,
13916                    LogLevel::Info => MessageType::INFO,
13917                    LogLevel::Log => MessageType::LOG,
13918                },
13919            ),
13920            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13921                verbose_info: trace_message.verbose_info,
13922            },
13923            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13924                received: match rpc_message::Kind::from_i32(message.kind)
13925                    .unwrap_or(rpc_message::Kind::Received)
13926                {
13927                    rpc_message::Kind::Received => true,
13928                    rpc_message::Kind::Sent => false,
13929                },
13930            },
13931        }
13932    }
13933}
13934
13935pub struct WorkspaceRefreshTask {
13936    refresh_tx: mpsc::Sender<()>,
13937    progress_tx: mpsc::Sender<()>,
13938    #[allow(dead_code)]
13939    task: Task<()>,
13940}
13941
13942pub enum LanguageServerState {
13943    Starting {
13944        startup: Task<Option<Arc<LanguageServer>>>,
13945        /// List of language servers that will be added to the workspace once it's initialization completes.
13946        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13947    },
13948
13949    Running {
13950        adapter: Arc<CachedLspAdapter>,
13951        server: Arc<LanguageServer>,
13952        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13953        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13954    },
13955}
13956
13957impl LanguageServerState {
13958    fn add_workspace_folder(&self, uri: Uri) {
13959        match self {
13960            LanguageServerState::Starting {
13961                pending_workspace_folders,
13962                ..
13963            } => {
13964                pending_workspace_folders.lock().insert(uri);
13965            }
13966            LanguageServerState::Running { server, .. } => {
13967                server.add_workspace_folder(uri);
13968            }
13969        }
13970    }
13971    fn _remove_workspace_folder(&self, uri: Uri) {
13972        match self {
13973            LanguageServerState::Starting {
13974                pending_workspace_folders,
13975                ..
13976            } => {
13977                pending_workspace_folders.lock().remove(&uri);
13978            }
13979            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13980        }
13981    }
13982}
13983
13984impl std::fmt::Debug for LanguageServerState {
13985    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13986        match self {
13987            LanguageServerState::Starting { .. } => {
13988                f.debug_struct("LanguageServerState::Starting").finish()
13989            }
13990            LanguageServerState::Running { .. } => {
13991                f.debug_struct("LanguageServerState::Running").finish()
13992            }
13993        }
13994    }
13995}
13996
13997#[derive(Clone, Debug, Serialize)]
13998pub struct LanguageServerProgress {
13999    pub is_disk_based_diagnostics_progress: bool,
14000    pub is_cancellable: bool,
14001    pub title: Option<String>,
14002    pub message: Option<String>,
14003    pub percentage: Option<usize>,
14004    #[serde(skip_serializing)]
14005    pub last_update_at: Instant,
14006}
14007
14008#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
14009pub struct DiagnosticSummary {
14010    pub error_count: usize,
14011    pub warning_count: usize,
14012}
14013
14014impl DiagnosticSummary {
14015    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
14016        let mut this = Self {
14017            error_count: 0,
14018            warning_count: 0,
14019        };
14020
14021        for entry in diagnostics {
14022            if entry.diagnostic.is_primary {
14023                match entry.diagnostic.severity {
14024                    DiagnosticSeverity::ERROR => this.error_count += 1,
14025                    DiagnosticSeverity::WARNING => this.warning_count += 1,
14026                    _ => {}
14027                }
14028            }
14029        }
14030
14031        this
14032    }
14033
14034    pub fn is_empty(&self) -> bool {
14035        self.error_count == 0 && self.warning_count == 0
14036    }
14037
14038    pub fn to_proto(
14039        self,
14040        language_server_id: LanguageServerId,
14041        path: &RelPath,
14042    ) -> proto::DiagnosticSummary {
14043        proto::DiagnosticSummary {
14044            path: path.to_proto(),
14045            language_server_id: language_server_id.0 as u64,
14046            error_count: self.error_count as u32,
14047            warning_count: self.warning_count as u32,
14048        }
14049    }
14050}
14051
14052#[derive(Clone, Debug)]
14053pub enum CompletionDocumentation {
14054    /// There is no documentation for this completion.
14055    Undocumented,
14056    /// A single line of documentation.
14057    SingleLine(SharedString),
14058    /// Multiple lines of plain text documentation.
14059    MultiLinePlainText(SharedString),
14060    /// Markdown documentation.
14061    MultiLineMarkdown(SharedString),
14062    /// Both single line and multiple lines of plain text documentation.
14063    SingleLineAndMultiLinePlainText {
14064        single_line: SharedString,
14065        plain_text: Option<SharedString>,
14066    },
14067}
14068
14069impl CompletionDocumentation {
14070    #[cfg(any(test, feature = "test-support"))]
14071    pub fn text(&self) -> SharedString {
14072        match self {
14073            CompletionDocumentation::Undocumented => "".into(),
14074            CompletionDocumentation::SingleLine(s) => s.clone(),
14075            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
14076            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
14077            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
14078                single_line.clone()
14079            }
14080        }
14081    }
14082}
14083
14084impl From<lsp::Documentation> for CompletionDocumentation {
14085    fn from(docs: lsp::Documentation) -> Self {
14086        match docs {
14087            lsp::Documentation::String(text) => {
14088                if text.lines().count() <= 1 {
14089                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
14090                } else {
14091                    CompletionDocumentation::MultiLinePlainText(text.into())
14092                }
14093            }
14094
14095            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
14096                lsp::MarkupKind::PlainText => {
14097                    if value.lines().count() <= 1 {
14098                        CompletionDocumentation::SingleLine(value.into())
14099                    } else {
14100                        CompletionDocumentation::MultiLinePlainText(value.into())
14101                    }
14102                }
14103
14104                lsp::MarkupKind::Markdown => {
14105                    CompletionDocumentation::MultiLineMarkdown(value.into())
14106                }
14107            },
14108        }
14109    }
14110}
14111
14112pub enum ResolvedHint {
14113    Resolved(InlayHint),
14114    Resolving(Shared<Task<()>>),
14115}
14116
14117pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
14118    glob.components()
14119        .take_while(|component| match component {
14120            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
14121            _ => true,
14122        })
14123        .collect()
14124}
14125
14126pub struct SshLspAdapter {
14127    name: LanguageServerName,
14128    binary: LanguageServerBinary,
14129    initialization_options: Option<String>,
14130    code_action_kinds: Option<Vec<CodeActionKind>>,
14131}
14132
14133impl SshLspAdapter {
14134    pub fn new(
14135        name: LanguageServerName,
14136        binary: LanguageServerBinary,
14137        initialization_options: Option<String>,
14138        code_action_kinds: Option<String>,
14139    ) -> Self {
14140        Self {
14141            name,
14142            binary,
14143            initialization_options,
14144            code_action_kinds: code_action_kinds
14145                .as_ref()
14146                .and_then(|c| serde_json::from_str(c).ok()),
14147        }
14148    }
14149}
14150
14151impl LspInstaller for SshLspAdapter {
14152    type BinaryVersion = ();
14153    async fn check_if_user_installed(
14154        &self,
14155        _: &dyn LspAdapterDelegate,
14156        _: Option<Toolchain>,
14157        _: &AsyncApp,
14158    ) -> Option<LanguageServerBinary> {
14159        Some(self.binary.clone())
14160    }
14161
14162    async fn cached_server_binary(
14163        &self,
14164        _: PathBuf,
14165        _: &dyn LspAdapterDelegate,
14166    ) -> Option<LanguageServerBinary> {
14167        None
14168    }
14169
14170    async fn fetch_latest_server_version(
14171        &self,
14172        _: &dyn LspAdapterDelegate,
14173        _: bool,
14174        _: &mut AsyncApp,
14175    ) -> Result<()> {
14176        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14177    }
14178
14179    async fn fetch_server_binary(
14180        &self,
14181        _: (),
14182        _: PathBuf,
14183        _: &dyn LspAdapterDelegate,
14184    ) -> Result<LanguageServerBinary> {
14185        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14186    }
14187}
14188
14189#[async_trait(?Send)]
14190impl LspAdapter for SshLspAdapter {
14191    fn name(&self) -> LanguageServerName {
14192        self.name.clone()
14193    }
14194
14195    async fn initialization_options(
14196        self: Arc<Self>,
14197        _: &Arc<dyn LspAdapterDelegate>,
14198        _: &mut AsyncApp,
14199    ) -> Result<Option<serde_json::Value>> {
14200        let Some(options) = &self.initialization_options else {
14201            return Ok(None);
14202        };
14203        let result = serde_json::from_str(options)?;
14204        Ok(result)
14205    }
14206
14207    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14208        self.code_action_kinds.clone()
14209    }
14210}
14211
14212pub fn language_server_settings<'a>(
14213    delegate: &'a dyn LspAdapterDelegate,
14214    language: &LanguageServerName,
14215    cx: &'a App,
14216) -> Option<&'a LspSettings> {
14217    language_server_settings_for(
14218        SettingsLocation {
14219            worktree_id: delegate.worktree_id(),
14220            path: RelPath::empty(),
14221        },
14222        language,
14223        cx,
14224    )
14225}
14226
14227pub fn language_server_settings_for<'a>(
14228    location: SettingsLocation<'a>,
14229    language: &LanguageServerName,
14230    cx: &'a App,
14231) -> Option<&'a LspSettings> {
14232    ProjectSettings::get(Some(location), cx).lsp.get(language)
14233}
14234
14235pub struct LocalLspAdapterDelegate {
14236    lsp_store: WeakEntity<LspStore>,
14237    worktree: worktree::Snapshot,
14238    fs: Arc<dyn Fs>,
14239    http_client: Arc<dyn HttpClient>,
14240    language_registry: Arc<LanguageRegistry>,
14241    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14242}
14243
14244impl LocalLspAdapterDelegate {
14245    pub fn new(
14246        language_registry: Arc<LanguageRegistry>,
14247        environment: &Entity<ProjectEnvironment>,
14248        lsp_store: WeakEntity<LspStore>,
14249        worktree: &Entity<Worktree>,
14250        http_client: Arc<dyn HttpClient>,
14251        fs: Arc<dyn Fs>,
14252        cx: &mut App,
14253    ) -> Arc<Self> {
14254        let load_shell_env_task =
14255            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14256
14257        Arc::new(Self {
14258            lsp_store,
14259            worktree: worktree.read(cx).snapshot(),
14260            fs,
14261            http_client,
14262            language_registry,
14263            load_shell_env_task,
14264        })
14265    }
14266
14267    pub fn from_local_lsp(
14268        local: &LocalLspStore,
14269        worktree: &Entity<Worktree>,
14270        cx: &mut App,
14271    ) -> Arc<Self> {
14272        Self::new(
14273            local.languages.clone(),
14274            &local.environment,
14275            local.weak.clone(),
14276            worktree,
14277            local.http_client.clone(),
14278            local.fs.clone(),
14279            cx,
14280        )
14281    }
14282}
14283
14284#[async_trait]
14285impl LspAdapterDelegate for LocalLspAdapterDelegate {
14286    fn show_notification(&self, message: &str, cx: &mut App) {
14287        self.lsp_store
14288            .update(cx, |_, cx| {
14289                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14290            })
14291            .ok();
14292    }
14293
14294    fn http_client(&self) -> Arc<dyn HttpClient> {
14295        self.http_client.clone()
14296    }
14297
14298    fn worktree_id(&self) -> WorktreeId {
14299        self.worktree.id()
14300    }
14301
14302    fn worktree_root_path(&self) -> &Path {
14303        self.worktree.abs_path().as_ref()
14304    }
14305
14306    fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
14307        self.worktree.resolve_relative_path(path)
14308    }
14309
14310    async fn shell_env(&self) -> HashMap<String, String> {
14311        let task = self.load_shell_env_task.clone();
14312        task.await.unwrap_or_default()
14313    }
14314
14315    async fn npm_package_installed_version(
14316        &self,
14317        package_name: &str,
14318    ) -> Result<Option<(PathBuf, Version)>> {
14319        let local_package_directory = self.worktree_root_path();
14320        let node_modules_directory = local_package_directory.join("node_modules");
14321
14322        if let Some(version) =
14323            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14324        {
14325            return Ok(Some((node_modules_directory, version)));
14326        }
14327        let Some(npm) = self.which("npm".as_ref()).await else {
14328            log::warn!(
14329                "Failed to find npm executable for {:?}",
14330                local_package_directory
14331            );
14332            return Ok(None);
14333        };
14334
14335        let env = self.shell_env().await;
14336        let output = util::command::new_command(&npm)
14337            .args(["root", "-g"])
14338            .envs(env)
14339            .current_dir(local_package_directory)
14340            .output()
14341            .await?;
14342        let global_node_modules =
14343            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14344
14345        if let Some(version) =
14346            read_package_installed_version(global_node_modules.clone(), package_name).await?
14347        {
14348            return Ok(Some((global_node_modules, version)));
14349        }
14350        return Ok(None);
14351    }
14352
14353    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14354        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14355        if self.fs.is_file(&worktree_abs_path).await {
14356            worktree_abs_path.pop();
14357        }
14358
14359        let env = self.shell_env().await;
14360
14361        let shell_path = env.get("PATH").cloned();
14362
14363        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14364    }
14365
14366    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14367        let mut working_dir = self.worktree_root_path().to_path_buf();
14368        if self.fs.is_file(&working_dir).await {
14369            working_dir.pop();
14370        }
14371        let output = util::command::new_command(&command.path)
14372            .args(command.arguments)
14373            .envs(command.env.clone().unwrap_or_default())
14374            .current_dir(working_dir)
14375            .output()
14376            .await?;
14377
14378        anyhow::ensure!(
14379            output.status.success(),
14380            "{}, stdout: {:?}, stderr: {:?}",
14381            output.status,
14382            String::from_utf8_lossy(&output.stdout),
14383            String::from_utf8_lossy(&output.stderr)
14384        );
14385        Ok(())
14386    }
14387
14388    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14389        self.language_registry
14390            .update_lsp_binary_status(server_name, status);
14391    }
14392
14393    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14394        self.language_registry
14395            .all_lsp_adapters()
14396            .into_iter()
14397            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14398            .collect()
14399    }
14400
14401    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14402        let dir = self.language_registry.language_server_download_dir(name)?;
14403
14404        if !dir.exists() {
14405            smol::fs::create_dir_all(&dir)
14406                .await
14407                .context("failed to create container directory")
14408                .log_err()?;
14409        }
14410
14411        Some(dir)
14412    }
14413
14414    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14415        let entry = self
14416            .worktree
14417            .entry_for_path(path)
14418            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14419        let abs_path = self.worktree.absolutize(&entry.path);
14420        self.fs.load(&abs_path).await
14421    }
14422}
14423
14424async fn populate_labels_for_symbols(
14425    symbols: Vec<CoreSymbol>,
14426    language_registry: &Arc<LanguageRegistry>,
14427    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14428    output: &mut Vec<Symbol>,
14429) {
14430    #[allow(clippy::mutable_key_type)]
14431    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14432
14433    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14434    for symbol in symbols {
14435        let Some(file_name) = symbol.path.file_name() else {
14436            continue;
14437        };
14438        let language = language_registry
14439            .load_language_for_file_path(Path::new(file_name))
14440            .await
14441            .ok()
14442            .or_else(|| {
14443                unknown_paths.insert(file_name.into());
14444                None
14445            });
14446        symbols_by_language
14447            .entry(language)
14448            .or_default()
14449            .push(symbol);
14450    }
14451
14452    for unknown_path in unknown_paths {
14453        log::info!("no language found for symbol in file {unknown_path:?}");
14454    }
14455
14456    let mut label_params = Vec::new();
14457    for (language, mut symbols) in symbols_by_language {
14458        label_params.clear();
14459        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14460            name: mem::take(&mut symbol.name),
14461            kind: symbol.kind,
14462            container_name: symbol.container_name.take(),
14463        }));
14464
14465        let mut labels = Vec::new();
14466        if let Some(language) = language {
14467            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14468                language_registry
14469                    .lsp_adapters(&language.name())
14470                    .first()
14471                    .cloned()
14472            });
14473            if let Some(lsp_adapter) = lsp_adapter {
14474                labels = lsp_adapter
14475                    .labels_for_symbols(&label_params, &language)
14476                    .await
14477                    .log_err()
14478                    .unwrap_or_default();
14479            }
14480        }
14481
14482        for (
14483            (
14484                symbol,
14485                language::Symbol {
14486                    name,
14487                    container_name,
14488                    ..
14489                },
14490            ),
14491            label,
14492        ) in symbols
14493            .into_iter()
14494            .zip(label_params.drain(..))
14495            .zip(labels.into_iter().chain(iter::repeat(None)))
14496        {
14497            output.push(Symbol {
14498                language_server_name: symbol.language_server_name,
14499                source_worktree_id: symbol.source_worktree_id,
14500                source_language_server_id: symbol.source_language_server_id,
14501                path: symbol.path,
14502                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14503                name,
14504                kind: symbol.kind,
14505                range: symbol.range,
14506                container_name,
14507            });
14508        }
14509    }
14510}
14511
14512pub(crate) fn collapse_newlines(text: &str, separator: &str) -> String {
14513    text.lines()
14514        .map(|line| line.trim())
14515        .filter(|line| !line.is_empty())
14516        .join(separator)
14517}
14518
14519fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14520    match server.capabilities().text_document_sync.as_ref()? {
14521        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14522            // Server wants didSave but didn't specify includeText.
14523            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14524            // Server doesn't want didSave at all.
14525            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14526            // Server provided SaveOptions.
14527            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14528                Some(save_options.include_text.unwrap_or(false))
14529            }
14530        },
14531        // We do not have any save info. Kind affects didChange only.
14532        lsp::TextDocumentSyncCapability::Kind(_) => None,
14533    }
14534}
14535
14536/// Completion items are displayed in a `UniformList`.
14537/// Usually, those items are single-line strings, but in LSP responses,
14538/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14539/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14540/// 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,
14541/// breaking the completions menu presentation.
14542///
14543/// 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.
14544pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14545    let mut new_text = String::with_capacity(label.text.len());
14546    let mut offset_map = vec![0; label.text.len() + 1];
14547    let mut last_char_was_space = false;
14548    let mut new_idx = 0;
14549    let chars = label.text.char_indices().fuse();
14550    let mut newlines_removed = false;
14551
14552    for (idx, c) in chars {
14553        offset_map[idx] = new_idx;
14554
14555        match c {
14556            '\n' if last_char_was_space => {
14557                newlines_removed = true;
14558            }
14559            '\t' | ' ' if last_char_was_space => {}
14560            '\n' if !last_char_was_space => {
14561                new_text.push(' ');
14562                new_idx += 1;
14563                last_char_was_space = true;
14564                newlines_removed = true;
14565            }
14566            ' ' | '\t' => {
14567                new_text.push(' ');
14568                new_idx += 1;
14569                last_char_was_space = true;
14570            }
14571            _ => {
14572                new_text.push(c);
14573                new_idx += c.len_utf8();
14574                last_char_was_space = false;
14575            }
14576        }
14577    }
14578    offset_map[label.text.len()] = new_idx;
14579
14580    // Only modify the label if newlines were removed.
14581    if !newlines_removed {
14582        return;
14583    }
14584
14585    let last_index = new_idx;
14586    let mut run_ranges_errors = Vec::new();
14587    label.runs.retain_mut(|(range, _)| {
14588        match offset_map.get(range.start) {
14589            Some(&start) => range.start = start,
14590            None => {
14591                run_ranges_errors.push(range.clone());
14592                return false;
14593            }
14594        }
14595
14596        match offset_map.get(range.end) {
14597            Some(&end) => range.end = end,
14598            None => {
14599                run_ranges_errors.push(range.clone());
14600                range.end = last_index;
14601            }
14602        }
14603        true
14604    });
14605    if !run_ranges_errors.is_empty() {
14606        log::error!(
14607            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14608            label.text
14609        );
14610    }
14611
14612    let mut wrong_filter_range = None;
14613    if label.filter_range == (0..label.text.len()) {
14614        label.filter_range = 0..new_text.len();
14615    } else {
14616        let mut original_filter_range = Some(label.filter_range.clone());
14617        match offset_map.get(label.filter_range.start) {
14618            Some(&start) => label.filter_range.start = start,
14619            None => {
14620                wrong_filter_range = original_filter_range.take();
14621                label.filter_range.start = last_index;
14622            }
14623        }
14624
14625        match offset_map.get(label.filter_range.end) {
14626            Some(&end) => label.filter_range.end = end,
14627            None => {
14628                wrong_filter_range = original_filter_range.take();
14629                label.filter_range.end = last_index;
14630            }
14631        }
14632    }
14633    if let Some(wrong_filter_range) = wrong_filter_range {
14634        log::error!(
14635            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14636            label.text
14637        );
14638    }
14639
14640    label.text = new_text;
14641}
14642
14643/// Apply edits to the buffer that will become part of the formatting transaction.
14644/// Fails if the buffer has been edited since the start of that transaction.
14645fn extend_formatting_transaction(
14646    buffer: &FormattableBuffer,
14647    formatting_transaction_id: text::TransactionId,
14648    cx: &mut AsyncApp,
14649    operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
14650) -> anyhow::Result<()> {
14651    buffer.handle.update(cx, |buffer, cx| {
14652        let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
14653        if last_transaction_id != Some(formatting_transaction_id) {
14654            anyhow::bail!("Buffer edited while formatting. Aborting")
14655        }
14656        buffer.start_transaction();
14657        operation(buffer, cx);
14658        if let Some(transaction_id) = buffer.end_transaction(cx) {
14659            buffer.merge_transactions(transaction_id, formatting_transaction_id);
14660        }
14661        Ok(())
14662    })
14663}