lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13mod code_lens;
   14mod document_colors;
   15mod document_symbols;
   16mod folding_ranges;
   17mod inlay_hints;
   18pub mod json_language_server_ext;
   19pub mod log_store;
   20pub mod lsp_ext_command;
   21pub mod rust_analyzer_ext;
   22mod semantic_tokens;
   23pub mod vue_language_server_ext;
   24
   25use self::code_lens::CodeLensData;
   26use self::document_colors::DocumentColorData;
   27use self::document_symbols::DocumentSymbolsData;
   28use self::inlay_hints::BufferInlayHints;
   29use crate::{
   30    CodeAction, Completion, CompletionDisplayOptions, CompletionResponse, CompletionSource,
   31    CoreCompletion, Hover, InlayHint, InlayId, LocationLink, LspAction, LspPullDiagnostics,
   32    ManifestProvidersStore, Project, ProjectItem, ProjectPath, ProjectTransaction,
   33    PulledDiagnostics, ResolveState, Symbol,
   34    buffer_store::{BufferStore, BufferStoreEvent},
   35    environment::ProjectEnvironment,
   36    lsp_command::{self, *},
   37    lsp_store::{
   38        self,
   39        folding_ranges::FoldingRangeData,
   40        log_store::{GlobalLogStore, LanguageServerKind},
   41        semantic_tokens::{SemanticTokenConfig, SemanticTokensData},
   42    },
   43    manifest_tree::{
   44        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   45        ManifestTree,
   46    },
   47    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   48    project_settings::{BinarySettings, LspSettings, ProjectSettings},
   49    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   50    trusted_worktrees::{PathTrust, TrustedWorktrees, TrustedWorktreesEvent},
   51    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   52    yarn::YarnPathStore,
   53};
   54use anyhow::{Context as _, Result, anyhow};
   55use async_trait::async_trait;
   56use client::{TypedEnvelope, proto};
   57use clock::Global;
   58use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   59use futures::{
   60    AsyncWriteExt, Future, FutureExt, StreamExt,
   61    future::{Either, Shared, join_all, pending, select},
   62    select, select_biased,
   63    stream::FuturesUnordered,
   64};
   65use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   66use gpui::{
   67    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString,
   68    Subscription, Task, WeakEntity,
   69};
   70use http_client::HttpClient;
   71use itertools::Itertools as _;
   72use language::{
   73    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, Capability, CodeLabel,
   74    CodeLabelExt, Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff,
   75    File as _, Language, LanguageName, LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate,
   76    LspInstaller, ManifestDelegate, ManifestName, ModelineSettings, Patch, PointUtf16,
   77    TextBufferSnapshot, ToOffset, ToPointUtf16, Toolchain, Transaction, Unclipped,
   78    language_settings::{
   79        AllLanguageSettings, FormatOnSave, Formatter, LanguageSettings, all_language_settings,
   80    },
   81    modeline, point_to_lsp,
   82    proto::{
   83        deserialize_anchor, deserialize_anchor_range, deserialize_version, serialize_anchor,
   84        serialize_anchor_range, serialize_version,
   85    },
   86    range_from_lsp, range_to_lsp,
   87    row_chunk::RowChunk,
   88};
   89use lsp::{
   90    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   91    DEFAULT_LSP_REQUEST_TIMEOUT, DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   92    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   93    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LanguageServer,
   94    LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId, LanguageServerName,
   95    LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType, OneOf,
   96    RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles,
   97    WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   98};
   99use node_runtime::read_package_installed_version;
  100use parking_lot::Mutex;
  101use postage::{mpsc, sink::Sink, stream::Stream, watch};
  102use rand::prelude::*;
  103use rpc::{
  104    AnyProtoClient, ErrorCode, ErrorExt as _,
  105    proto::{LspRequestId, LspRequestMessage as _},
  106};
  107use semver::Version;
  108use serde::Serialize;
  109use serde_json::Value;
  110use settings::{Settings, SettingsLocation, SettingsStore};
  111use sha2::{Digest, Sha256};
  112use snippet::Snippet;
  113use std::{
  114    any::TypeId,
  115    borrow::Cow,
  116    cell::RefCell,
  117    cmp::{Ordering, Reverse},
  118    collections::{VecDeque, hash_map},
  119    convert::TryInto,
  120    ffi::OsStr,
  121    future::ready,
  122    iter, mem,
  123    ops::{ControlFlow, Range},
  124    path::{self, Path, PathBuf},
  125    pin::pin,
  126    rc::Rc,
  127    sync::{
  128        Arc,
  129        atomic::{self, AtomicUsize},
  130    },
  131    time::{Duration, Instant},
  132    vec,
  133};
  134use sum_tree::Dimensions;
  135use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  136
  137use util::{
  138    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  139    paths::{PathStyle, SanitizedPath, UrlExt},
  140    post_inc,
  141    redact::redact_command,
  142    rel_path::RelPath,
  143};
  144
  145pub use document_colors::DocumentColors;
  146pub use folding_ranges::LspFoldingRange;
  147pub use fs::*;
  148pub use language::Location;
  149pub use lsp_store::inlay_hints::{CacheInlayHints, InvalidationStrategy};
  150#[cfg(any(test, feature = "test-support"))]
  151pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  152pub use semantic_tokens::{
  153    BufferSemanticToken, BufferSemanticTokens, RefreshForServer, SemanticTokenStylizer, TokenType,
  154};
  155
  156pub use worktree::{
  157    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  158    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  159};
  160
  161const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  162pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  163const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  164const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  165static NEXT_PROMPT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
  166
  167#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  168pub enum ProgressToken {
  169    Number(i32),
  170    String(SharedString),
  171}
  172
  173impl std::fmt::Display for ProgressToken {
  174    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  175        match self {
  176            Self::Number(number) => write!(f, "{number}"),
  177            Self::String(string) => write!(f, "{string}"),
  178        }
  179    }
  180}
  181
  182impl ProgressToken {
  183    fn from_lsp(value: lsp::NumberOrString) -> Self {
  184        match value {
  185            lsp::NumberOrString::Number(number) => Self::Number(number),
  186            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  187        }
  188    }
  189
  190    fn to_lsp(&self) -> lsp::NumberOrString {
  191        match self {
  192            Self::Number(number) => lsp::NumberOrString::Number(*number),
  193            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  194        }
  195    }
  196
  197    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  198        Some(match value.value? {
  199            proto::progress_token::Value::Number(number) => Self::Number(number),
  200            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  201        })
  202    }
  203
  204    fn to_proto(&self) -> proto::ProgressToken {
  205        proto::ProgressToken {
  206            value: Some(match self {
  207                Self::Number(number) => proto::progress_token::Value::Number(*number),
  208                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  209            }),
  210        }
  211    }
  212}
  213
  214#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  215pub enum FormatTrigger {
  216    Save,
  217    Manual,
  218}
  219
  220pub enum LspFormatTarget {
  221    Buffers,
  222    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  223}
  224
  225#[derive(Debug, Clone, PartialEq, Eq, Hash)]
  226pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  227
  228struct OpenLspBuffer(Entity<Buffer>);
  229
  230impl FormatTrigger {
  231    fn from_proto(value: i32) -> FormatTrigger {
  232        match value {
  233            0 => FormatTrigger::Save,
  234            1 => FormatTrigger::Manual,
  235            _ => FormatTrigger::Save,
  236        }
  237    }
  238}
  239
  240#[derive(Clone)]
  241struct UnifiedLanguageServer {
  242    id: LanguageServerId,
  243    project_roots: HashSet<Arc<RelPath>>,
  244}
  245
  246/// Settings that affect language server identity.
  247///
  248/// Dynamic settings (`LspSettings::settings`) are excluded because they can be
  249/// updated via `workspace/didChangeConfiguration` without restarting the server.
  250#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  251struct LanguageServerSeedSettings {
  252    binary: Option<BinarySettings>,
  253    initialization_options: Option<serde_json::Value>,
  254}
  255
  256#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  257struct LanguageServerSeed {
  258    worktree_id: WorktreeId,
  259    name: LanguageServerName,
  260    toolchain: Option<Toolchain>,
  261    settings: LanguageServerSeedSettings,
  262}
  263
  264#[derive(Debug)]
  265pub struct DocumentDiagnosticsUpdate<'a, D> {
  266    pub diagnostics: D,
  267    pub result_id: Option<SharedString>,
  268    pub registration_id: Option<SharedString>,
  269    pub server_id: LanguageServerId,
  270    pub disk_based_sources: Cow<'a, [String]>,
  271}
  272
  273pub struct DocumentDiagnostics {
  274    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  275    document_abs_path: PathBuf,
  276    version: Option<i32>,
  277}
  278
  279#[derive(Default, Debug)]
  280struct DynamicRegistrations {
  281    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  282    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  283}
  284
  285pub struct LocalLspStore {
  286    weak: WeakEntity<LspStore>,
  287    pub worktree_store: Entity<WorktreeStore>,
  288    toolchain_store: Entity<LocalToolchainStore>,
  289    http_client: Arc<dyn HttpClient>,
  290    environment: Entity<ProjectEnvironment>,
  291    fs: Arc<dyn Fs>,
  292    languages: Arc<LanguageRegistry>,
  293    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  294    yarn: Entity<YarnPathStore>,
  295    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  296    buffers_being_formatted: HashSet<BufferId>,
  297    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  298    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  299    watched_manifest_filenames: HashSet<ManifestName>,
  300    language_server_paths_watched_for_rename:
  301        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  302    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  303    supplementary_language_servers:
  304        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  305    prettier_store: Entity<PrettierStore>,
  306    next_diagnostic_group_id: usize,
  307    diagnostics: HashMap<
  308        WorktreeId,
  309        HashMap<
  310            Arc<RelPath>,
  311            Vec<(
  312                LanguageServerId,
  313                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  314            )>,
  315        >,
  316    >,
  317    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  318    _subscription: gpui::Subscription,
  319    lsp_tree: LanguageServerTree,
  320    registered_buffers: HashMap<BufferId, usize>,
  321    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  322    buffer_pull_diagnostics_result_ids: HashMap<
  323        LanguageServerId,
  324        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  325    >,
  326    workspace_pull_diagnostics_result_ids: HashMap<
  327        LanguageServerId,
  328        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  329    >,
  330    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  331
  332    buffers_to_refresh_hash_set: HashSet<BufferId>,
  333    buffers_to_refresh_queue: VecDeque<BufferId>,
  334    _background_diagnostics_worker: Shared<Task<()>>,
  335}
  336
  337impl LocalLspStore {
  338    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  339    pub fn running_language_server_for_id(
  340        &self,
  341        id: LanguageServerId,
  342    ) -> Option<&Arc<LanguageServer>> {
  343        let language_server_state = self.language_servers.get(&id)?;
  344
  345        match language_server_state {
  346            LanguageServerState::Running { server, .. } => Some(server),
  347            LanguageServerState::Starting { .. } => None,
  348        }
  349    }
  350
  351    fn get_or_insert_language_server(
  352        &mut self,
  353        worktree_handle: &Entity<Worktree>,
  354        delegate: Arc<LocalLspAdapterDelegate>,
  355        disposition: &Arc<LaunchDisposition>,
  356        language_name: &LanguageName,
  357        cx: &mut App,
  358    ) -> LanguageServerId {
  359        let key = LanguageServerSeed {
  360            worktree_id: worktree_handle.read(cx).id(),
  361            name: disposition.server_name.clone(),
  362            settings: LanguageServerSeedSettings {
  363                binary: disposition.settings.binary.clone(),
  364                initialization_options: disposition.settings.initialization_options.clone(),
  365            },
  366            toolchain: disposition.toolchain.clone(),
  367        };
  368        if let Some(state) = self.language_server_ids.get_mut(&key) {
  369            state.project_roots.insert(disposition.path.path.clone());
  370            state.id
  371        } else {
  372            let adapter = self
  373                .languages
  374                .lsp_adapters(language_name)
  375                .into_iter()
  376                .find(|adapter| adapter.name() == disposition.server_name)
  377                .expect("To find LSP adapter");
  378            let new_language_server_id = self.start_language_server(
  379                worktree_handle,
  380                delegate,
  381                adapter,
  382                disposition.settings.clone(),
  383                key.clone(),
  384                language_name.clone(),
  385                cx,
  386            );
  387            if let Some(state) = self.language_server_ids.get_mut(&key) {
  388                state.project_roots.insert(disposition.path.path.clone());
  389            } else {
  390                debug_assert!(
  391                    false,
  392                    "Expected `start_language_server` to ensure that `key` exists in a map"
  393                );
  394            }
  395            new_language_server_id
  396        }
  397    }
  398
  399    fn start_language_server(
  400        &mut self,
  401        worktree_handle: &Entity<Worktree>,
  402        delegate: Arc<LocalLspAdapterDelegate>,
  403        adapter: Arc<CachedLspAdapter>,
  404        settings: Arc<LspSettings>,
  405        key: LanguageServerSeed,
  406        language_name: LanguageName,
  407        cx: &mut App,
  408    ) -> LanguageServerId {
  409        let worktree = worktree_handle.read(cx);
  410
  411        let worktree_id = worktree.id();
  412        let worktree_abs_path = worktree.abs_path();
  413        let toolchain = key.toolchain.clone();
  414        let override_options = settings.initialization_options.clone();
  415
  416        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  417
  418        let server_id = self.languages.next_language_server_id();
  419        log::trace!(
  420            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  421            adapter.name.0
  422        );
  423
  424        let wait_until_worktree_trust =
  425            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  426                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  427                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  428                });
  429                if can_trust {
  430                    self.restricted_worktrees_tasks.remove(&worktree_id);
  431                    None
  432                } else {
  433                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  434                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  435                        hash_map::Entry::Vacant(v) => {
  436                            let (mut tx, rx) = watch::channel::<bool>();
  437                            let lsp_store = self.weak.clone();
  438                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  439                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  440                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  441                                        tx.blocking_send(true).ok();
  442                                        lsp_store
  443                                            .update(cx, |lsp_store, _| {
  444                                                if let Some(local_lsp_store) =
  445                                                    lsp_store.as_local_mut()
  446                                                {
  447                                                    local_lsp_store
  448                                                        .restricted_worktrees_tasks
  449                                                        .remove(&worktree_id);
  450                                                }
  451                                            })
  452                                            .ok();
  453                                    }
  454                                }
  455                            });
  456                            v.insert((subscription, rx.clone()));
  457                            Some(rx)
  458                        }
  459                    }
  460                }
  461            });
  462        let update_binary_status = wait_until_worktree_trust.is_none();
  463
  464        let binary = self.get_language_server_binary(
  465            worktree_abs_path.clone(),
  466            adapter.clone(),
  467            settings,
  468            toolchain.clone(),
  469            delegate.clone(),
  470            true,
  471            wait_until_worktree_trust,
  472            cx,
  473        );
  474        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  475
  476        let pending_server = cx.spawn({
  477            let adapter = adapter.clone();
  478            let server_name = adapter.name.clone();
  479            let stderr_capture = stderr_capture.clone();
  480            #[cfg(any(test, feature = "test-support"))]
  481            let lsp_store = self.weak.clone();
  482            let pending_workspace_folders = pending_workspace_folders.clone();
  483            async move |cx| {
  484                let binary = binary.await?;
  485                #[cfg(any(test, feature = "test-support"))]
  486                if let Some(server) = lsp_store
  487                    .update(&mut cx.clone(), |this, cx| {
  488                        this.languages.create_fake_language_server(
  489                            server_id,
  490                            &server_name,
  491                            binary.clone(),
  492                            &mut cx.to_async(),
  493                        )
  494                    })
  495                    .ok()
  496                    .flatten()
  497                {
  498                    return Ok(server);
  499                }
  500
  501                let code_action_kinds = adapter.code_action_kinds();
  502                lsp::LanguageServer::new(
  503                    stderr_capture,
  504                    server_id,
  505                    server_name,
  506                    binary,
  507                    &worktree_abs_path,
  508                    code_action_kinds,
  509                    Some(pending_workspace_folders),
  510                    cx,
  511                )
  512            }
  513        });
  514
  515        let startup = {
  516            let server_name = adapter.name.0.clone();
  517            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  518            let key = key.clone();
  519            let adapter = adapter.clone();
  520            let lsp_store = self.weak.clone();
  521            let pending_workspace_folders = pending_workspace_folders.clone();
  522            let pull_diagnostics = ProjectSettings::get_global(cx)
  523                .diagnostics
  524                .lsp_pull_diagnostics
  525                .enabled;
  526            let settings_location = SettingsLocation {
  527                worktree_id,
  528                path: RelPath::empty(),
  529            };
  530            let augments_syntax_tokens = AllLanguageSettings::get(Some(settings_location), cx)
  531                .language(Some(settings_location), Some(&language_name), cx)
  532                .semantic_tokens
  533                .use_tree_sitter();
  534            cx.spawn(async move |cx| {
  535                let result = async {
  536                    let language_server = pending_server.await?;
  537
  538                    let workspace_config = Self::workspace_configuration_for_adapter(
  539                        adapter.adapter.clone(),
  540                        &delegate,
  541                        toolchain,
  542                        None,
  543                        cx,
  544                    )
  545                    .await?;
  546
  547                    let mut initialization_options = Self::initialization_options_for_adapter(
  548                        adapter.adapter.clone(),
  549                        &delegate,
  550                        cx,
  551                    )
  552                    .await?;
  553
  554                    match (&mut initialization_options, override_options) {
  555                        (Some(initialization_options), Some(override_options)) => {
  556                            merge_json_value_into(override_options, initialization_options);
  557                        }
  558                        (None, override_options) => initialization_options = override_options,
  559                        _ => {}
  560                    }
  561
  562                    let initialization_params = cx.update(|cx| {
  563                        let mut params = language_server.default_initialize_params(
  564                            pull_diagnostics,
  565                            augments_syntax_tokens,
  566                            cx,
  567                        );
  568                        params.initialization_options = initialization_options;
  569                        adapter.adapter.prepare_initialize_params(params, cx)
  570                    })?;
  571
  572                    Self::setup_lsp_messages(
  573                        lsp_store.clone(),
  574                        &language_server,
  575                        delegate.clone(),
  576                        adapter.clone(),
  577                    );
  578
  579                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  580                        settings: workspace_config,
  581                    };
  582                    let language_server = cx
  583                        .update(|cx| {
  584                            let request_timeout = ProjectSettings::get_global(cx)
  585                                .global_lsp_settings
  586                                .get_request_timeout();
  587
  588                            language_server.initialize(
  589                                initialization_params,
  590                                Arc::new(did_change_configuration_params.clone()),
  591                                request_timeout,
  592                                cx,
  593                            )
  594                        })
  595                        .await
  596                        .inspect_err(|_| {
  597                            if let Some(lsp_store) = lsp_store.upgrade() {
  598                                lsp_store.update(cx, |lsp_store, cx| {
  599                                    lsp_store.cleanup_lsp_data(server_id);
  600                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  601                                });
  602                            }
  603                        })?;
  604
  605                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  606                        did_change_configuration_params,
  607                    )?;
  608
  609                    anyhow::Ok(language_server)
  610                }
  611                .await;
  612
  613                match result {
  614                    Ok(server) => {
  615                        lsp_store
  616                            .update(cx, |lsp_store, cx| {
  617                                lsp_store.insert_newly_running_language_server(
  618                                    adapter,
  619                                    server.clone(),
  620                                    server_id,
  621                                    key,
  622                                    pending_workspace_folders,
  623                                    cx,
  624                                );
  625                            })
  626                            .ok();
  627                        stderr_capture.lock().take();
  628                        Some(server)
  629                    }
  630
  631                    Err(err) => {
  632                        let log = stderr_capture.lock().take().unwrap_or_default();
  633                        delegate.update_status(
  634                            adapter.name(),
  635                            BinaryStatus::Failed {
  636                                error: if log.is_empty() {
  637                                    format!("{err:#}")
  638                                } else {
  639                                    format!("{err:#}\n-- stderr --\n{log}")
  640                                },
  641                            },
  642                        );
  643                        log::error!(
  644                            "Failed to start language server {server_name:?}: {}",
  645                            redact_command(&format!("{err:?}"))
  646                        );
  647                        if !log.is_empty() {
  648                            log::error!("server stderr: {}", redact_command(&log));
  649                        }
  650                        None
  651                    }
  652                }
  653            })
  654        };
  655        let state = LanguageServerState::Starting {
  656            startup,
  657            pending_workspace_folders,
  658        };
  659
  660        if update_binary_status {
  661            self.languages
  662                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  663        }
  664
  665        self.language_servers.insert(server_id, state);
  666        self.language_server_ids
  667            .entry(key)
  668            .or_insert(UnifiedLanguageServer {
  669                id: server_id,
  670                project_roots: Default::default(),
  671            });
  672        server_id
  673    }
  674
  675    fn get_language_server_binary(
  676        &self,
  677        worktree_abs_path: Arc<Path>,
  678        adapter: Arc<CachedLspAdapter>,
  679        settings: Arc<LspSettings>,
  680        toolchain: Option<Toolchain>,
  681        delegate: Arc<dyn LspAdapterDelegate>,
  682        allow_binary_download: bool,
  683        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  684        cx: &mut App,
  685    ) -> Task<Result<LanguageServerBinary>> {
  686        if let Some(settings) = &settings.binary
  687            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  688        {
  689            let settings = settings.clone();
  690            let languages = self.languages.clone();
  691            return cx.background_spawn(async move {
  692                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  693                    let already_trusted =  *wait_until_worktree_trust.borrow();
  694                    if !already_trusted {
  695                        log::info!(
  696                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  697                            adapter.name(),
  698                        );
  699                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  700                            if worktree_trusted {
  701                                break;
  702                            }
  703                        }
  704                        log::info!(
  705                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  706                            adapter.name(),
  707                        );
  708                    }
  709                    languages
  710                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  711                }
  712                let mut env = delegate.shell_env().await;
  713                env.extend(settings.env.unwrap_or_default());
  714
  715                Ok(LanguageServerBinary {
  716                    path: delegate.resolve_relative_path(path),
  717                    env: Some(env),
  718                    arguments: settings
  719                        .arguments
  720                        .unwrap_or_default()
  721                        .iter()
  722                        .map(Into::into)
  723                        .collect(),
  724                })
  725            });
  726        }
  727        let lsp_binary_options = LanguageServerBinaryOptions {
  728            allow_path_lookup: !settings
  729                .binary
  730                .as_ref()
  731                .and_then(|b| b.ignore_system_version)
  732                .unwrap_or_default(),
  733            allow_binary_download,
  734            pre_release: settings
  735                .fetch
  736                .as_ref()
  737                .and_then(|f| f.pre_release)
  738                .unwrap_or(false),
  739        };
  740
  741        cx.spawn(async move |cx| {
  742            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  743                let already_trusted =  *wait_until_worktree_trust.borrow();
  744                if !already_trusted {
  745                    log::info!(
  746                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  747                        adapter.name(),
  748                    );
  749                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  750                        if worktree_trusted {
  751                            break;
  752                        }
  753                    }
  754                    log::info!(
  755                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  756                            adapter.name(),
  757                    );
  758                }
  759            }
  760
  761            let (existing_binary, maybe_download_binary) = adapter
  762                .clone()
  763                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  764                .await
  765                .await;
  766
  767            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  768
  769            let mut binary = match (existing_binary, maybe_download_binary) {
  770                (binary, None) => binary?,
  771                (Err(_), Some(downloader)) => downloader.await?,
  772                (Ok(existing_binary), Some(downloader)) => {
  773                    let mut download_timeout = cx
  774                        .background_executor()
  775                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  776                        .fuse();
  777                    let mut downloader = downloader.fuse();
  778                    futures::select! {
  779                        _ = download_timeout => {
  780                            // Return existing binary and kick the existing work to the background.
  781                            cx.spawn(async move |_| downloader.await).detach();
  782                            Ok(existing_binary)
  783                        },
  784                        downloaded_or_existing_binary = downloader => {
  785                            // If download fails, this results in the existing binary.
  786                            downloaded_or_existing_binary
  787                        }
  788                    }?
  789                }
  790            };
  791            let mut shell_env = delegate.shell_env().await;
  792
  793            shell_env.extend(binary.env.unwrap_or_default());
  794
  795            if let Some(settings) = settings.binary.as_ref() {
  796                if let Some(arguments) = &settings.arguments {
  797                    binary.arguments = arguments.iter().map(Into::into).collect();
  798                }
  799                if let Some(env) = &settings.env {
  800                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  801                }
  802            }
  803
  804            binary.env = Some(shell_env);
  805            Ok(binary)
  806        })
  807    }
  808
  809    fn setup_lsp_messages(
  810        lsp_store: WeakEntity<LspStore>,
  811        language_server: &LanguageServer,
  812        delegate: Arc<dyn LspAdapterDelegate>,
  813        adapter: Arc<CachedLspAdapter>,
  814    ) {
  815        let name = language_server.name();
  816        let server_id = language_server.server_id();
  817        language_server
  818            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  819                let adapter = adapter.clone();
  820                let this = lsp_store.clone();
  821                move |mut params, cx| {
  822                    let adapter = adapter.clone();
  823                    if let Some(this) = this.upgrade() {
  824                        this.update(cx, |this, cx| {
  825                            adapter.process_diagnostics(&mut params, server_id);
  826
  827                            this.merge_lsp_diagnostics(
  828                                DiagnosticSourceKind::Pushed,
  829                                vec![DocumentDiagnosticsUpdate {
  830                                    server_id,
  831                                    diagnostics: params,
  832                                    result_id: None,
  833                                    disk_based_sources: Cow::Borrowed(
  834                                        &adapter.disk_based_diagnostic_sources,
  835                                    ),
  836                                    registration_id: None,
  837                                }],
  838                                |_, diagnostic, _cx| match diagnostic.source_kind {
  839                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  840                                        adapter.retain_old_diagnostic(diagnostic)
  841                                    }
  842                                    DiagnosticSourceKind::Pulled => true,
  843                                },
  844                                cx,
  845                            )
  846                            .log_err();
  847                        });
  848                    }
  849                }
  850            })
  851            .detach();
  852        language_server
  853            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  854                let adapter = adapter.adapter.clone();
  855                let delegate = delegate.clone();
  856                let this = lsp_store.clone();
  857                move |params, cx| {
  858                    let adapter = adapter.clone();
  859                    let delegate = delegate.clone();
  860                    let this = this.clone();
  861                    let mut cx = cx.clone();
  862                    async move {
  863                        let toolchain_for_id = this
  864                            .update(&mut cx, |this, _| {
  865                                this.as_local()?.language_server_ids.iter().find_map(
  866                                    |(seed, value)| {
  867                                        (value.id == server_id).then(|| seed.toolchain.clone())
  868                                    },
  869                                )
  870                            })?
  871                            .context("Expected the LSP store to be in a local mode")?;
  872
  873                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  874                        for item in &params.items {
  875                            let scope_uri = item.scope_uri.clone();
  876                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  877                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  878                            else {
  879                                // We've already queried workspace configuration of this URI.
  880                                continue;
  881                            };
  882                            let workspace_config = Self::workspace_configuration_for_adapter(
  883                                adapter.clone(),
  884                                &delegate,
  885                                toolchain_for_id.clone(),
  886                                scope_uri,
  887                                &mut cx,
  888                            )
  889                            .await?;
  890                            new_scope_uri.insert(workspace_config);
  891                        }
  892
  893                        Ok(params
  894                            .items
  895                            .into_iter()
  896                            .filter_map(|item| {
  897                                let workspace_config =
  898                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  899                                if let Some(section) = &item.section {
  900                                    Some(
  901                                        workspace_config
  902                                            .get(section)
  903                                            .cloned()
  904                                            .unwrap_or(serde_json::Value::Null),
  905                                    )
  906                                } else {
  907                                    Some(workspace_config.clone())
  908                                }
  909                            })
  910                            .collect())
  911                    }
  912                }
  913            })
  914            .detach();
  915
  916        language_server
  917            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  918                let this = lsp_store.clone();
  919                move |_, cx| {
  920                    let this = this.clone();
  921                    let cx = cx.clone();
  922                    async move {
  923                        let Some(server) =
  924                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  925                        else {
  926                            return Ok(None);
  927                        };
  928                        let root = server.workspace_folders();
  929                        Ok(Some(
  930                            root.into_iter()
  931                                .map(|uri| WorkspaceFolder {
  932                                    uri,
  933                                    name: Default::default(),
  934                                })
  935                                .collect(),
  936                        ))
  937                    }
  938                }
  939            })
  940            .detach();
  941        // Even though we don't have handling for these requests, respond to them to
  942        // avoid stalling any language server like `gopls` which waits for a response
  943        // to these requests when initializing.
  944        language_server
  945            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  946                let this = lsp_store.clone();
  947                move |params, cx| {
  948                    let this = this.clone();
  949                    let mut cx = cx.clone();
  950                    async move {
  951                        this.update(&mut cx, |this, _| {
  952                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  953                            {
  954                                status
  955                                    .progress_tokens
  956                                    .insert(ProgressToken::from_lsp(params.token));
  957                            }
  958                        })?;
  959
  960                        Ok(())
  961                    }
  962                }
  963            })
  964            .detach();
  965
  966        language_server
  967            .on_request::<lsp::request::RegisterCapability, _, _>({
  968                let lsp_store = lsp_store.clone();
  969                move |params, cx| {
  970                    let lsp_store = lsp_store.clone();
  971                    let mut cx = cx.clone();
  972                    async move {
  973                        lsp_store
  974                            .update(&mut cx, |lsp_store, cx| {
  975                                if lsp_store.as_local().is_some() {
  976                                    match lsp_store
  977                                        .register_server_capabilities(server_id, params, cx)
  978                                    {
  979                                        Ok(()) => {}
  980                                        Err(e) => {
  981                                            log::error!(
  982                                                "Failed to register server capabilities: {e:#}"
  983                                            );
  984                                        }
  985                                    };
  986                                }
  987                            })
  988                            .ok();
  989                        Ok(())
  990                    }
  991                }
  992            })
  993            .detach();
  994
  995        language_server
  996            .on_request::<lsp::request::UnregisterCapability, _, _>({
  997                let lsp_store = lsp_store.clone();
  998                move |params, cx| {
  999                    let lsp_store = lsp_store.clone();
 1000                    let mut cx = cx.clone();
 1001                    async move {
 1002                        lsp_store
 1003                            .update(&mut cx, |lsp_store, cx| {
 1004                                if lsp_store.as_local().is_some() {
 1005                                    match lsp_store
 1006                                        .unregister_server_capabilities(server_id, params, cx)
 1007                                    {
 1008                                        Ok(()) => {}
 1009                                        Err(e) => {
 1010                                            log::error!(
 1011                                                "Failed to unregister server capabilities: {e:#}"
 1012                                            );
 1013                                        }
 1014                                    }
 1015                                }
 1016                            })
 1017                            .ok();
 1018                        Ok(())
 1019                    }
 1020                }
 1021            })
 1022            .detach();
 1023
 1024        language_server
 1025            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
 1026                let this = lsp_store.clone();
 1027                move |params, cx| {
 1028                    let mut cx = cx.clone();
 1029                    let this = this.clone();
 1030                    async move {
 1031                        LocalLspStore::on_lsp_workspace_edit(
 1032                            this.clone(),
 1033                            params,
 1034                            server_id,
 1035                            &mut cx,
 1036                        )
 1037                        .await
 1038                    }
 1039                }
 1040            })
 1041            .detach();
 1042
 1043        language_server
 1044            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1045                let lsp_store = lsp_store.clone();
 1046                let request_id = Arc::new(AtomicUsize::new(0));
 1047                move |(), cx| {
 1048                    let lsp_store = lsp_store.clone();
 1049                    let request_id = request_id.clone();
 1050                    let mut cx = cx.clone();
 1051                    async move {
 1052                        lsp_store
 1053                            .update(&mut cx, |lsp_store, cx| {
 1054                                let request_id =
 1055                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1056                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1057                                    server_id,
 1058                                    request_id,
 1059                                });
 1060                                lsp_store
 1061                                    .downstream_client
 1062                                    .as_ref()
 1063                                    .map(|(client, project_id)| {
 1064                                        client.send(proto::RefreshInlayHints {
 1065                                            project_id: *project_id,
 1066                                            server_id: server_id.to_proto(),
 1067                                            request_id: request_id.map(|id| id as u64),
 1068                                        })
 1069                                    })
 1070                            })?
 1071                            .transpose()?;
 1072                        Ok(())
 1073                    }
 1074                }
 1075            })
 1076            .detach();
 1077
 1078        language_server
 1079            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1080                let this = lsp_store.clone();
 1081                move |(), cx| {
 1082                    let this = this.clone();
 1083                    let mut cx = cx.clone();
 1084                    async move {
 1085                        this.update(&mut cx, |this, cx| {
 1086                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1087                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1088                                client.send(proto::RefreshCodeLens {
 1089                                    project_id: *project_id,
 1090                                })
 1091                            })
 1092                        })?
 1093                        .transpose()?;
 1094                        Ok(())
 1095                    }
 1096                }
 1097            })
 1098            .detach();
 1099
 1100        language_server
 1101            .on_request::<lsp::request::SemanticTokensRefresh, _, _>({
 1102                let lsp_store = lsp_store.clone();
 1103                let request_id = Arc::new(AtomicUsize::new(0));
 1104                move |(), cx| {
 1105                    let lsp_store = lsp_store.clone();
 1106                    let request_id = request_id.clone();
 1107                    let mut cx = cx.clone();
 1108                    async move {
 1109                        lsp_store
 1110                            .update(&mut cx, |lsp_store, cx| {
 1111                                let request_id =
 1112                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1113                                cx.emit(LspStoreEvent::RefreshSemanticTokens {
 1114                                    server_id,
 1115                                    request_id,
 1116                                });
 1117                                lsp_store
 1118                                    .downstream_client
 1119                                    .as_ref()
 1120                                    .map(|(client, project_id)| {
 1121                                        client.send(proto::RefreshSemanticTokens {
 1122                                            project_id: *project_id,
 1123                                            server_id: server_id.to_proto(),
 1124                                            request_id: request_id.map(|id| id as u64),
 1125                                        })
 1126                                    })
 1127                            })?
 1128                            .transpose()?;
 1129                        Ok(())
 1130                    }
 1131                }
 1132            })
 1133            .detach();
 1134
 1135        language_server
 1136            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1137                let this = lsp_store.clone();
 1138                move |(), cx| {
 1139                    let this = this.clone();
 1140                    let mut cx = cx.clone();
 1141                    async move {
 1142                        this.update(&mut cx, |lsp_store, cx| {
 1143                            lsp_store.pull_workspace_diagnostics(server_id);
 1144                            lsp_store
 1145                                .downstream_client
 1146                                .as_ref()
 1147                                .map(|(client, project_id)| {
 1148                                    client.send(proto::PullWorkspaceDiagnostics {
 1149                                        project_id: *project_id,
 1150                                        server_id: server_id.to_proto(),
 1151                                    })
 1152                                })
 1153                                .transpose()?;
 1154                            anyhow::Ok(
 1155                                lsp_store.pull_document_diagnostics_for_server(server_id, None, cx),
 1156                            )
 1157                        })??
 1158                        .await;
 1159                        Ok(())
 1160                    }
 1161                }
 1162            })
 1163            .detach();
 1164
 1165        language_server
 1166            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1167                let this = lsp_store.clone();
 1168                let name = name.to_string();
 1169                let adapter = adapter.clone();
 1170                move |params, cx| {
 1171                    let this = this.clone();
 1172                    let name = name.to_string();
 1173                    let adapter = adapter.clone();
 1174                    let mut cx = cx.clone();
 1175                    async move {
 1176                        let actions = params.actions.unwrap_or_default();
 1177                        let message = params.message.clone();
 1178                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1179                        let level = match params.typ {
 1180                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1181                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1182                            _ => PromptLevel::Info,
 1183                        };
 1184                        let request = LanguageServerPromptRequest::new(
 1185                            level,
 1186                            params.message,
 1187                            actions,
 1188                            name.clone(),
 1189                            tx,
 1190                        );
 1191
 1192                        let did_update = this
 1193                            .update(&mut cx, |_, cx| {
 1194                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1195                            })
 1196                            .is_ok();
 1197                        if did_update {
 1198                            let response = rx.recv().await.ok();
 1199                            if let Some(ref selected_action) = response {
 1200                                let context = language::PromptResponseContext {
 1201                                    message,
 1202                                    selected_action: selected_action.clone(),
 1203                                };
 1204                                adapter.process_prompt_response(&context, &mut cx)
 1205                            }
 1206
 1207                            Ok(response)
 1208                        } else {
 1209                            Ok(None)
 1210                        }
 1211                    }
 1212                }
 1213            })
 1214            .detach();
 1215        language_server
 1216            .on_notification::<lsp::notification::ShowMessage, _>({
 1217                let this = lsp_store.clone();
 1218                let name = name.to_string();
 1219                move |params, cx| {
 1220                    let this = this.clone();
 1221                    let name = name.to_string();
 1222                    let mut cx = cx.clone();
 1223
 1224                    let (tx, _) = smol::channel::bounded(1);
 1225                    let level = match params.typ {
 1226                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1227                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1228                        _ => PromptLevel::Info,
 1229                    };
 1230                    let request =
 1231                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1232
 1233                    let _ = this.update(&mut cx, |_, cx| {
 1234                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1235                    });
 1236                }
 1237            })
 1238            .detach();
 1239
 1240        let disk_based_diagnostics_progress_token =
 1241            adapter.disk_based_diagnostics_progress_token.clone();
 1242
 1243        language_server
 1244            .on_notification::<lsp::notification::Progress, _>({
 1245                let this = lsp_store.clone();
 1246                move |params, cx| {
 1247                    if let Some(this) = this.upgrade() {
 1248                        this.update(cx, |this, cx| {
 1249                            this.on_lsp_progress(
 1250                                params,
 1251                                server_id,
 1252                                disk_based_diagnostics_progress_token.clone(),
 1253                                cx,
 1254                            );
 1255                        });
 1256                    }
 1257                }
 1258            })
 1259            .detach();
 1260
 1261        language_server
 1262            .on_notification::<lsp::notification::LogMessage, _>({
 1263                let this = lsp_store.clone();
 1264                move |params, cx| {
 1265                    if let Some(this) = this.upgrade() {
 1266                        this.update(cx, |_, cx| {
 1267                            cx.emit(LspStoreEvent::LanguageServerLog(
 1268                                server_id,
 1269                                LanguageServerLogType::Log(params.typ),
 1270                                params.message,
 1271                            ));
 1272                        });
 1273                    }
 1274                }
 1275            })
 1276            .detach();
 1277
 1278        language_server
 1279            .on_notification::<lsp::notification::LogTrace, _>({
 1280                let this = lsp_store.clone();
 1281                move |params, cx| {
 1282                    let mut cx = cx.clone();
 1283                    if let Some(this) = this.upgrade() {
 1284                        this.update(&mut cx, |_, cx| {
 1285                            cx.emit(LspStoreEvent::LanguageServerLog(
 1286                                server_id,
 1287                                LanguageServerLogType::Trace {
 1288                                    verbose_info: params.verbose,
 1289                                },
 1290                                params.message,
 1291                            ));
 1292                        });
 1293                    }
 1294                }
 1295            })
 1296            .detach();
 1297
 1298        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1299        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1300        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1301        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1302    }
 1303
 1304    fn shutdown_language_servers_on_quit(&mut self) -> impl Future<Output = ()> + use<> {
 1305        let shutdown_futures = self
 1306            .language_servers
 1307            .drain()
 1308            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1309            .collect::<Vec<_>>();
 1310
 1311        async move {
 1312            join_all(shutdown_futures).await;
 1313        }
 1314    }
 1315
 1316    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1317        match server_state {
 1318            LanguageServerState::Running { server, .. } => {
 1319                if let Some(shutdown) = server.shutdown() {
 1320                    shutdown.await;
 1321                }
 1322            }
 1323            LanguageServerState::Starting { startup, .. } => {
 1324                if let Some(server) = startup.await
 1325                    && let Some(shutdown) = server.shutdown()
 1326                {
 1327                    shutdown.await;
 1328                }
 1329            }
 1330        }
 1331        Ok(())
 1332    }
 1333
 1334    fn language_servers_for_worktree(
 1335        &self,
 1336        worktree_id: WorktreeId,
 1337    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1338        self.language_server_ids
 1339            .iter()
 1340            .filter_map(move |(seed, state)| {
 1341                if seed.worktree_id != worktree_id {
 1342                    return None;
 1343                }
 1344
 1345                if let Some(LanguageServerState::Running { server, .. }) =
 1346                    self.language_servers.get(&state.id)
 1347                {
 1348                    Some(server)
 1349                } else {
 1350                    None
 1351                }
 1352            })
 1353    }
 1354
 1355    fn language_server_ids_for_project_path(
 1356        &self,
 1357        project_path: ProjectPath,
 1358        language: &Language,
 1359        cx: &mut App,
 1360    ) -> Vec<LanguageServerId> {
 1361        let Some(worktree) = self
 1362            .worktree_store
 1363            .read(cx)
 1364            .worktree_for_id(project_path.worktree_id, cx)
 1365        else {
 1366            return Vec::new();
 1367        };
 1368        let delegate: Arc<dyn ManifestDelegate> =
 1369            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1370
 1371        self.lsp_tree
 1372            .get(
 1373                project_path,
 1374                language.name(),
 1375                language.manifest(),
 1376                &delegate,
 1377                cx,
 1378            )
 1379            .collect::<Vec<_>>()
 1380    }
 1381
 1382    fn language_server_ids_for_buffer(
 1383        &self,
 1384        buffer: &Buffer,
 1385        cx: &mut App,
 1386    ) -> Vec<LanguageServerId> {
 1387        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1388            let worktree_id = file.worktree_id(cx);
 1389
 1390            let path: Arc<RelPath> = file
 1391                .path()
 1392                .parent()
 1393                .map(Arc::from)
 1394                .unwrap_or_else(|| file.path().clone());
 1395            let worktree_path = ProjectPath { worktree_id, path };
 1396            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1397        } else {
 1398            Vec::new()
 1399        }
 1400    }
 1401
 1402    fn language_servers_for_buffer<'a>(
 1403        &'a self,
 1404        buffer: &'a Buffer,
 1405        cx: &'a mut App,
 1406    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1407        self.language_server_ids_for_buffer(buffer, cx)
 1408            .into_iter()
 1409            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1410                LanguageServerState::Running {
 1411                    adapter, server, ..
 1412                } => Some((adapter, server)),
 1413                _ => None,
 1414            })
 1415    }
 1416
 1417    async fn execute_code_action_kind_locally(
 1418        lsp_store: WeakEntity<LspStore>,
 1419        mut buffers: Vec<Entity<Buffer>>,
 1420        kind: CodeActionKind,
 1421        push_to_history: bool,
 1422        cx: &mut AsyncApp,
 1423    ) -> anyhow::Result<ProjectTransaction> {
 1424        // Do not allow multiple concurrent code actions requests for the
 1425        // same buffer.
 1426        lsp_store.update(cx, |this, cx| {
 1427            let this = this.as_local_mut().unwrap();
 1428            buffers.retain(|buffer| {
 1429                this.buffers_being_formatted
 1430                    .insert(buffer.read(cx).remote_id())
 1431            });
 1432        })?;
 1433        let _cleanup = defer({
 1434            let this = lsp_store.clone();
 1435            let mut cx = cx.clone();
 1436            let buffers = &buffers;
 1437            move || {
 1438                this.update(&mut cx, |this, cx| {
 1439                    let this = this.as_local_mut().unwrap();
 1440                    for buffer in buffers {
 1441                        this.buffers_being_formatted
 1442                            .remove(&buffer.read(cx).remote_id());
 1443                    }
 1444                })
 1445                .ok();
 1446            }
 1447        });
 1448        let mut project_transaction = ProjectTransaction::default();
 1449
 1450        for buffer in &buffers {
 1451            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1452                buffer.update(cx, |buffer, cx| {
 1453                    lsp_store
 1454                        .as_local()
 1455                        .unwrap()
 1456                        .language_servers_for_buffer(buffer, cx)
 1457                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1458                        .collect::<Vec<_>>()
 1459                })
 1460            })?;
 1461            for (_, language_server) in adapters_and_servers.iter() {
 1462                let actions = Self::get_server_code_actions_from_action_kinds(
 1463                    &lsp_store,
 1464                    language_server.server_id(),
 1465                    vec![kind.clone()],
 1466                    buffer,
 1467                    cx,
 1468                )
 1469                .await?;
 1470                Self::execute_code_actions_on_server(
 1471                    &lsp_store,
 1472                    language_server,
 1473                    actions,
 1474                    push_to_history,
 1475                    &mut project_transaction,
 1476                    cx,
 1477                )
 1478                .await?;
 1479            }
 1480        }
 1481        Ok(project_transaction)
 1482    }
 1483
 1484    async fn format_locally(
 1485        lsp_store: WeakEntity<LspStore>,
 1486        mut buffers: Vec<FormattableBuffer>,
 1487        push_to_history: bool,
 1488        trigger: FormatTrigger,
 1489        logger: zlog::Logger,
 1490        cx: &mut AsyncApp,
 1491    ) -> anyhow::Result<ProjectTransaction> {
 1492        // Do not allow multiple concurrent formatting requests for the
 1493        // same buffer.
 1494        lsp_store.update(cx, |this, cx| {
 1495            let this = this.as_local_mut().unwrap();
 1496            buffers.retain(|buffer| {
 1497                this.buffers_being_formatted
 1498                    .insert(buffer.handle.read(cx).remote_id())
 1499            });
 1500        })?;
 1501
 1502        let _cleanup = defer({
 1503            let this = lsp_store.clone();
 1504            let mut cx = cx.clone();
 1505            let buffers = &buffers;
 1506            move || {
 1507                this.update(&mut cx, |this, cx| {
 1508                    let this = this.as_local_mut().unwrap();
 1509                    for buffer in buffers {
 1510                        this.buffers_being_formatted
 1511                            .remove(&buffer.handle.read(cx).remote_id());
 1512                    }
 1513                })
 1514                .ok();
 1515            }
 1516        });
 1517
 1518        let mut project_transaction = ProjectTransaction::default();
 1519
 1520        for buffer in &buffers {
 1521            zlog::debug!(
 1522                logger =>
 1523                "formatting buffer '{:?}'",
 1524                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1525            );
 1526            // Create an empty transaction to hold all of the formatting edits.
 1527            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1528                // ensure no transactions created while formatting are
 1529                // grouped with the previous transaction in the history
 1530                // based on the transaction group interval
 1531                buffer.finalize_last_transaction();
 1532                buffer
 1533                    .start_transaction()
 1534                    .context("transaction already open")?;
 1535                buffer.end_transaction(cx);
 1536                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1537                buffer.finalize_last_transaction();
 1538                anyhow::Ok(transaction_id)
 1539            })?;
 1540
 1541            let result = Self::format_buffer_locally(
 1542                lsp_store.clone(),
 1543                buffer,
 1544                formatting_transaction_id,
 1545                trigger,
 1546                logger,
 1547                cx,
 1548            )
 1549            .await;
 1550
 1551            buffer.handle.update(cx, |buffer, cx| {
 1552                let Some(formatting_transaction) =
 1553                    buffer.get_transaction(formatting_transaction_id).cloned()
 1554                else {
 1555                    zlog::warn!(logger => "no formatting transaction");
 1556                    return;
 1557                };
 1558                if formatting_transaction.edit_ids.is_empty() {
 1559                    zlog::debug!(logger => "no changes made while formatting");
 1560                    buffer.forget_transaction(formatting_transaction_id);
 1561                    return;
 1562                }
 1563                if !push_to_history {
 1564                    zlog::trace!(logger => "forgetting format transaction");
 1565                    buffer.forget_transaction(formatting_transaction.id);
 1566                }
 1567                project_transaction
 1568                    .0
 1569                    .insert(cx.entity(), formatting_transaction);
 1570            });
 1571
 1572            result?;
 1573        }
 1574
 1575        Ok(project_transaction)
 1576    }
 1577
 1578    async fn format_buffer_locally(
 1579        lsp_store: WeakEntity<LspStore>,
 1580        buffer: &FormattableBuffer,
 1581        formatting_transaction_id: clock::Lamport,
 1582        trigger: FormatTrigger,
 1583        logger: zlog::Logger,
 1584        cx: &mut AsyncApp,
 1585    ) -> Result<()> {
 1586        let (adapters_and_servers, settings, request_timeout) =
 1587            lsp_store.update(cx, |lsp_store, cx| {
 1588                buffer.handle.update(cx, |buffer, cx| {
 1589                    let adapters_and_servers = lsp_store
 1590                        .as_local()
 1591                        .unwrap()
 1592                        .language_servers_for_buffer(buffer, cx)
 1593                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1594                        .collect::<Vec<_>>();
 1595                    let settings = LanguageSettings::for_buffer(buffer, cx).into_owned();
 1596                    let request_timeout = ProjectSettings::get_global(cx)
 1597                        .global_lsp_settings
 1598                        .get_request_timeout();
 1599                    (adapters_and_servers, settings, request_timeout)
 1600                })
 1601            })?;
 1602
 1603        // handle whitespace formatting
 1604        if settings.remove_trailing_whitespace_on_save {
 1605            zlog::trace!(logger => "removing trailing whitespace");
 1606            let diff = buffer
 1607                .handle
 1608                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1609                .await;
 1610            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1611                buffer.apply_diff(diff, cx);
 1612            })?;
 1613        }
 1614
 1615        if settings.ensure_final_newline_on_save {
 1616            zlog::trace!(logger => "ensuring final newline");
 1617            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1618                buffer.ensure_final_newline(cx);
 1619            })?;
 1620        }
 1621
 1622        // Formatter for `code_actions_on_format` that runs before
 1623        // the rest of the formatters
 1624        let mut code_actions_on_format_formatters = None;
 1625        let should_run_code_actions_on_format = !matches!(
 1626            (trigger, &settings.format_on_save),
 1627            (FormatTrigger::Save, &FormatOnSave::Off)
 1628        );
 1629        if should_run_code_actions_on_format {
 1630            let have_code_actions_to_run_on_format = settings
 1631                .code_actions_on_format
 1632                .values()
 1633                .any(|enabled| *enabled);
 1634            if have_code_actions_to_run_on_format {
 1635                zlog::trace!(logger => "going to run code actions on format");
 1636                code_actions_on_format_formatters = Some(
 1637                    settings
 1638                        .code_actions_on_format
 1639                        .iter()
 1640                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1641                        .cloned()
 1642                        .map(Formatter::CodeAction)
 1643                        .collect::<Vec<_>>(),
 1644                );
 1645            }
 1646        }
 1647
 1648        let formatters = match (trigger, &settings.format_on_save) {
 1649            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1650            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1651                settings.formatter.as_ref()
 1652            }
 1653        };
 1654
 1655        let formatters = code_actions_on_format_formatters
 1656            .iter()
 1657            .flatten()
 1658            .chain(formatters);
 1659
 1660        for formatter in formatters {
 1661            let formatter = if formatter == &Formatter::Auto {
 1662                if settings.prettier.allowed {
 1663                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1664                    &Formatter::Prettier
 1665                } else {
 1666                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1667                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1668                }
 1669            } else {
 1670                formatter
 1671            };
 1672            if let Err(err) = Self::apply_formatter(
 1673                formatter,
 1674                &lsp_store,
 1675                buffer,
 1676                formatting_transaction_id,
 1677                &adapters_and_servers,
 1678                &settings,
 1679                request_timeout,
 1680                logger,
 1681                cx,
 1682            )
 1683            .await
 1684            {
 1685                zlog::error!(logger => "Formatter failed, skipping: {err:#}");
 1686            }
 1687        }
 1688
 1689        Ok(())
 1690    }
 1691
 1692    async fn apply_formatter(
 1693        formatter: &Formatter,
 1694        lsp_store: &WeakEntity<LspStore>,
 1695        buffer: &FormattableBuffer,
 1696        formatting_transaction_id: clock::Lamport,
 1697        adapters_and_servers: &[(Arc<CachedLspAdapter>, Arc<LanguageServer>)],
 1698        settings: &LanguageSettings,
 1699        request_timeout: Duration,
 1700        logger: zlog::Logger,
 1701        cx: &mut AsyncApp,
 1702    ) -> anyhow::Result<()> {
 1703        match formatter {
 1704            Formatter::None => {
 1705                zlog::trace!(logger => "skipping formatter 'none'");
 1706                return Ok(());
 1707            }
 1708            Formatter::Auto => {
 1709                debug_panic!("Auto resolved above");
 1710                return Ok(());
 1711            }
 1712            Formatter::Prettier => {
 1713                let logger = zlog::scoped!(logger => "prettier");
 1714                zlog::trace!(logger => "formatting");
 1715                let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1716
 1717                let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1718                    lsp_store.prettier_store().unwrap().downgrade()
 1719                })?;
 1720                let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1721                    .await
 1722                    .transpose()?;
 1723                let Some(diff) = diff else {
 1724                    zlog::trace!(logger => "No changes");
 1725                    return Ok(());
 1726                };
 1727
 1728                extend_formatting_transaction(
 1729                    buffer,
 1730                    formatting_transaction_id,
 1731                    cx,
 1732                    |buffer, cx| {
 1733                        buffer.apply_diff(diff, cx);
 1734                    },
 1735                )?;
 1736            }
 1737            Formatter::External { command, arguments } => {
 1738                let logger = zlog::scoped!(logger => "command");
 1739                zlog::trace!(logger => "formatting");
 1740                let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1741
 1742                let diff =
 1743                    Self::format_via_external_command(buffer, &command, arguments.as_deref(), cx)
 1744                        .await
 1745                        .with_context(|| {
 1746                            format!("Failed to format buffer via external command: {}", command)
 1747                        })?;
 1748                let Some(diff) = diff else {
 1749                    zlog::trace!(logger => "No changes");
 1750                    return Ok(());
 1751                };
 1752
 1753                extend_formatting_transaction(
 1754                    buffer,
 1755                    formatting_transaction_id,
 1756                    cx,
 1757                    |buffer, cx| {
 1758                        buffer.apply_diff(diff, cx);
 1759                    },
 1760                )?;
 1761            }
 1762            Formatter::LanguageServer(specifier) => {
 1763                let logger = zlog::scoped!(logger => "language-server");
 1764                zlog::trace!(logger => "formatting");
 1765                let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1766
 1767                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1768                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1769                    return Ok(());
 1770                };
 1771
 1772                let language_server = match specifier {
 1773                    settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1774                        adapters_and_servers.iter().find_map(|(adapter, server)| {
 1775                            if adapter.name.0.as_ref() == name {
 1776                                Some(server.clone())
 1777                            } else {
 1778                                None
 1779                            }
 1780                        })
 1781                    }
 1782                    settings::LanguageServerFormatterSpecifier::Current => adapters_and_servers
 1783                        .iter()
 1784                        .find(|(_, server)| Self::server_supports_formatting(server))
 1785                        .map(|(_, server)| server.clone()),
 1786                };
 1787
 1788                let Some(language_server) = language_server else {
 1789                    log::debug!(
 1790                        "No language server found to format buffer '{:?}'. Skipping",
 1791                        buffer_path_abs.as_path().to_string_lossy()
 1792                    );
 1793                    return Ok(());
 1794                };
 1795
 1796                zlog::trace!(
 1797                    logger =>
 1798                    "Formatting buffer '{:?}' using language server '{:?}'",
 1799                    buffer_path_abs.as_path().to_string_lossy(),
 1800                    language_server.name()
 1801                );
 1802
 1803                let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1804                    zlog::trace!(logger => "formatting ranges");
 1805                    Self::format_ranges_via_lsp(
 1806                        &lsp_store,
 1807                        &buffer.handle,
 1808                        ranges,
 1809                        buffer_path_abs,
 1810                        &language_server,
 1811                        &settings,
 1812                        cx,
 1813                    )
 1814                    .await
 1815                    .context("Failed to format ranges via language server")?
 1816                } else {
 1817                    zlog::trace!(logger => "formatting full");
 1818                    Self::format_via_lsp(
 1819                        &lsp_store,
 1820                        &buffer.handle,
 1821                        buffer_path_abs,
 1822                        &language_server,
 1823                        &settings,
 1824                        cx,
 1825                    )
 1826                    .await
 1827                    .context("failed to format via language server")?
 1828                };
 1829
 1830                if edits.is_empty() {
 1831                    zlog::trace!(logger => "No changes");
 1832                    return Ok(());
 1833                }
 1834                extend_formatting_transaction(
 1835                    buffer,
 1836                    formatting_transaction_id,
 1837                    cx,
 1838                    |buffer, cx| {
 1839                        buffer.edit(edits, None, cx);
 1840                    },
 1841                )?;
 1842            }
 1843            Formatter::CodeAction(code_action_name) => {
 1844                let logger = zlog::scoped!(logger => "code-actions");
 1845                zlog::trace!(logger => "formatting");
 1846                let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1847
 1848                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1849                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1850                    return Ok(());
 1851                };
 1852
 1853                let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1854                zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1855
 1856                let mut actions_and_servers = Vec::new();
 1857
 1858                for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1859                    let actions_result = Self::get_server_code_actions_from_action_kinds(
 1860                        &lsp_store,
 1861                        language_server.server_id(),
 1862                        vec![code_action_kind.clone()],
 1863                        &buffer.handle,
 1864                        cx,
 1865                    )
 1866                    .await
 1867                    .with_context(|| {
 1868                        format!(
 1869                            "Failed to resolve code action {:?} with language server {}",
 1870                            code_action_kind,
 1871                            language_server.name()
 1872                        )
 1873                    });
 1874                    let Ok(actions) = actions_result else {
 1875                        // note: it may be better to set result to the error and break formatters here
 1876                        // but for now we try to execute the actions that we can resolve and skip the rest
 1877                        zlog::error!(
 1878                            logger =>
 1879                            "Failed to resolve code action {:?} with language server {}",
 1880                            code_action_kind,
 1881                            language_server.name()
 1882                        );
 1883                        continue;
 1884                    };
 1885                    for action in actions {
 1886                        actions_and_servers.push((action, index));
 1887                    }
 1888                }
 1889
 1890                if actions_and_servers.is_empty() {
 1891                    zlog::warn!(logger => "No code actions were resolved, continuing");
 1892                    return Ok(());
 1893                }
 1894
 1895                'actions: for (mut action, server_index) in actions_and_servers {
 1896                    let server = &adapters_and_servers[server_index].1;
 1897
 1898                    let describe_code_action = |action: &CodeAction| {
 1899                        format!(
 1900                            "code action '{}' with title \"{}\" on server {}",
 1901                            action
 1902                                .lsp_action
 1903                                .action_kind()
 1904                                .unwrap_or("unknown".into())
 1905                                .as_str(),
 1906                            action.lsp_action.title(),
 1907                            server.name(),
 1908                        )
 1909                    };
 1910
 1911                    zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1912
 1913                    if let Err(err) =
 1914                        Self::try_resolve_code_action(server, &mut action, request_timeout).await
 1915                    {
 1916                        zlog::error!(
 1917                            logger =>
 1918                            "Failed to resolve {}. Error: {}",
 1919                            describe_code_action(&action),
 1920                            err
 1921                        );
 1922                        continue;
 1923                    }
 1924
 1925                    if let Some(edit) = action.lsp_action.edit().cloned() {
 1926                        // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1927                        // but filters out and logs warnings for code actions that require unreasonably
 1928                        // difficult handling on our part, such as:
 1929                        // - applying edits that call commands
 1930                        //   which can result in arbitrary workspace edits being sent from the server that
 1931                        //   have no way of being tied back to the command that initiated them (i.e. we
 1932                        //   can't know which edits are part of the format request, or if the server is done sending
 1933                        //   actions in response to the command)
 1934                        // - actions that create/delete/modify/rename files other than the one we are formatting
 1935                        //   as we then would need to handle such changes correctly in the local history as well
 1936                        //   as the remote history through the ProjectTransaction
 1937                        // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1938                        // Supporting these actions is not impossible, but not supported as of yet.
 1939                        if edit.changes.is_none() && edit.document_changes.is_none() {
 1940                            zlog::trace!(
 1941                                logger =>
 1942                                "No changes for code action. Skipping {}",
 1943                                describe_code_action(&action),
 1944                            );
 1945                            continue;
 1946                        }
 1947
 1948                        let mut operations = Vec::new();
 1949                        if let Some(document_changes) = edit.document_changes {
 1950                            match document_changes {
 1951                                lsp::DocumentChanges::Edits(edits) => operations.extend(
 1952                                    edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1953                                ),
 1954                                lsp::DocumentChanges::Operations(ops) => operations = ops,
 1955                            }
 1956                        } else if let Some(changes) = edit.changes {
 1957                            operations.extend(changes.into_iter().map(|(uri, edits)| {
 1958                                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1959                                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 1960                                        uri,
 1961                                        version: None,
 1962                                    },
 1963                                    edits: edits.into_iter().map(Edit::Plain).collect(),
 1964                                })
 1965                            }));
 1966                        }
 1967
 1968                        let mut edits = Vec::with_capacity(operations.len());
 1969
 1970                        if operations.is_empty() {
 1971                            zlog::trace!(
 1972                                logger =>
 1973                                "No changes for code action. Skipping {}",
 1974                                describe_code_action(&action),
 1975                            );
 1976                            continue;
 1977                        }
 1978                        for operation in operations {
 1979                            let op = match operation {
 1980                                lsp::DocumentChangeOperation::Edit(op) => op,
 1981                                lsp::DocumentChangeOperation::Op(_) => {
 1982                                    zlog::warn!(
 1983                                        logger =>
 1984                                        "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1985                                        describe_code_action(&action),
 1986                                    );
 1987                                    continue 'actions;
 1988                                }
 1989                            };
 1990                            let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1991                                zlog::warn!(
 1992                                    logger =>
 1993                                    "Failed to convert URI '{:?}' to file path. Skipping {}",
 1994                                    &op.text_document.uri,
 1995                                    describe_code_action(&action),
 1996                                );
 1997                                continue 'actions;
 1998                            };
 1999                            if &file_path != buffer_path_abs {
 2000                                zlog::warn!(
 2001                                    logger =>
 2002                                    "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 2003                                    file_path,
 2004                                    buffer_path_abs,
 2005                                    describe_code_action(&action),
 2006                                );
 2007                                continue 'actions;
 2008                            }
 2009
 2010                            let mut lsp_edits = Vec::new();
 2011                            for edit in op.edits {
 2012                                match edit {
 2013                                    Edit::Plain(edit) => {
 2014                                        if !lsp_edits.contains(&edit) {
 2015                                            lsp_edits.push(edit);
 2016                                        }
 2017                                    }
 2018                                    Edit::Annotated(edit) => {
 2019                                        if !lsp_edits.contains(&edit.text_edit) {
 2020                                            lsp_edits.push(edit.text_edit);
 2021                                        }
 2022                                    }
 2023                                    Edit::Snippet(_) => {
 2024                                        zlog::warn!(
 2025                                            logger =>
 2026                                            "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 2027                                            describe_code_action(&action),
 2028                                        );
 2029                                        continue 'actions;
 2030                                    }
 2031                                }
 2032                            }
 2033                            let edits_result = lsp_store
 2034                                .update(cx, |lsp_store, cx| {
 2035                                    lsp_store.as_local_mut().unwrap().edits_from_lsp(
 2036                                        &buffer.handle,
 2037                                        lsp_edits,
 2038                                        server.server_id(),
 2039                                        op.text_document.version,
 2040                                        cx,
 2041                                    )
 2042                                })?
 2043                                .await;
 2044                            let Ok(resolved_edits) = edits_result else {
 2045                                zlog::warn!(
 2046                                    logger =>
 2047                                    "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 2048                                    buffer_path_abs.as_path(),
 2049                                    describe_code_action(&action),
 2050                                );
 2051                                continue 'actions;
 2052                            };
 2053                            edits.extend(resolved_edits);
 2054                        }
 2055
 2056                        if edits.is_empty() {
 2057                            zlog::warn!(logger => "No edits resolved from LSP");
 2058                            continue;
 2059                        }
 2060
 2061                        extend_formatting_transaction(
 2062                            buffer,
 2063                            formatting_transaction_id,
 2064                            cx,
 2065                            |buffer, cx| {
 2066                                zlog::info!(
 2067                                    "Applying edits {edits:?}. Content: {:?}",
 2068                                    buffer.text()
 2069                                );
 2070                                buffer.edit(edits, None, cx);
 2071                                zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 2072                            },
 2073                        )?;
 2074                    }
 2075
 2076                    let Some(command) = action.lsp_action.command() else {
 2077                        continue;
 2078                    };
 2079
 2080                    zlog::warn!(
 2081                        logger =>
 2082                        "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 2083                        &command.command,
 2084                    );
 2085
 2086                    let server_capabilities = server.capabilities();
 2087                    let available_commands = server_capabilities
 2088                        .execute_command_provider
 2089                        .as_ref()
 2090                        .map(|options| options.commands.as_slice())
 2091                        .unwrap_or_default();
 2092                    if !available_commands.contains(&command.command) {
 2093                        zlog::warn!(
 2094                            logger =>
 2095                            "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2096                            command.command,
 2097                            server.name(),
 2098                        );
 2099                        continue;
 2100                    }
 2101
 2102                    extend_formatting_transaction(
 2103                        buffer,
 2104                        formatting_transaction_id,
 2105                        cx,
 2106                        |_, _| {},
 2107                    )?;
 2108                    zlog::info!(logger => "Executing command {}", &command.command);
 2109
 2110                    lsp_store.update(cx, |this, _| {
 2111                        this.as_local_mut()
 2112                            .unwrap()
 2113                            .last_workspace_edits_by_language_server
 2114                            .remove(&server.server_id());
 2115                    })?;
 2116
 2117                    let execute_command_result = server
 2118                        .request::<lsp::request::ExecuteCommand>(
 2119                            lsp::ExecuteCommandParams {
 2120                                command: command.command.clone(),
 2121                                arguments: command.arguments.clone().unwrap_or_default(),
 2122                                ..Default::default()
 2123                            },
 2124                            request_timeout,
 2125                        )
 2126                        .await
 2127                        .into_response();
 2128
 2129                    if execute_command_result.is_err() {
 2130                        zlog::error!(
 2131                            logger =>
 2132                            "Failed to execute command '{}' as part of {}",
 2133                            &command.command,
 2134                            describe_code_action(&action),
 2135                        );
 2136                        continue 'actions;
 2137                    }
 2138
 2139                    let mut project_transaction_command = lsp_store.update(cx, |this, _| {
 2140                        this.as_local_mut()
 2141                            .unwrap()
 2142                            .last_workspace_edits_by_language_server
 2143                            .remove(&server.server_id())
 2144                            .unwrap_or_default()
 2145                    })?;
 2146
 2147                    if let Some(transaction) = project_transaction_command.0.remove(&buffer.handle)
 2148                    {
 2149                        zlog::trace!(
 2150                            logger =>
 2151                            "Successfully captured {} edits that resulted from command {}",
 2152                            transaction.edit_ids.len(),
 2153                            &command.command,
 2154                        );
 2155                        let transaction_id_project_transaction = transaction.id;
 2156                        buffer.handle.update(cx, |buffer, _| {
 2157                            // it may have been removed from history if push_to_history was
 2158                            // false in deserialize_workspace_edit. If so push it so we
 2159                            // can merge it with the format transaction
 2160                            // and pop the combined transaction off the history stack
 2161                            // later if push_to_history is false
 2162                            if buffer.get_transaction(transaction.id).is_none() {
 2163                                buffer.push_transaction(transaction, Instant::now());
 2164                            }
 2165                            buffer.merge_transactions(
 2166                                transaction_id_project_transaction,
 2167                                formatting_transaction_id,
 2168                            );
 2169                        });
 2170                    }
 2171
 2172                    if project_transaction_command.0.is_empty() {
 2173                        continue;
 2174                    }
 2175
 2176                    let mut extra_buffers = String::new();
 2177                    for buffer in project_transaction_command.0.keys() {
 2178                        buffer.read_with(cx, |b, cx| {
 2179                            let Some(path) = b.project_path(cx) else {
 2180                                return;
 2181                            };
 2182
 2183                            if !extra_buffers.is_empty() {
 2184                                extra_buffers.push_str(", ");
 2185                            }
 2186                            extra_buffers.push_str(path.path.as_unix_str());
 2187                        });
 2188                    }
 2189                    zlog::warn!(
 2190                        logger =>
 2191                        "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2192                        &command.command,
 2193                        extra_buffers,
 2194                    );
 2195                    // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2196                    // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2197                    // add it so it's included, and merge it into the format transaction when its created later
 2198                }
 2199            }
 2200        }
 2201
 2202        Ok(())
 2203    }
 2204
 2205    pub async fn format_ranges_via_lsp(
 2206        this: &WeakEntity<LspStore>,
 2207        buffer_handle: &Entity<Buffer>,
 2208        ranges: &[Range<Anchor>],
 2209        abs_path: &Path,
 2210        language_server: &Arc<LanguageServer>,
 2211        settings: &LanguageSettings,
 2212        cx: &mut AsyncApp,
 2213    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2214        let capabilities = &language_server.capabilities();
 2215        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2216        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2217            anyhow::bail!(
 2218                "{} language server does not support range formatting",
 2219                language_server.name()
 2220            );
 2221        }
 2222
 2223        let uri = file_path_to_lsp_url(abs_path)?;
 2224        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2225
 2226        let request_timeout = cx.update(|app| {
 2227            ProjectSettings::get_global(app)
 2228                .global_lsp_settings
 2229                .get_request_timeout()
 2230        });
 2231        let lsp_edits = {
 2232            let mut lsp_ranges = Vec::new();
 2233            this.update(cx, |_this, cx| {
 2234                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2235                // not have been sent to the language server. This seems like a fairly systemic
 2236                // issue, though, the resolution probably is not specific to formatting.
 2237                //
 2238                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2239                // LSP.
 2240                let snapshot = buffer_handle.read(cx).snapshot();
 2241                for range in ranges {
 2242                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2243                }
 2244                anyhow::Ok(())
 2245            })??;
 2246
 2247            let mut edits = None;
 2248            for range in lsp_ranges {
 2249                if let Some(mut edit) = language_server
 2250                    .request::<lsp::request::RangeFormatting>(
 2251                        lsp::DocumentRangeFormattingParams {
 2252                            text_document: text_document.clone(),
 2253                            range,
 2254                            options: lsp_command::lsp_formatting_options(settings),
 2255                            work_done_progress_params: Default::default(),
 2256                        },
 2257                        request_timeout,
 2258                    )
 2259                    .await
 2260                    .into_response()?
 2261                {
 2262                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2263                }
 2264            }
 2265            edits
 2266        };
 2267
 2268        if let Some(lsp_edits) = lsp_edits {
 2269            this.update(cx, |this, cx| {
 2270                this.as_local_mut().unwrap().edits_from_lsp(
 2271                    buffer_handle,
 2272                    lsp_edits,
 2273                    language_server.server_id(),
 2274                    None,
 2275                    cx,
 2276                )
 2277            })?
 2278            .await
 2279        } else {
 2280            Ok(Vec::with_capacity(0))
 2281        }
 2282    }
 2283
 2284    fn server_supports_formatting(server: &Arc<LanguageServer>) -> bool {
 2285        let capabilities = server.capabilities();
 2286        let formatting = capabilities.document_formatting_provider.as_ref();
 2287        let range_formatting = capabilities.document_range_formatting_provider.as_ref();
 2288        matches!(formatting, Some(p) if *p != OneOf::Left(false))
 2289            || matches!(range_formatting, Some(p) if *p != OneOf::Left(false))
 2290    }
 2291
 2292    async fn format_via_lsp(
 2293        this: &WeakEntity<LspStore>,
 2294        buffer: &Entity<Buffer>,
 2295        abs_path: &Path,
 2296        language_server: &Arc<LanguageServer>,
 2297        settings: &LanguageSettings,
 2298        cx: &mut AsyncApp,
 2299    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2300        let logger = zlog::scoped!("lsp_format");
 2301        zlog::debug!(logger => "Formatting via LSP");
 2302
 2303        let uri = file_path_to_lsp_url(abs_path)?;
 2304        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2305        let capabilities = &language_server.capabilities();
 2306
 2307        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2308        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2309
 2310        let request_timeout = cx.update(|app| {
 2311            ProjectSettings::get_global(app)
 2312                .global_lsp_settings
 2313                .get_request_timeout()
 2314        });
 2315
 2316        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2317            let _timer = zlog::time!(logger => "format-full");
 2318            language_server
 2319                .request::<lsp::request::Formatting>(
 2320                    lsp::DocumentFormattingParams {
 2321                        text_document,
 2322                        options: lsp_command::lsp_formatting_options(settings),
 2323                        work_done_progress_params: Default::default(),
 2324                    },
 2325                    request_timeout,
 2326                )
 2327                .await
 2328                .into_response()?
 2329        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2330            let _timer = zlog::time!(logger => "format-range");
 2331            let buffer_start = lsp::Position::new(0, 0);
 2332            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2333            language_server
 2334                .request::<lsp::request::RangeFormatting>(
 2335                    lsp::DocumentRangeFormattingParams {
 2336                        text_document: text_document.clone(),
 2337                        range: lsp::Range::new(buffer_start, buffer_end),
 2338                        options: lsp_command::lsp_formatting_options(settings),
 2339                        work_done_progress_params: Default::default(),
 2340                    },
 2341                    request_timeout,
 2342                )
 2343                .await
 2344                .into_response()?
 2345        } else {
 2346            None
 2347        };
 2348
 2349        if let Some(lsp_edits) = lsp_edits {
 2350            this.update(cx, |this, cx| {
 2351                this.as_local_mut().unwrap().edits_from_lsp(
 2352                    buffer,
 2353                    lsp_edits,
 2354                    language_server.server_id(),
 2355                    None,
 2356                    cx,
 2357                )
 2358            })?
 2359            .await
 2360        } else {
 2361            Ok(Vec::with_capacity(0))
 2362        }
 2363    }
 2364
 2365    async fn format_via_external_command(
 2366        buffer: &FormattableBuffer,
 2367        command: &str,
 2368        arguments: Option<&[String]>,
 2369        cx: &mut AsyncApp,
 2370    ) -> Result<Option<Diff>> {
 2371        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2372            let file = File::from_dyn(buffer.file())?;
 2373            let worktree = file.worktree.read(cx);
 2374            let mut worktree_path = worktree.abs_path().to_path_buf();
 2375            if worktree.root_entry()?.is_file() {
 2376                worktree_path.pop();
 2377            }
 2378            Some(worktree_path)
 2379        });
 2380
 2381        use util::command::Stdio;
 2382        let mut child = util::command::new_command(command);
 2383
 2384        if let Some(buffer_env) = buffer.env.as_ref() {
 2385            child.envs(buffer_env);
 2386        }
 2387
 2388        if let Some(working_dir_path) = working_dir_path {
 2389            child.current_dir(working_dir_path);
 2390        }
 2391
 2392        if let Some(arguments) = arguments {
 2393            child.args(arguments.iter().map(|arg| {
 2394                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2395                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2396                } else {
 2397                    arg.replace("{buffer_path}", "Untitled")
 2398                }
 2399            }));
 2400        }
 2401
 2402        let mut child = child
 2403            .stdin(Stdio::piped())
 2404            .stdout(Stdio::piped())
 2405            .stderr(Stdio::piped())
 2406            .spawn()?;
 2407
 2408        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2409        let text = buffer
 2410            .handle
 2411            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2412        for chunk in text.chunks() {
 2413            stdin.write_all(chunk.as_bytes()).await?;
 2414        }
 2415        stdin.flush().await?;
 2416
 2417        let output = child.output().await?;
 2418        anyhow::ensure!(
 2419            output.status.success(),
 2420            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2421            output.status.code(),
 2422            String::from_utf8_lossy(&output.stdout),
 2423            String::from_utf8_lossy(&output.stderr),
 2424        );
 2425
 2426        let stdout = String::from_utf8(output.stdout)?;
 2427        Ok(Some(
 2428            buffer
 2429                .handle
 2430                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2431                .await,
 2432        ))
 2433    }
 2434
 2435    async fn try_resolve_code_action(
 2436        lang_server: &LanguageServer,
 2437        action: &mut CodeAction,
 2438        request_timeout: Duration,
 2439    ) -> anyhow::Result<()> {
 2440        match &mut action.lsp_action {
 2441            LspAction::Action(lsp_action) => {
 2442                if !action.resolved
 2443                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2444                    && lsp_action.data.is_some()
 2445                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2446                {
 2447                    **lsp_action = lang_server
 2448                        .request::<lsp::request::CodeActionResolveRequest>(
 2449                            *lsp_action.clone(),
 2450                            request_timeout,
 2451                        )
 2452                        .await
 2453                        .into_response()?;
 2454                }
 2455            }
 2456            LspAction::CodeLens(lens) => {
 2457                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2458                    *lens = lang_server
 2459                        .request::<lsp::request::CodeLensResolve>(lens.clone(), request_timeout)
 2460                        .await
 2461                        .into_response()?;
 2462                }
 2463            }
 2464            LspAction::Command(_) => {}
 2465        }
 2466
 2467        action.resolved = true;
 2468        anyhow::Ok(())
 2469    }
 2470
 2471    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2472        let buffer = buffer_handle.read(cx);
 2473
 2474        let file = buffer.file().cloned();
 2475
 2476        let Some(file) = File::from_dyn(file.as_ref()) else {
 2477            return;
 2478        };
 2479        if !file.is_local() {
 2480            return;
 2481        }
 2482        let path = ProjectPath::from_file(file, cx);
 2483        let worktree_id = file.worktree_id(cx);
 2484        let language = buffer.language().cloned();
 2485
 2486        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2487            for (server_id, diagnostics) in
 2488                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2489            {
 2490                self.update_buffer_diagnostics(
 2491                    buffer_handle,
 2492                    server_id,
 2493                    None,
 2494                    None,
 2495                    None,
 2496                    Vec::new(),
 2497                    diagnostics,
 2498                    cx,
 2499                )
 2500                .log_err();
 2501            }
 2502        }
 2503        let Some(language) = language else {
 2504            return;
 2505        };
 2506        let Some(snapshot) = self
 2507            .worktree_store
 2508            .read(cx)
 2509            .worktree_for_id(worktree_id, cx)
 2510            .map(|worktree| worktree.read(cx).snapshot())
 2511        else {
 2512            return;
 2513        };
 2514        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2515
 2516        for server_id in
 2517            self.lsp_tree
 2518                .get(path, language.name(), language.manifest(), &delegate, cx)
 2519        {
 2520            let server = self
 2521                .language_servers
 2522                .get(&server_id)
 2523                .and_then(|server_state| {
 2524                    if let LanguageServerState::Running { server, .. } = server_state {
 2525                        Some(server.clone())
 2526                    } else {
 2527                        None
 2528                    }
 2529                });
 2530            let server = match server {
 2531                Some(server) => server,
 2532                None => continue,
 2533            };
 2534
 2535            buffer_handle.update(cx, |buffer, cx| {
 2536                buffer.set_completion_triggers(
 2537                    server.server_id(),
 2538                    server
 2539                        .capabilities()
 2540                        .completion_provider
 2541                        .as_ref()
 2542                        .and_then(|provider| {
 2543                            provider
 2544                                .trigger_characters
 2545                                .as_ref()
 2546                                .map(|characters| characters.iter().cloned().collect())
 2547                        })
 2548                        .unwrap_or_default(),
 2549                    cx,
 2550                );
 2551            });
 2552        }
 2553    }
 2554
 2555    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2556        buffer.update(cx, |buffer, cx| {
 2557            let Some(language) = buffer.language() else {
 2558                return;
 2559            };
 2560            let path = ProjectPath {
 2561                worktree_id: old_file.worktree_id(cx),
 2562                path: old_file.path.clone(),
 2563            };
 2564            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2565                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2566                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2567            }
 2568        });
 2569    }
 2570
 2571    fn update_buffer_diagnostics(
 2572        &mut self,
 2573        buffer: &Entity<Buffer>,
 2574        server_id: LanguageServerId,
 2575        registration_id: Option<Option<SharedString>>,
 2576        result_id: Option<SharedString>,
 2577        version: Option<i32>,
 2578        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2579        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2580        cx: &mut Context<LspStore>,
 2581    ) -> Result<()> {
 2582        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2583            Ordering::Equal
 2584                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2585                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2586                .then_with(|| a.severity.cmp(&b.severity))
 2587                .then_with(|| a.message.cmp(&b.message))
 2588        }
 2589
 2590        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2591        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2592        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2593
 2594        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2595            Ordering::Equal
 2596                .then_with(|| a.range.start.cmp(&b.range.start))
 2597                .then_with(|| b.range.end.cmp(&a.range.end))
 2598                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2599        });
 2600
 2601        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2602
 2603        let edits_since_save = std::cell::LazyCell::new(|| {
 2604            let saved_version = buffer.read(cx).saved_version();
 2605            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2606        });
 2607
 2608        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2609
 2610        for (new_diagnostic, entry) in diagnostics {
 2611            let start;
 2612            let end;
 2613            if new_diagnostic && entry.diagnostic.is_disk_based {
 2614                // Some diagnostics are based on files on disk instead of buffers'
 2615                // current contents. Adjust these diagnostics' ranges to reflect
 2616                // any unsaved edits.
 2617                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2618                // and were properly adjusted on reuse.
 2619                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2620                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2621            } else {
 2622                start = entry.range.start;
 2623                end = entry.range.end;
 2624            }
 2625
 2626            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2627                ..snapshot.clip_point_utf16(end, Bias::Right);
 2628
 2629            // Expand empty ranges by one codepoint
 2630            if range.start == range.end {
 2631                // This will be go to the next boundary when being clipped
 2632                range.end.column += 1;
 2633                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2634                if range.start == range.end && range.end.column > 0 {
 2635                    range.start.column -= 1;
 2636                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2637                }
 2638            }
 2639
 2640            sanitized_diagnostics.push(DiagnosticEntry {
 2641                range,
 2642                diagnostic: entry.diagnostic,
 2643            });
 2644        }
 2645        drop(edits_since_save);
 2646
 2647        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2648        buffer.update(cx, |buffer, cx| {
 2649            if let Some(registration_id) = registration_id {
 2650                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2651                    self.buffer_pull_diagnostics_result_ids
 2652                        .entry(server_id)
 2653                        .or_default()
 2654                        .entry(registration_id)
 2655                        .or_default()
 2656                        .insert(abs_path, result_id);
 2657                }
 2658            }
 2659
 2660            buffer.update_diagnostics(server_id, set, cx)
 2661        });
 2662
 2663        Ok(())
 2664    }
 2665
 2666    fn register_language_server_for_invisible_worktree(
 2667        &mut self,
 2668        worktree: &Entity<Worktree>,
 2669        language_server_id: LanguageServerId,
 2670        cx: &mut App,
 2671    ) {
 2672        let worktree = worktree.read(cx);
 2673        let worktree_id = worktree.id();
 2674        debug_assert!(!worktree.is_visible());
 2675        let Some(mut origin_seed) = self
 2676            .language_server_ids
 2677            .iter()
 2678            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2679        else {
 2680            return;
 2681        };
 2682        origin_seed.worktree_id = worktree_id;
 2683        self.language_server_ids
 2684            .entry(origin_seed)
 2685            .or_insert_with(|| UnifiedLanguageServer {
 2686                id: language_server_id,
 2687                project_roots: Default::default(),
 2688            });
 2689    }
 2690
 2691    fn register_buffer_with_language_servers(
 2692        &mut self,
 2693        buffer_handle: &Entity<Buffer>,
 2694        only_register_servers: HashSet<LanguageServerSelector>,
 2695        cx: &mut Context<LspStore>,
 2696    ) {
 2697        let buffer = buffer_handle.read(cx);
 2698        let buffer_id = buffer.remote_id();
 2699
 2700        let Some(file) = File::from_dyn(buffer.file()) else {
 2701            return;
 2702        };
 2703        if !file.is_local() {
 2704            return;
 2705        }
 2706
 2707        let abs_path = file.abs_path(cx);
 2708        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2709            return;
 2710        };
 2711        let initial_snapshot = buffer.text_snapshot();
 2712        let worktree_id = file.worktree_id(cx);
 2713
 2714        let Some(language) = buffer.language().cloned() else {
 2715            return;
 2716        };
 2717        let path: Arc<RelPath> = file
 2718            .path()
 2719            .parent()
 2720            .map(Arc::from)
 2721            .unwrap_or_else(|| file.path().clone());
 2722        let Some(worktree) = self
 2723            .worktree_store
 2724            .read(cx)
 2725            .worktree_for_id(worktree_id, cx)
 2726        else {
 2727            return;
 2728        };
 2729        let language_name = language.name();
 2730        let (reused, delegate, servers) = self
 2731            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2732            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2733            .unwrap_or_else(|| {
 2734                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2735                let delegate: Arc<dyn ManifestDelegate> =
 2736                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2737
 2738                let servers = self
 2739                    .lsp_tree
 2740                    .walk(
 2741                        ProjectPath { worktree_id, path },
 2742                        language.name(),
 2743                        language.manifest(),
 2744                        &delegate,
 2745                        cx,
 2746                    )
 2747                    .collect::<Vec<_>>();
 2748                (false, lsp_delegate, servers)
 2749            });
 2750        let servers_and_adapters = servers
 2751            .into_iter()
 2752            .filter_map(|server_node| {
 2753                if reused && server_node.server_id().is_none() {
 2754                    return None;
 2755                }
 2756                if !only_register_servers.is_empty() {
 2757                    if let Some(server_id) = server_node.server_id()
 2758                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2759                    {
 2760                        return None;
 2761                    }
 2762                    if let Some(name) = server_node.name()
 2763                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2764                    {
 2765                        return None;
 2766                    }
 2767                }
 2768
 2769                let server_id = server_node.server_id_or_init(|disposition| {
 2770                    let path = &disposition.path;
 2771
 2772                    {
 2773                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2774
 2775                        let server_id = self.get_or_insert_language_server(
 2776                            &worktree,
 2777                            delegate.clone(),
 2778                            disposition,
 2779                            &language_name,
 2780                            cx,
 2781                        );
 2782
 2783                        if let Some(state) = self.language_servers.get(&server_id)
 2784                            && let Ok(uri) = uri
 2785                        {
 2786                            state.add_workspace_folder(uri);
 2787                        };
 2788                        server_id
 2789                    }
 2790                })?;
 2791                let server_state = self.language_servers.get(&server_id)?;
 2792                if let LanguageServerState::Running {
 2793                    server, adapter, ..
 2794                } = server_state
 2795                {
 2796                    Some((server.clone(), adapter.clone()))
 2797                } else {
 2798                    None
 2799                }
 2800            })
 2801            .collect::<Vec<_>>();
 2802        for (server, adapter) in servers_and_adapters {
 2803            buffer_handle.update(cx, |buffer, cx| {
 2804                buffer.set_completion_triggers(
 2805                    server.server_id(),
 2806                    server
 2807                        .capabilities()
 2808                        .completion_provider
 2809                        .as_ref()
 2810                        .and_then(|provider| {
 2811                            provider
 2812                                .trigger_characters
 2813                                .as_ref()
 2814                                .map(|characters| characters.iter().cloned().collect())
 2815                        })
 2816                        .unwrap_or_default(),
 2817                    cx,
 2818                );
 2819            });
 2820
 2821            let snapshot = LspBufferSnapshot {
 2822                version: 0,
 2823                snapshot: initial_snapshot.clone(),
 2824            };
 2825
 2826            let mut registered = false;
 2827            self.buffer_snapshots
 2828                .entry(buffer_id)
 2829                .or_default()
 2830                .entry(server.server_id())
 2831                .or_insert_with(|| {
 2832                    registered = true;
 2833                    server.register_buffer(
 2834                        uri.clone(),
 2835                        adapter.language_id(&language.name()),
 2836                        0,
 2837                        initial_snapshot.text(),
 2838                    );
 2839
 2840                    vec![snapshot]
 2841                });
 2842
 2843            self.buffers_opened_in_servers
 2844                .entry(buffer_id)
 2845                .or_default()
 2846                .insert(server.server_id());
 2847            if registered {
 2848                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2849                    language_server_id: server.server_id(),
 2850                    name: None,
 2851                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2852                        proto::RegisteredForBuffer {
 2853                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2854                            buffer_id: buffer_id.to_proto(),
 2855                        },
 2856                    ),
 2857                });
 2858            }
 2859        }
 2860    }
 2861
 2862    fn reuse_existing_language_server<'lang_name>(
 2863        &self,
 2864        server_tree: &LanguageServerTree,
 2865        worktree: &Entity<Worktree>,
 2866        language_name: &'lang_name LanguageName,
 2867        cx: &mut App,
 2868    ) -> Option<(
 2869        Arc<LocalLspAdapterDelegate>,
 2870        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2871    )> {
 2872        if worktree.read(cx).is_visible() {
 2873            return None;
 2874        }
 2875
 2876        let worktree_store = self.worktree_store.read(cx);
 2877        let servers = server_tree
 2878            .instances
 2879            .iter()
 2880            .filter(|(worktree_id, _)| {
 2881                worktree_store
 2882                    .worktree_for_id(**worktree_id, cx)
 2883                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2884            })
 2885            .flat_map(|(worktree_id, servers)| {
 2886                servers
 2887                    .roots
 2888                    .iter()
 2889                    .flat_map(|(_, language_servers)| language_servers)
 2890                    .map(move |(_, (server_node, server_languages))| {
 2891                        (worktree_id, server_node, server_languages)
 2892                    })
 2893                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2894                    .map(|(worktree_id, server_node, _)| {
 2895                        (
 2896                            *worktree_id,
 2897                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2898                        )
 2899                    })
 2900            })
 2901            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2902                acc.entry(worktree_id)
 2903                    .or_insert_with(Vec::new)
 2904                    .push(server_node);
 2905                acc
 2906            })
 2907            .into_values()
 2908            .max_by_key(|servers| servers.len())?;
 2909
 2910        let worktree_id = worktree.read(cx).id();
 2911        let apply = move |tree: &mut LanguageServerTree| {
 2912            for server_node in &servers {
 2913                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2914            }
 2915            servers
 2916        };
 2917
 2918        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2919        Some((delegate, apply))
 2920    }
 2921
 2922    pub(crate) fn unregister_old_buffer_from_language_servers(
 2923        &mut self,
 2924        buffer: &Entity<Buffer>,
 2925        old_file: &File,
 2926        cx: &mut App,
 2927    ) {
 2928        let old_path = match old_file.as_local() {
 2929            Some(local) => local.abs_path(cx),
 2930            None => return,
 2931        };
 2932
 2933        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2934            debug_panic!("{old_path:?} is not parseable as an URI");
 2935            return;
 2936        };
 2937        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2938    }
 2939
 2940    pub(crate) fn unregister_buffer_from_language_servers(
 2941        &mut self,
 2942        buffer: &Entity<Buffer>,
 2943        file_url: &lsp::Uri,
 2944        cx: &mut App,
 2945    ) {
 2946        buffer.update(cx, |buffer, cx| {
 2947            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2948
 2949            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2950                if snapshots
 2951                    .as_mut()
 2952                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2953                {
 2954                    language_server.unregister_buffer(file_url.clone());
 2955                }
 2956            }
 2957        });
 2958    }
 2959
 2960    fn buffer_snapshot_for_lsp_version(
 2961        &mut self,
 2962        buffer: &Entity<Buffer>,
 2963        server_id: LanguageServerId,
 2964        version: Option<i32>,
 2965        cx: &App,
 2966    ) -> Result<TextBufferSnapshot> {
 2967        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2968
 2969        if let Some(version) = version {
 2970            let buffer_id = buffer.read(cx).remote_id();
 2971            let snapshots = if let Some(snapshots) = self
 2972                .buffer_snapshots
 2973                .get_mut(&buffer_id)
 2974                .and_then(|m| m.get_mut(&server_id))
 2975            {
 2976                snapshots
 2977            } else if version == 0 {
 2978                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2979                // We detect this case and treat it as if the version was `None`.
 2980                return Ok(buffer.read(cx).text_snapshot());
 2981            } else {
 2982                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2983            };
 2984
 2985            let found_snapshot = snapshots
 2986                    .binary_search_by_key(&version, |e| e.version)
 2987                    .map(|ix| snapshots[ix].snapshot.clone())
 2988                    .map_err(|_| {
 2989                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2990                    })?;
 2991
 2992            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2993            Ok(found_snapshot)
 2994        } else {
 2995            Ok((buffer.read(cx)).text_snapshot())
 2996        }
 2997    }
 2998
 2999    async fn get_server_code_actions_from_action_kinds(
 3000        lsp_store: &WeakEntity<LspStore>,
 3001        language_server_id: LanguageServerId,
 3002        code_action_kinds: Vec<lsp::CodeActionKind>,
 3003        buffer: &Entity<Buffer>,
 3004        cx: &mut AsyncApp,
 3005    ) -> Result<Vec<CodeAction>> {
 3006        let actions = lsp_store
 3007            .update(cx, move |this, cx| {
 3008                let request = GetCodeActions {
 3009                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 3010                    kinds: Some(code_action_kinds),
 3011                };
 3012                let server = LanguageServerToQuery::Other(language_server_id);
 3013                this.request_lsp(buffer.clone(), server, request, cx)
 3014            })?
 3015            .await?;
 3016        Ok(actions)
 3017    }
 3018
 3019    pub async fn execute_code_actions_on_server(
 3020        lsp_store: &WeakEntity<LspStore>,
 3021        language_server: &Arc<LanguageServer>,
 3022        actions: Vec<CodeAction>,
 3023        push_to_history: bool,
 3024        project_transaction: &mut ProjectTransaction,
 3025        cx: &mut AsyncApp,
 3026    ) -> anyhow::Result<()> {
 3027        let request_timeout = cx.update(|app| {
 3028            ProjectSettings::get_global(app)
 3029                .global_lsp_settings
 3030                .get_request_timeout()
 3031        });
 3032
 3033        for mut action in actions {
 3034            Self::try_resolve_code_action(language_server, &mut action, request_timeout)
 3035                .await
 3036                .context("resolving a formatting code action")?;
 3037
 3038            if let Some(edit) = action.lsp_action.edit() {
 3039                if edit.changes.is_none() && edit.document_changes.is_none() {
 3040                    continue;
 3041                }
 3042
 3043                let new = Self::deserialize_workspace_edit(
 3044                    lsp_store.upgrade().context("project dropped")?,
 3045                    edit.clone(),
 3046                    push_to_history,
 3047                    language_server.clone(),
 3048                    cx,
 3049                )
 3050                .await?;
 3051                project_transaction.0.extend(new.0);
 3052            }
 3053
 3054            let Some(command) = action.lsp_action.command() else {
 3055                continue;
 3056            };
 3057
 3058            let server_capabilities = language_server.capabilities();
 3059            let available_commands = server_capabilities
 3060                .execute_command_provider
 3061                .as_ref()
 3062                .map(|options| options.commands.as_slice())
 3063                .unwrap_or_default();
 3064            if !available_commands.contains(&command.command) {
 3065                log::warn!(
 3066                    "Cannot execute a command {} not listed in the language server capabilities",
 3067                    command.command
 3068                );
 3069                continue;
 3070            }
 3071
 3072            lsp_store.update(cx, |lsp_store, _| {
 3073                if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 3074                    mode.last_workspace_edits_by_language_server
 3075                        .remove(&language_server.server_id());
 3076                }
 3077            })?;
 3078
 3079            language_server
 3080                .request::<lsp::request::ExecuteCommand>(
 3081                    lsp::ExecuteCommandParams {
 3082                        command: command.command.clone(),
 3083                        arguments: command.arguments.clone().unwrap_or_default(),
 3084                        ..Default::default()
 3085                    },
 3086                    request_timeout,
 3087                )
 3088                .await
 3089                .into_response()
 3090                .context("execute command")?;
 3091
 3092            lsp_store.update(cx, |this, _| {
 3093                if let LspStoreMode::Local(mode) = &mut this.mode {
 3094                    project_transaction.0.extend(
 3095                        mode.last_workspace_edits_by_language_server
 3096                            .remove(&language_server.server_id())
 3097                            .unwrap_or_default()
 3098                            .0,
 3099                    )
 3100                }
 3101            })?;
 3102        }
 3103        Ok(())
 3104    }
 3105
 3106    pub async fn deserialize_text_edits(
 3107        this: Entity<LspStore>,
 3108        buffer_to_edit: Entity<Buffer>,
 3109        edits: Vec<lsp::TextEdit>,
 3110        push_to_history: bool,
 3111        _: Arc<CachedLspAdapter>,
 3112        language_server: Arc<LanguageServer>,
 3113        cx: &mut AsyncApp,
 3114    ) -> Result<Option<Transaction>> {
 3115        let edits = this
 3116            .update(cx, |this, cx| {
 3117                this.as_local_mut().unwrap().edits_from_lsp(
 3118                    &buffer_to_edit,
 3119                    edits,
 3120                    language_server.server_id(),
 3121                    None,
 3122                    cx,
 3123                )
 3124            })
 3125            .await?;
 3126
 3127        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3128            buffer.finalize_last_transaction();
 3129            buffer.start_transaction();
 3130            for (range, text) in edits {
 3131                buffer.edit([(range, text)], None, cx);
 3132            }
 3133
 3134            if buffer.end_transaction(cx).is_some() {
 3135                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3136                if !push_to_history {
 3137                    buffer.forget_transaction(transaction.id);
 3138                }
 3139                Some(transaction)
 3140            } else {
 3141                None
 3142            }
 3143        });
 3144
 3145        Ok(transaction)
 3146    }
 3147
 3148    #[allow(clippy::type_complexity)]
 3149    pub fn edits_from_lsp(
 3150        &mut self,
 3151        buffer: &Entity<Buffer>,
 3152        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3153        server_id: LanguageServerId,
 3154        version: Option<i32>,
 3155        cx: &mut Context<LspStore>,
 3156    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3157        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3158        cx.background_spawn(async move {
 3159            let snapshot = snapshot?;
 3160            let mut lsp_edits = lsp_edits
 3161                .into_iter()
 3162                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3163                .collect::<Vec<_>>();
 3164
 3165            lsp_edits.sort_unstable_by_key(|(range, _)| (range.start, range.end));
 3166
 3167            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3168            let mut edits = Vec::new();
 3169            while let Some((range, mut new_text)) = lsp_edits.next() {
 3170                // Clip invalid ranges provided by the language server.
 3171                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3172                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3173
 3174                // Combine any LSP edits that are adjacent.
 3175                //
 3176                // Also, combine LSP edits that are separated from each other by only
 3177                // a newline. This is important because for some code actions,
 3178                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3179                // are separated by unchanged newline characters.
 3180                //
 3181                // In order for the diffing logic below to work properly, any edits that
 3182                // cancel each other out must be combined into one.
 3183                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3184                    if next_range.start.0 > range.end {
 3185                        if next_range.start.0.row > range.end.row + 1
 3186                            || next_range.start.0.column > 0
 3187                            || snapshot.clip_point_utf16(
 3188                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3189                                Bias::Left,
 3190                            ) > range.end
 3191                        {
 3192                            break;
 3193                        }
 3194                        new_text.push('\n');
 3195                    }
 3196                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3197                    new_text.push_str(next_text);
 3198                    lsp_edits.next();
 3199                }
 3200
 3201                // For multiline edits, perform a diff of the old and new text so that
 3202                // we can identify the changes more precisely, preserving the locations
 3203                // of any anchors positioned in the unchanged regions.
 3204                if range.end.row > range.start.row {
 3205                    let offset = range.start.to_offset(&snapshot);
 3206                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3207                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3208                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3209                        (
 3210                            snapshot.anchor_after(offset + range.start)
 3211                                ..snapshot.anchor_before(offset + range.end),
 3212                            replacement,
 3213                        )
 3214                    }));
 3215                } else if range.end == range.start {
 3216                    let anchor = snapshot.anchor_after(range.start);
 3217                    edits.push((anchor..anchor, new_text.into()));
 3218                } else {
 3219                    let edit_start = snapshot.anchor_after(range.start);
 3220                    let edit_end = snapshot.anchor_before(range.end);
 3221                    edits.push((edit_start..edit_end, new_text.into()));
 3222                }
 3223            }
 3224
 3225            Ok(edits)
 3226        })
 3227    }
 3228
 3229    pub(crate) async fn deserialize_workspace_edit(
 3230        this: Entity<LspStore>,
 3231        edit: lsp::WorkspaceEdit,
 3232        push_to_history: bool,
 3233        language_server: Arc<LanguageServer>,
 3234        cx: &mut AsyncApp,
 3235    ) -> Result<ProjectTransaction> {
 3236        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3237
 3238        let mut operations = Vec::new();
 3239        if let Some(document_changes) = edit.document_changes {
 3240            match document_changes {
 3241                lsp::DocumentChanges::Edits(edits) => {
 3242                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3243                }
 3244                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3245            }
 3246        } else if let Some(changes) = edit.changes {
 3247            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3248                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3249                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3250                        uri,
 3251                        version: None,
 3252                    },
 3253                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3254                })
 3255            }));
 3256        }
 3257
 3258        let mut project_transaction = ProjectTransaction::default();
 3259        for operation in operations {
 3260            match operation {
 3261                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3262                    let abs_path = op
 3263                        .uri
 3264                        .to_file_path()
 3265                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3266
 3267                    if let Some(parent_path) = abs_path.parent() {
 3268                        fs.create_dir(parent_path).await?;
 3269                    }
 3270                    if abs_path.ends_with("/") {
 3271                        fs.create_dir(&abs_path).await?;
 3272                    } else {
 3273                        fs.create_file(
 3274                            &abs_path,
 3275                            op.options
 3276                                .map(|options| fs::CreateOptions {
 3277                                    overwrite: options.overwrite.unwrap_or(false),
 3278                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3279                                })
 3280                                .unwrap_or_default(),
 3281                        )
 3282                        .await?;
 3283                    }
 3284                }
 3285
 3286                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3287                    let source_abs_path = op
 3288                        .old_uri
 3289                        .to_file_path()
 3290                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3291                    let target_abs_path = op
 3292                        .new_uri
 3293                        .to_file_path()
 3294                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3295
 3296                    let options = fs::RenameOptions {
 3297                        overwrite: op
 3298                            .options
 3299                            .as_ref()
 3300                            .and_then(|options| options.overwrite)
 3301                            .unwrap_or(false),
 3302                        ignore_if_exists: op
 3303                            .options
 3304                            .as_ref()
 3305                            .and_then(|options| options.ignore_if_exists)
 3306                            .unwrap_or(false),
 3307                        create_parents: true,
 3308                    };
 3309
 3310                    fs.rename(&source_abs_path, &target_abs_path, options)
 3311                        .await?;
 3312                }
 3313
 3314                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3315                    let abs_path = op
 3316                        .uri
 3317                        .to_file_path()
 3318                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3319                    let options = op
 3320                        .options
 3321                        .map(|options| fs::RemoveOptions {
 3322                            recursive: options.recursive.unwrap_or(false),
 3323                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3324                        })
 3325                        .unwrap_or_default();
 3326                    if abs_path.ends_with("/") {
 3327                        fs.remove_dir(&abs_path, options).await?;
 3328                    } else {
 3329                        fs.remove_file(&abs_path, options).await?;
 3330                    }
 3331                }
 3332
 3333                lsp::DocumentChangeOperation::Edit(op) => {
 3334                    let buffer_to_edit = this
 3335                        .update(cx, |this, cx| {
 3336                            this.open_local_buffer_via_lsp(
 3337                                op.text_document.uri.clone(),
 3338                                language_server.server_id(),
 3339                                cx,
 3340                            )
 3341                        })
 3342                        .await?;
 3343
 3344                    let edits = this
 3345                        .update(cx, |this, cx| {
 3346                            let path = buffer_to_edit.read(cx).project_path(cx);
 3347                            let active_entry = this.active_entry;
 3348                            let is_active_entry = path.is_some_and(|project_path| {
 3349                                this.worktree_store
 3350                                    .read(cx)
 3351                                    .entry_for_path(&project_path, cx)
 3352                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3353                            });
 3354                            let local = this.as_local_mut().unwrap();
 3355
 3356                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3357                            for edit in op.edits {
 3358                                match edit {
 3359                                    Edit::Plain(edit) => {
 3360                                        if !edits.contains(&edit) {
 3361                                            edits.push(edit)
 3362                                        }
 3363                                    }
 3364                                    Edit::Annotated(edit) => {
 3365                                        if !edits.contains(&edit.text_edit) {
 3366                                            edits.push(edit.text_edit)
 3367                                        }
 3368                                    }
 3369                                    Edit::Snippet(edit) => {
 3370                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3371                                        else {
 3372                                            continue;
 3373                                        };
 3374
 3375                                        if is_active_entry {
 3376                                            snippet_edits.push((edit.range, snippet));
 3377                                        } else {
 3378                                            // Since this buffer is not focused, apply a normal edit.
 3379                                            let new_edit = TextEdit {
 3380                                                range: edit.range,
 3381                                                new_text: snippet.text,
 3382                                            };
 3383                                            if !edits.contains(&new_edit) {
 3384                                                edits.push(new_edit);
 3385                                            }
 3386                                        }
 3387                                    }
 3388                                }
 3389                            }
 3390                            if !snippet_edits.is_empty() {
 3391                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3392                                let version = if let Some(buffer_version) = op.text_document.version
 3393                                {
 3394                                    local
 3395                                        .buffer_snapshot_for_lsp_version(
 3396                                            &buffer_to_edit,
 3397                                            language_server.server_id(),
 3398                                            Some(buffer_version),
 3399                                            cx,
 3400                                        )
 3401                                        .ok()
 3402                                        .map(|snapshot| snapshot.version)
 3403                                } else {
 3404                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3405                                };
 3406
 3407                                let most_recent_edit =
 3408                                    version.and_then(|version| version.most_recent());
 3409                                // Check if the edit that triggered that edit has been made by this participant.
 3410
 3411                                if let Some(most_recent_edit) = most_recent_edit {
 3412                                    cx.emit(LspStoreEvent::SnippetEdit {
 3413                                        buffer_id,
 3414                                        edits: snippet_edits,
 3415                                        most_recent_edit,
 3416                                    });
 3417                                }
 3418                            }
 3419
 3420                            local.edits_from_lsp(
 3421                                &buffer_to_edit,
 3422                                edits,
 3423                                language_server.server_id(),
 3424                                op.text_document.version,
 3425                                cx,
 3426                            )
 3427                        })
 3428                        .await?;
 3429
 3430                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3431                        buffer.finalize_last_transaction();
 3432                        buffer.start_transaction();
 3433                        for (range, text) in edits {
 3434                            buffer.edit([(range, text)], None, cx);
 3435                        }
 3436
 3437                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3438                            if push_to_history {
 3439                                buffer.finalize_last_transaction();
 3440                                buffer.get_transaction(transaction_id).cloned()
 3441                            } else {
 3442                                buffer.forget_transaction(transaction_id)
 3443                            }
 3444                        })
 3445                    });
 3446                    if let Some(transaction) = transaction {
 3447                        project_transaction.0.insert(buffer_to_edit, transaction);
 3448                    }
 3449                }
 3450            }
 3451        }
 3452
 3453        Ok(project_transaction)
 3454    }
 3455
 3456    async fn on_lsp_workspace_edit(
 3457        this: WeakEntity<LspStore>,
 3458        params: lsp::ApplyWorkspaceEditParams,
 3459        server_id: LanguageServerId,
 3460        cx: &mut AsyncApp,
 3461    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3462        let this = this.upgrade().context("project project closed")?;
 3463        let language_server = this
 3464            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3465            .context("language server not found")?;
 3466        let transaction = Self::deserialize_workspace_edit(
 3467            this.clone(),
 3468            params.edit,
 3469            true,
 3470            language_server.clone(),
 3471            cx,
 3472        )
 3473        .await
 3474        .log_err();
 3475        this.update(cx, |this, cx| {
 3476            if let Some(transaction) = transaction {
 3477                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3478
 3479                this.as_local_mut()
 3480                    .unwrap()
 3481                    .last_workspace_edits_by_language_server
 3482                    .insert(server_id, transaction);
 3483            }
 3484        });
 3485        Ok(lsp::ApplyWorkspaceEditResponse {
 3486            applied: true,
 3487            failed_change: None,
 3488            failure_reason: None,
 3489        })
 3490    }
 3491
 3492    fn remove_worktree(
 3493        &mut self,
 3494        id_to_remove: WorktreeId,
 3495        cx: &mut Context<LspStore>,
 3496    ) -> Vec<LanguageServerId> {
 3497        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3498        self.diagnostics.remove(&id_to_remove);
 3499        self.prettier_store.update(cx, |prettier_store, cx| {
 3500            prettier_store.remove_worktree(id_to_remove, cx);
 3501        });
 3502
 3503        let mut servers_to_remove = BTreeSet::default();
 3504        let mut servers_to_preserve = HashSet::default();
 3505        for (seed, state) in &self.language_server_ids {
 3506            if seed.worktree_id == id_to_remove {
 3507                servers_to_remove.insert(state.id);
 3508            } else {
 3509                servers_to_preserve.insert(state.id);
 3510            }
 3511        }
 3512        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3513        self.language_server_ids
 3514            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3515        for server_id_to_remove in &servers_to_remove {
 3516            self.language_server_watched_paths
 3517                .remove(server_id_to_remove);
 3518            self.language_server_paths_watched_for_rename
 3519                .remove(server_id_to_remove);
 3520            self.last_workspace_edits_by_language_server
 3521                .remove(server_id_to_remove);
 3522            self.language_servers.remove(server_id_to_remove);
 3523            self.buffer_pull_diagnostics_result_ids
 3524                .remove(server_id_to_remove);
 3525            self.workspace_pull_diagnostics_result_ids
 3526                .remove(server_id_to_remove);
 3527            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3528                buffer_servers.remove(server_id_to_remove);
 3529            }
 3530            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3531        }
 3532        servers_to_remove.into_iter().collect()
 3533    }
 3534
 3535    fn rebuild_watched_paths_inner<'a>(
 3536        &'a self,
 3537        language_server_id: LanguageServerId,
 3538        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3539        cx: &mut Context<LspStore>,
 3540    ) -> LanguageServerWatchedPathsBuilder {
 3541        let worktrees = self
 3542            .worktree_store
 3543            .read(cx)
 3544            .worktrees()
 3545            .filter_map(|worktree| {
 3546                self.language_servers_for_worktree(worktree.read(cx).id())
 3547                    .find(|server| server.server_id() == language_server_id)
 3548                    .map(|_| worktree)
 3549            })
 3550            .collect::<Vec<_>>();
 3551
 3552        let mut worktree_globs = HashMap::default();
 3553        let mut abs_globs = HashMap::default();
 3554        log::trace!(
 3555            "Processing new watcher paths for language server with id {}",
 3556            language_server_id
 3557        );
 3558
 3559        for watcher in watchers {
 3560            if let Some((worktree, literal_prefix, pattern)) =
 3561                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3562            {
 3563                worktree.update(cx, |worktree, _| {
 3564                    if let Some((tree, glob)) =
 3565                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3566                    {
 3567                        tree.add_path_prefix_to_scan(literal_prefix);
 3568                        worktree_globs
 3569                            .entry(tree.id())
 3570                            .or_insert_with(GlobSetBuilder::new)
 3571                            .add(glob);
 3572                    }
 3573                });
 3574            } else {
 3575                let (path, pattern) = match &watcher.glob_pattern {
 3576                    lsp::GlobPattern::String(s) => {
 3577                        let watcher_path = SanitizedPath::new(s);
 3578                        let path = glob_literal_prefix(watcher_path.as_path());
 3579                        let pattern = watcher_path
 3580                            .as_path()
 3581                            .strip_prefix(&path)
 3582                            .map(|p| p.to_string_lossy().into_owned())
 3583                            .unwrap_or_else(|e| {
 3584                                debug_panic!(
 3585                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3586                                    s,
 3587                                    path.display(),
 3588                                    e
 3589                                );
 3590                                watcher_path.as_path().to_string_lossy().into_owned()
 3591                            });
 3592                        (path, pattern)
 3593                    }
 3594                    lsp::GlobPattern::Relative(rp) => {
 3595                        let Ok(mut base_uri) = match &rp.base_uri {
 3596                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3597                            lsp::OneOf::Right(base_uri) => base_uri,
 3598                        }
 3599                        .to_file_path() else {
 3600                            continue;
 3601                        };
 3602
 3603                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3604                        let pattern = Path::new(&rp.pattern)
 3605                            .strip_prefix(&path)
 3606                            .map(|p| p.to_string_lossy().into_owned())
 3607                            .unwrap_or_else(|e| {
 3608                                debug_panic!(
 3609                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3610                                    rp.pattern,
 3611                                    path.display(),
 3612                                    e
 3613                                );
 3614                                rp.pattern.clone()
 3615                            });
 3616                        base_uri.push(path);
 3617                        (base_uri, pattern)
 3618                    }
 3619                };
 3620
 3621                if let Some(glob) = Glob::new(&pattern).log_err() {
 3622                    if !path
 3623                        .components()
 3624                        .any(|c| matches!(c, path::Component::Normal(_)))
 3625                    {
 3626                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3627                        // rather than adding a new watcher for `/`.
 3628                        for worktree in &worktrees {
 3629                            worktree_globs
 3630                                .entry(worktree.read(cx).id())
 3631                                .or_insert_with(GlobSetBuilder::new)
 3632                                .add(glob.clone());
 3633                        }
 3634                    } else {
 3635                        abs_globs
 3636                            .entry(path.into())
 3637                            .or_insert_with(GlobSetBuilder::new)
 3638                            .add(glob);
 3639                    }
 3640                }
 3641            }
 3642        }
 3643
 3644        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3645        for (worktree_id, builder) in worktree_globs {
 3646            if let Ok(globset) = builder.build() {
 3647                watch_builder.watch_worktree(worktree_id, globset);
 3648            }
 3649        }
 3650        for (abs_path, builder) in abs_globs {
 3651            if let Ok(globset) = builder.build() {
 3652                watch_builder.watch_abs_path(abs_path, globset);
 3653            }
 3654        }
 3655        watch_builder
 3656    }
 3657
 3658    fn worktree_and_path_for_file_watcher(
 3659        worktrees: &[Entity<Worktree>],
 3660        watcher: &FileSystemWatcher,
 3661        cx: &App,
 3662    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3663        worktrees.iter().find_map(|worktree| {
 3664            let tree = worktree.read(cx);
 3665            let worktree_root_path = tree.abs_path();
 3666            let path_style = tree.path_style();
 3667            match &watcher.glob_pattern {
 3668                lsp::GlobPattern::String(s) => {
 3669                    let watcher_path = SanitizedPath::new(s);
 3670                    let relative = watcher_path
 3671                        .as_path()
 3672                        .strip_prefix(&worktree_root_path)
 3673                        .ok()?;
 3674                    let literal_prefix = glob_literal_prefix(relative);
 3675                    Some((
 3676                        worktree.clone(),
 3677                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3678                        relative.to_string_lossy().into_owned(),
 3679                    ))
 3680                }
 3681                lsp::GlobPattern::Relative(rp) => {
 3682                    let base_uri = match &rp.base_uri {
 3683                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3684                        lsp::OneOf::Right(base_uri) => base_uri,
 3685                    }
 3686                    .to_file_path()
 3687                    .ok()?;
 3688                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3689                    let mut literal_prefix = relative.to_owned();
 3690                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3691                    Some((
 3692                        worktree.clone(),
 3693                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3694                        rp.pattern.clone(),
 3695                    ))
 3696                }
 3697            }
 3698        })
 3699    }
 3700
 3701    fn rebuild_watched_paths(
 3702        &mut self,
 3703        language_server_id: LanguageServerId,
 3704        cx: &mut Context<LspStore>,
 3705    ) {
 3706        let Some(registrations) = self
 3707            .language_server_dynamic_registrations
 3708            .get(&language_server_id)
 3709        else {
 3710            return;
 3711        };
 3712
 3713        let watch_builder = self.rebuild_watched_paths_inner(
 3714            language_server_id,
 3715            registrations.did_change_watched_files.values().flatten(),
 3716            cx,
 3717        );
 3718        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3719        self.language_server_watched_paths
 3720            .insert(language_server_id, watcher);
 3721
 3722        cx.notify();
 3723    }
 3724
 3725    fn on_lsp_did_change_watched_files(
 3726        &mut self,
 3727        language_server_id: LanguageServerId,
 3728        registration_id: &str,
 3729        params: DidChangeWatchedFilesRegistrationOptions,
 3730        cx: &mut Context<LspStore>,
 3731    ) {
 3732        let registrations = self
 3733            .language_server_dynamic_registrations
 3734            .entry(language_server_id)
 3735            .or_default();
 3736
 3737        registrations
 3738            .did_change_watched_files
 3739            .insert(registration_id.to_string(), params.watchers);
 3740
 3741        self.rebuild_watched_paths(language_server_id, cx);
 3742    }
 3743
 3744    fn on_lsp_unregister_did_change_watched_files(
 3745        &mut self,
 3746        language_server_id: LanguageServerId,
 3747        registration_id: &str,
 3748        cx: &mut Context<LspStore>,
 3749    ) {
 3750        let registrations = self
 3751            .language_server_dynamic_registrations
 3752            .entry(language_server_id)
 3753            .or_default();
 3754
 3755        if registrations
 3756            .did_change_watched_files
 3757            .remove(registration_id)
 3758            .is_some()
 3759        {
 3760            log::info!(
 3761                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3762                language_server_id,
 3763                registration_id
 3764            );
 3765        } else {
 3766            log::warn!(
 3767                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3768                language_server_id,
 3769                registration_id
 3770            );
 3771        }
 3772
 3773        self.rebuild_watched_paths(language_server_id, cx);
 3774    }
 3775
 3776    async fn initialization_options_for_adapter(
 3777        adapter: Arc<dyn LspAdapter>,
 3778        delegate: &Arc<dyn LspAdapterDelegate>,
 3779        cx: &mut AsyncApp,
 3780    ) -> Result<Option<serde_json::Value>> {
 3781        let Some(mut initialization_config) =
 3782            adapter.clone().initialization_options(delegate, cx).await?
 3783        else {
 3784            return Ok(None);
 3785        };
 3786
 3787        for other_adapter in delegate.registered_lsp_adapters() {
 3788            if other_adapter.name() == adapter.name() {
 3789                continue;
 3790            }
 3791            if let Ok(Some(target_config)) = other_adapter
 3792                .clone()
 3793                .additional_initialization_options(adapter.name(), delegate)
 3794                .await
 3795            {
 3796                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3797            }
 3798        }
 3799
 3800        Ok(Some(initialization_config))
 3801    }
 3802
 3803    async fn workspace_configuration_for_adapter(
 3804        adapter: Arc<dyn LspAdapter>,
 3805        delegate: &Arc<dyn LspAdapterDelegate>,
 3806        toolchain: Option<Toolchain>,
 3807        requested_uri: Option<Uri>,
 3808        cx: &mut AsyncApp,
 3809    ) -> Result<serde_json::Value> {
 3810        let mut workspace_config = adapter
 3811            .clone()
 3812            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3813            .await?;
 3814
 3815        for other_adapter in delegate.registered_lsp_adapters() {
 3816            if other_adapter.name() == adapter.name() {
 3817                continue;
 3818            }
 3819            if let Ok(Some(target_config)) = other_adapter
 3820                .clone()
 3821                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3822                .await
 3823            {
 3824                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3825            }
 3826        }
 3827
 3828        Ok(workspace_config)
 3829    }
 3830
 3831    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3832        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3833            Some(server.clone())
 3834        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3835            Some(Arc::clone(server))
 3836        } else {
 3837            None
 3838        }
 3839    }
 3840}
 3841
 3842fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3843    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3844        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3845            language_server_id: server.server_id(),
 3846            name: Some(server.name()),
 3847            message: proto::update_language_server::Variant::MetadataUpdated(
 3848                proto::ServerMetadataUpdated {
 3849                    capabilities: Some(capabilities),
 3850                    binary: Some(proto::LanguageServerBinaryInfo {
 3851                        path: server.binary().path.to_string_lossy().into_owned(),
 3852                        arguments: server
 3853                            .binary()
 3854                            .arguments
 3855                            .iter()
 3856                            .map(|arg| arg.to_string_lossy().into_owned())
 3857                            .collect(),
 3858                    }),
 3859                    configuration: serde_json::to_string(server.configuration()).ok(),
 3860                    workspace_folders: server
 3861                        .workspace_folders()
 3862                        .iter()
 3863                        .map(|uri| uri.to_string())
 3864                        .collect(),
 3865                },
 3866            ),
 3867        });
 3868    }
 3869}
 3870
 3871#[derive(Debug)]
 3872pub struct FormattableBuffer {
 3873    handle: Entity<Buffer>,
 3874    abs_path: Option<PathBuf>,
 3875    env: Option<HashMap<String, String>>,
 3876    ranges: Option<Vec<Range<Anchor>>>,
 3877}
 3878
 3879pub struct RemoteLspStore {
 3880    upstream_client: Option<AnyProtoClient>,
 3881    upstream_project_id: u64,
 3882}
 3883
 3884pub(crate) enum LspStoreMode {
 3885    Local(LocalLspStore),   // ssh host and collab host
 3886    Remote(RemoteLspStore), // collab guest
 3887}
 3888
 3889impl LspStoreMode {
 3890    fn is_local(&self) -> bool {
 3891        matches!(self, LspStoreMode::Local(_))
 3892    }
 3893}
 3894
 3895pub struct LspStore {
 3896    mode: LspStoreMode,
 3897    last_formatting_failure: Option<String>,
 3898    downstream_client: Option<(AnyProtoClient, u64)>,
 3899    nonce: u128,
 3900    buffer_store: Entity<BufferStore>,
 3901    worktree_store: Entity<WorktreeStore>,
 3902    pub languages: Arc<LanguageRegistry>,
 3903    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3904    active_entry: Option<ProjectEntryId>,
 3905    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3906    _maintain_buffer_languages: Task<()>,
 3907    diagnostic_summaries:
 3908        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3909    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3910    semantic_token_config: SemanticTokenConfig,
 3911    lsp_data: HashMap<BufferId, BufferLspData>,
 3912    buffer_reload_tasks: HashMap<BufferId, Task<anyhow::Result<()>>>,
 3913    next_hint_id: Arc<AtomicUsize>,
 3914}
 3915
 3916#[derive(Debug)]
 3917pub struct BufferLspData {
 3918    buffer_version: Global,
 3919    document_colors: Option<DocumentColorData>,
 3920    code_lens: Option<CodeLensData>,
 3921    semantic_tokens: Option<SemanticTokensData>,
 3922    folding_ranges: Option<FoldingRangeData>,
 3923    document_symbols: Option<DocumentSymbolsData>,
 3924    inlay_hints: BufferInlayHints,
 3925    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3926    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3927}
 3928
 3929#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3930struct LspKey {
 3931    request_type: TypeId,
 3932    server_queried: Option<LanguageServerId>,
 3933}
 3934
 3935impl BufferLspData {
 3936    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3937        Self {
 3938            buffer_version: buffer.read(cx).version(),
 3939            document_colors: None,
 3940            code_lens: None,
 3941            semantic_tokens: None,
 3942            folding_ranges: None,
 3943            document_symbols: None,
 3944            inlay_hints: BufferInlayHints::new(buffer, cx),
 3945            lsp_requests: HashMap::default(),
 3946            chunk_lsp_requests: HashMap::default(),
 3947        }
 3948    }
 3949
 3950    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3951        if let Some(document_colors) = &mut self.document_colors {
 3952            document_colors.remove_server_data(for_server);
 3953        }
 3954
 3955        if let Some(code_lens) = &mut self.code_lens {
 3956            code_lens.remove_server_data(for_server);
 3957        }
 3958
 3959        self.inlay_hints.remove_server_data(for_server);
 3960
 3961        if let Some(semantic_tokens) = &mut self.semantic_tokens {
 3962            semantic_tokens.remove_server_data(for_server);
 3963        }
 3964
 3965        if let Some(folding_ranges) = &mut self.folding_ranges {
 3966            folding_ranges.ranges.remove(&for_server);
 3967        }
 3968
 3969        if let Some(document_symbols) = &mut self.document_symbols {
 3970            document_symbols.remove_server_data(for_server);
 3971        }
 3972    }
 3973
 3974    #[cfg(any(test, feature = "test-support"))]
 3975    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3976        &self.inlay_hints
 3977    }
 3978}
 3979
 3980#[derive(Debug)]
 3981pub enum LspStoreEvent {
 3982    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3983    LanguageServerRemoved(LanguageServerId),
 3984    LanguageServerUpdate {
 3985        language_server_id: LanguageServerId,
 3986        name: Option<LanguageServerName>,
 3987        message: proto::update_language_server::Variant,
 3988    },
 3989    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3990    LanguageServerPrompt(LanguageServerPromptRequest),
 3991    LanguageDetected {
 3992        buffer: Entity<Buffer>,
 3993        new_language: Option<Arc<Language>>,
 3994    },
 3995    Notification(String),
 3996    RefreshInlayHints {
 3997        server_id: LanguageServerId,
 3998        request_id: Option<usize>,
 3999    },
 4000    RefreshSemanticTokens {
 4001        server_id: LanguageServerId,
 4002        request_id: Option<usize>,
 4003    },
 4004    RefreshCodeLens,
 4005    DiagnosticsUpdated {
 4006        server_id: LanguageServerId,
 4007        paths: Vec<ProjectPath>,
 4008    },
 4009    DiskBasedDiagnosticsStarted {
 4010        language_server_id: LanguageServerId,
 4011    },
 4012    DiskBasedDiagnosticsFinished {
 4013        language_server_id: LanguageServerId,
 4014    },
 4015    SnippetEdit {
 4016        buffer_id: BufferId,
 4017        edits: Vec<(lsp::Range, Snippet)>,
 4018        most_recent_edit: clock::Lamport,
 4019    },
 4020    WorkspaceEditApplied(ProjectTransaction),
 4021}
 4022
 4023#[derive(Clone, Debug, Serialize)]
 4024pub struct LanguageServerStatus {
 4025    pub name: LanguageServerName,
 4026    pub server_version: Option<SharedString>,
 4027    pub server_readable_version: Option<SharedString>,
 4028    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 4029    pub has_pending_diagnostic_updates: bool,
 4030    pub progress_tokens: HashSet<ProgressToken>,
 4031    pub worktree: Option<WorktreeId>,
 4032    pub binary: Option<LanguageServerBinary>,
 4033    pub configuration: Option<Value>,
 4034    pub workspace_folders: BTreeSet<Uri>,
 4035    pub process_id: Option<u32>,
 4036}
 4037
 4038#[derive(Clone, Debug)]
 4039struct CoreSymbol {
 4040    pub language_server_name: LanguageServerName,
 4041    pub source_worktree_id: WorktreeId,
 4042    pub source_language_server_id: LanguageServerId,
 4043    pub path: SymbolLocation,
 4044    pub name: String,
 4045    pub kind: lsp::SymbolKind,
 4046    pub range: Range<Unclipped<PointUtf16>>,
 4047    pub container_name: Option<String>,
 4048}
 4049
 4050#[derive(Clone, Debug, PartialEq, Eq)]
 4051pub enum SymbolLocation {
 4052    InProject(ProjectPath),
 4053    OutsideProject {
 4054        abs_path: Arc<Path>,
 4055        signature: [u8; 32],
 4056    },
 4057}
 4058
 4059impl SymbolLocation {
 4060    fn file_name(&self) -> Option<&str> {
 4061        match self {
 4062            Self::InProject(path) => path.path.file_name(),
 4063            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 4064        }
 4065    }
 4066}
 4067
 4068impl LspStore {
 4069    pub fn init(client: &AnyProtoClient) {
 4070        client.add_entity_request_handler(Self::handle_lsp_query);
 4071        client.add_entity_message_handler(Self::handle_lsp_query_response);
 4072        client.add_entity_request_handler(Self::handle_restart_language_servers);
 4073        client.add_entity_request_handler(Self::handle_stop_language_servers);
 4074        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 4075        client.add_entity_message_handler(Self::handle_start_language_server);
 4076        client.add_entity_message_handler(Self::handle_update_language_server);
 4077        client.add_entity_message_handler(Self::handle_language_server_log);
 4078        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 4079        client.add_entity_request_handler(Self::handle_format_buffers);
 4080        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 4081        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 4082        client.add_entity_request_handler(Self::handle_apply_code_action);
 4083        client.add_entity_request_handler(Self::handle_get_project_symbols);
 4084        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 4085        client.add_entity_request_handler(Self::handle_get_color_presentation);
 4086        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 4087        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 4088        client.add_entity_request_handler(Self::handle_refresh_semantic_tokens);
 4089        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 4090        client.add_entity_request_handler(Self::handle_on_type_formatting);
 4091        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 4092        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 4093        client.add_entity_request_handler(Self::handle_rename_project_entry);
 4094        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 4095        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 4096        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 4097        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 4098        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 4099        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 4100        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 4101
 4102        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 4103        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 4104        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 4105        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 4106        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 4107        client.add_entity_request_handler(
 4108            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 4109        );
 4110        client.add_entity_request_handler(
 4111            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 4112        );
 4113        client.add_entity_request_handler(
 4114            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 4115        );
 4116    }
 4117
 4118    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 4119        match &self.mode {
 4120            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 4121            _ => None,
 4122        }
 4123    }
 4124
 4125    pub fn as_local(&self) -> Option<&LocalLspStore> {
 4126        match &self.mode {
 4127            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4128            _ => None,
 4129        }
 4130    }
 4131
 4132    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 4133        match &mut self.mode {
 4134            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4135            _ => None,
 4136        }
 4137    }
 4138
 4139    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4140        match &self.mode {
 4141            LspStoreMode::Remote(RemoteLspStore {
 4142                upstream_client: Some(upstream_client),
 4143                upstream_project_id,
 4144                ..
 4145            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4146
 4147            LspStoreMode::Remote(RemoteLspStore {
 4148                upstream_client: None,
 4149                ..
 4150            }) => None,
 4151            LspStoreMode::Local(_) => None,
 4152        }
 4153    }
 4154
 4155    pub fn new_local(
 4156        buffer_store: Entity<BufferStore>,
 4157        worktree_store: Entity<WorktreeStore>,
 4158        prettier_store: Entity<PrettierStore>,
 4159        toolchain_store: Entity<LocalToolchainStore>,
 4160        environment: Entity<ProjectEnvironment>,
 4161        manifest_tree: Entity<ManifestTree>,
 4162        languages: Arc<LanguageRegistry>,
 4163        http_client: Arc<dyn HttpClient>,
 4164        fs: Arc<dyn Fs>,
 4165        cx: &mut Context<Self>,
 4166    ) -> Self {
 4167        let yarn = YarnPathStore::new(fs.clone(), cx);
 4168        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4169            .detach();
 4170        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4171            .detach();
 4172        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4173            .detach();
 4174        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4175            .detach();
 4176        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4177            .detach();
 4178        subscribe_to_binary_statuses(&languages, cx).detach();
 4179
 4180        let _maintain_workspace_config = {
 4181            let (sender, receiver) = watch::channel();
 4182            (Self::maintain_workspace_config(receiver, cx), sender)
 4183        };
 4184
 4185        Self {
 4186            mode: LspStoreMode::Local(LocalLspStore {
 4187                weak: cx.weak_entity(),
 4188                worktree_store: worktree_store.clone(),
 4189
 4190                supplementary_language_servers: Default::default(),
 4191                languages: languages.clone(),
 4192                language_server_ids: Default::default(),
 4193                language_servers: Default::default(),
 4194                last_workspace_edits_by_language_server: Default::default(),
 4195                language_server_watched_paths: Default::default(),
 4196                language_server_paths_watched_for_rename: Default::default(),
 4197                language_server_dynamic_registrations: Default::default(),
 4198                buffers_being_formatted: Default::default(),
 4199                buffers_to_refresh_hash_set: HashSet::default(),
 4200                buffers_to_refresh_queue: VecDeque::new(),
 4201                _background_diagnostics_worker: Task::ready(()).shared(),
 4202                buffer_snapshots: Default::default(),
 4203                prettier_store,
 4204                environment,
 4205                http_client,
 4206                fs,
 4207                yarn,
 4208                next_diagnostic_group_id: Default::default(),
 4209                diagnostics: Default::default(),
 4210                _subscription: cx.on_app_quit(|this, _| {
 4211                    this.as_local_mut()
 4212                        .unwrap()
 4213                        .shutdown_language_servers_on_quit()
 4214                }),
 4215                lsp_tree: LanguageServerTree::new(
 4216                    manifest_tree,
 4217                    languages.clone(),
 4218                    toolchain_store.clone(),
 4219                ),
 4220                toolchain_store,
 4221                registered_buffers: HashMap::default(),
 4222                buffers_opened_in_servers: HashMap::default(),
 4223                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4224                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4225                restricted_worktrees_tasks: HashMap::default(),
 4226                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4227                    .manifest_file_names(),
 4228            }),
 4229            last_formatting_failure: None,
 4230            downstream_client: None,
 4231            buffer_store,
 4232            worktree_store,
 4233            languages: languages.clone(),
 4234            language_server_statuses: Default::default(),
 4235            nonce: StdRng::from_os_rng().random(),
 4236            diagnostic_summaries: HashMap::default(),
 4237            lsp_server_capabilities: HashMap::default(),
 4238            semantic_token_config: SemanticTokenConfig::new(cx),
 4239            lsp_data: HashMap::default(),
 4240            buffer_reload_tasks: HashMap::default(),
 4241            next_hint_id: Arc::default(),
 4242            active_entry: None,
 4243            _maintain_workspace_config,
 4244            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4245        }
 4246    }
 4247
 4248    fn send_lsp_proto_request<R: LspCommand>(
 4249        &self,
 4250        buffer: Entity<Buffer>,
 4251        client: AnyProtoClient,
 4252        upstream_project_id: u64,
 4253        request: R,
 4254        cx: &mut Context<LspStore>,
 4255    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4256        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4257            return Task::ready(Ok(R::Response::default()));
 4258        }
 4259        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4260        cx.spawn(async move |this, cx| {
 4261            let response = client.request(message).await?;
 4262            let this = this.upgrade().context("project dropped")?;
 4263            request
 4264                .response_from_proto(response, this, buffer, cx.clone())
 4265                .await
 4266        })
 4267    }
 4268
 4269    pub(super) fn new_remote(
 4270        buffer_store: Entity<BufferStore>,
 4271        worktree_store: Entity<WorktreeStore>,
 4272        languages: Arc<LanguageRegistry>,
 4273        upstream_client: AnyProtoClient,
 4274        project_id: u64,
 4275        cx: &mut Context<Self>,
 4276    ) -> Self {
 4277        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4278            .detach();
 4279        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4280            .detach();
 4281        subscribe_to_binary_statuses(&languages, cx).detach();
 4282        let _maintain_workspace_config = {
 4283            let (sender, receiver) = watch::channel();
 4284            (Self::maintain_workspace_config(receiver, cx), sender)
 4285        };
 4286        Self {
 4287            mode: LspStoreMode::Remote(RemoteLspStore {
 4288                upstream_client: Some(upstream_client),
 4289                upstream_project_id: project_id,
 4290            }),
 4291            downstream_client: None,
 4292            last_formatting_failure: None,
 4293            buffer_store,
 4294            worktree_store,
 4295            languages: languages.clone(),
 4296            language_server_statuses: Default::default(),
 4297            nonce: StdRng::from_os_rng().random(),
 4298            diagnostic_summaries: HashMap::default(),
 4299            lsp_server_capabilities: HashMap::default(),
 4300            semantic_token_config: SemanticTokenConfig::new(cx),
 4301            next_hint_id: Arc::default(),
 4302            lsp_data: HashMap::default(),
 4303            buffer_reload_tasks: HashMap::default(),
 4304            active_entry: None,
 4305
 4306            _maintain_workspace_config,
 4307            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4308        }
 4309    }
 4310
 4311    fn on_buffer_store_event(
 4312        &mut self,
 4313        _: Entity<BufferStore>,
 4314        event: &BufferStoreEvent,
 4315        cx: &mut Context<Self>,
 4316    ) {
 4317        match event {
 4318            BufferStoreEvent::BufferAdded(buffer) => {
 4319                self.on_buffer_added(buffer, cx).log_err();
 4320            }
 4321            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4322                let buffer_id = buffer.read(cx).remote_id();
 4323                if let Some(local) = self.as_local_mut()
 4324                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4325                {
 4326                    local.reset_buffer(buffer, old_file, cx);
 4327
 4328                    if local.registered_buffers.contains_key(&buffer_id) {
 4329                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4330                    }
 4331                }
 4332
 4333                self.detect_language_for_buffer(buffer, cx);
 4334                if let Some(local) = self.as_local_mut() {
 4335                    local.initialize_buffer(buffer, cx);
 4336                    if local.registered_buffers.contains_key(&buffer_id) {
 4337                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4338                    }
 4339                }
 4340            }
 4341            _ => {}
 4342        }
 4343    }
 4344
 4345    fn on_worktree_store_event(
 4346        &mut self,
 4347        _: Entity<WorktreeStore>,
 4348        event: &WorktreeStoreEvent,
 4349        cx: &mut Context<Self>,
 4350    ) {
 4351        match event {
 4352            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4353                if !worktree.read(cx).is_local() {
 4354                    return;
 4355                }
 4356                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4357                    worktree::Event::UpdatedEntries(changes) => {
 4358                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4359                    }
 4360                    worktree::Event::UpdatedGitRepositories(_)
 4361                    | worktree::Event::DeletedEntry(_) => {}
 4362                })
 4363                .detach()
 4364            }
 4365            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4366            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4367                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4368            }
 4369            WorktreeStoreEvent::WorktreeUpdatedEntries(worktree_id, changes) => {
 4370                self.invalidate_diagnostic_summaries_for_removed_entries(*worktree_id, changes, cx);
 4371            }
 4372            WorktreeStoreEvent::WorktreeReleased(..)
 4373            | WorktreeStoreEvent::WorktreeOrderChanged
 4374            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4375            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4376        }
 4377    }
 4378
 4379    fn on_prettier_store_event(
 4380        &mut self,
 4381        _: Entity<PrettierStore>,
 4382        event: &PrettierStoreEvent,
 4383        cx: &mut Context<Self>,
 4384    ) {
 4385        match event {
 4386            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4387                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4388            }
 4389            PrettierStoreEvent::LanguageServerAdded {
 4390                new_server_id,
 4391                name,
 4392                prettier_server,
 4393            } => {
 4394                self.register_supplementary_language_server(
 4395                    *new_server_id,
 4396                    name.clone(),
 4397                    prettier_server.clone(),
 4398                    cx,
 4399                );
 4400            }
 4401        }
 4402    }
 4403
 4404    fn on_toolchain_store_event(
 4405        &mut self,
 4406        _: Entity<LocalToolchainStore>,
 4407        event: &ToolchainStoreEvent,
 4408        _: &mut Context<Self>,
 4409    ) {
 4410        if let ToolchainStoreEvent::ToolchainActivated = event {
 4411            self.request_workspace_config_refresh()
 4412        }
 4413    }
 4414
 4415    fn request_workspace_config_refresh(&mut self) {
 4416        *self._maintain_workspace_config.1.borrow_mut() = ();
 4417    }
 4418
 4419    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4420        self.as_local().map(|local| local.prettier_store.clone())
 4421    }
 4422
 4423    fn on_buffer_event(
 4424        &mut self,
 4425        buffer: Entity<Buffer>,
 4426        event: &language::BufferEvent,
 4427        cx: &mut Context<Self>,
 4428    ) {
 4429        match event {
 4430            language::BufferEvent::Edited { .. } => {
 4431                self.on_buffer_edited(buffer, cx);
 4432            }
 4433
 4434            language::BufferEvent::Saved => {
 4435                self.on_buffer_saved(buffer, cx);
 4436            }
 4437
 4438            language::BufferEvent::Reloaded => {
 4439                self.on_buffer_reloaded(buffer, cx);
 4440            }
 4441
 4442            _ => {}
 4443        }
 4444    }
 4445
 4446    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4447        buffer
 4448            .read(cx)
 4449            .set_language_registry(self.languages.clone());
 4450
 4451        cx.subscribe(buffer, |this, buffer, event, cx| {
 4452            this.on_buffer_event(buffer, event, cx);
 4453        })
 4454        .detach();
 4455
 4456        self.parse_modeline(buffer, cx);
 4457        self.detect_language_for_buffer(buffer, cx);
 4458        if let Some(local) = self.as_local_mut() {
 4459            local.initialize_buffer(buffer, cx);
 4460        }
 4461
 4462        Ok(())
 4463    }
 4464
 4465    pub fn refresh_background_diagnostics_for_buffers(
 4466        &mut self,
 4467        buffers: HashSet<BufferId>,
 4468        cx: &mut Context<Self>,
 4469    ) -> Shared<Task<()>> {
 4470        let Some(local) = self.as_local_mut() else {
 4471            return Task::ready(()).shared();
 4472        };
 4473        for buffer in buffers {
 4474            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4475                local.buffers_to_refresh_queue.push_back(buffer);
 4476                if local.buffers_to_refresh_queue.len() == 1 {
 4477                    local._background_diagnostics_worker =
 4478                        Self::background_diagnostics_worker(cx).shared();
 4479                }
 4480            }
 4481        }
 4482
 4483        local._background_diagnostics_worker.clone()
 4484    }
 4485
 4486    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4487        let buffer_store = self.buffer_store.clone();
 4488        let local = self.as_local_mut()?;
 4489        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4490            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4491            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4492                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4493            }
 4494        }
 4495        None
 4496    }
 4497
 4498    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4499        cx.spawn(async move |this, cx| {
 4500            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4501                task.await.log_err();
 4502            }
 4503        })
 4504    }
 4505
 4506    fn on_buffer_reloaded(&mut self, buffer: Entity<Buffer>, cx: &mut Context<Self>) {
 4507        if self.parse_modeline(&buffer, cx) {
 4508            self.detect_language_for_buffer(&buffer, cx);
 4509        }
 4510
 4511        let buffer_id = buffer.read(cx).remote_id();
 4512        let task = self.pull_diagnostics_for_buffer(buffer, cx);
 4513        self.buffer_reload_tasks.insert(buffer_id, task);
 4514    }
 4515
 4516    pub(crate) fn register_buffer_with_language_servers(
 4517        &mut self,
 4518        buffer: &Entity<Buffer>,
 4519        only_register_servers: HashSet<LanguageServerSelector>,
 4520        ignore_refcounts: bool,
 4521        cx: &mut Context<Self>,
 4522    ) -> OpenLspBufferHandle {
 4523        let buffer_id = buffer.read(cx).remote_id();
 4524        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4525        if let Some(local) = self.as_local_mut() {
 4526            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4527            if !ignore_refcounts {
 4528                *refcount += 1;
 4529            }
 4530
 4531            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4532            // 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
 4533            // 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
 4534            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4535            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4536                return handle;
 4537            };
 4538            if !file.is_local() {
 4539                return handle;
 4540            }
 4541
 4542            if ignore_refcounts || *refcount == 1 {
 4543                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4544            }
 4545            if !ignore_refcounts {
 4546                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4547                    let refcount = {
 4548                        let local = lsp_store.as_local_mut().unwrap();
 4549                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4550                            debug_panic!("bad refcounting");
 4551                            return;
 4552                        };
 4553
 4554                        *refcount -= 1;
 4555                        *refcount
 4556                    };
 4557                    if refcount == 0 {
 4558                        lsp_store.lsp_data.remove(&buffer_id);
 4559                        lsp_store.buffer_reload_tasks.remove(&buffer_id);
 4560                        let local = lsp_store.as_local_mut().unwrap();
 4561                        local.registered_buffers.remove(&buffer_id);
 4562
 4563                        local.buffers_opened_in_servers.remove(&buffer_id);
 4564                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4565                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4566
 4567                            let buffer_abs_path = file.abs_path(cx);
 4568                            for (_, buffer_pull_diagnostics_result_ids) in
 4569                                &mut local.buffer_pull_diagnostics_result_ids
 4570                            {
 4571                                buffer_pull_diagnostics_result_ids.retain(
 4572                                    |_, buffer_result_ids| {
 4573                                        buffer_result_ids.remove(&buffer_abs_path);
 4574                                        !buffer_result_ids.is_empty()
 4575                                    },
 4576                                );
 4577                            }
 4578
 4579                            let diagnostic_updates = local
 4580                                .language_servers
 4581                                .keys()
 4582                                .cloned()
 4583                                .map(|server_id| DocumentDiagnosticsUpdate {
 4584                                    diagnostics: DocumentDiagnostics {
 4585                                        document_abs_path: buffer_abs_path.clone(),
 4586                                        version: None,
 4587                                        diagnostics: Vec::new(),
 4588                                    },
 4589                                    result_id: None,
 4590                                    registration_id: None,
 4591                                    server_id,
 4592                                    disk_based_sources: Cow::Borrowed(&[]),
 4593                                })
 4594                                .collect::<Vec<_>>();
 4595
 4596                            lsp_store
 4597                                .merge_diagnostic_entries(
 4598                                    diagnostic_updates,
 4599                                    |_, diagnostic, _| {
 4600                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4601                                    },
 4602                                    cx,
 4603                                )
 4604                                .context("Clearing diagnostics for the closed buffer")
 4605                                .log_err();
 4606                        }
 4607                    }
 4608                })
 4609                .detach();
 4610            }
 4611        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4612            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4613            cx.background_spawn(async move {
 4614                upstream_client
 4615                    .request(proto::RegisterBufferWithLanguageServers {
 4616                        project_id: upstream_project_id,
 4617                        buffer_id,
 4618                        only_servers: only_register_servers
 4619                            .into_iter()
 4620                            .map(|selector| {
 4621                                let selector = match selector {
 4622                                    LanguageServerSelector::Id(language_server_id) => {
 4623                                        proto::language_server_selector::Selector::ServerId(
 4624                                            language_server_id.to_proto(),
 4625                                        )
 4626                                    }
 4627                                    LanguageServerSelector::Name(language_server_name) => {
 4628                                        proto::language_server_selector::Selector::Name(
 4629                                            language_server_name.to_string(),
 4630                                        )
 4631                                    }
 4632                                };
 4633                                proto::LanguageServerSelector {
 4634                                    selector: Some(selector),
 4635                                }
 4636                            })
 4637                            .collect(),
 4638                    })
 4639                    .await
 4640            })
 4641            .detach();
 4642        } else {
 4643            // Our remote connection got closed
 4644        }
 4645        handle
 4646    }
 4647
 4648    fn maintain_buffer_languages(
 4649        languages: Arc<LanguageRegistry>,
 4650        cx: &mut Context<Self>,
 4651    ) -> Task<()> {
 4652        let mut subscription = languages.subscribe();
 4653        let mut prev_reload_count = languages.reload_count();
 4654        cx.spawn(async move |this, cx| {
 4655            while let Some(()) = subscription.next().await {
 4656                if let Some(this) = this.upgrade() {
 4657                    // If the language registry has been reloaded, then remove and
 4658                    // re-assign the languages on all open buffers.
 4659                    let reload_count = languages.reload_count();
 4660                    if reload_count > prev_reload_count {
 4661                        prev_reload_count = reload_count;
 4662                        this.update(cx, |this, cx| {
 4663                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4664                                for buffer in buffer_store.buffers() {
 4665                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4666                                    {
 4667                                        buffer.update(cx, |buffer, cx| {
 4668                                            buffer.set_language_async(None, cx)
 4669                                        });
 4670                                        if let Some(local) = this.as_local_mut() {
 4671                                            local.reset_buffer(&buffer, &f, cx);
 4672
 4673                                            if local
 4674                                                .registered_buffers
 4675                                                .contains_key(&buffer.read(cx).remote_id())
 4676                                                && let Some(file_url) =
 4677                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4678                                            {
 4679                                                local.unregister_buffer_from_language_servers(
 4680                                                    &buffer, &file_url, cx,
 4681                                                );
 4682                                            }
 4683                                        }
 4684                                    }
 4685                                }
 4686                            });
 4687                        });
 4688                    }
 4689
 4690                    this.update(cx, |this, cx| {
 4691                        let mut plain_text_buffers = Vec::new();
 4692                        let mut buffers_with_unknown_injections = Vec::new();
 4693                        for handle in this.buffer_store.read(cx).buffers() {
 4694                            let buffer = handle.read(cx);
 4695                            if buffer.language().is_none()
 4696                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4697                            {
 4698                                plain_text_buffers.push(handle);
 4699                            } else if buffer.contains_unknown_injections() {
 4700                                buffers_with_unknown_injections.push(handle);
 4701                            }
 4702                        }
 4703
 4704                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4705                        // and reused later in the invisible worktrees.
 4706                        plain_text_buffers.sort_by_key(|buffer| {
 4707                            Reverse(
 4708                                File::from_dyn(buffer.read(cx).file())
 4709                                    .map(|file| file.worktree.read(cx).is_visible()),
 4710                            )
 4711                        });
 4712
 4713                        for buffer in plain_text_buffers {
 4714                            this.detect_language_for_buffer(&buffer, cx);
 4715                            if let Some(local) = this.as_local_mut() {
 4716                                local.initialize_buffer(&buffer, cx);
 4717                                if local
 4718                                    .registered_buffers
 4719                                    .contains_key(&buffer.read(cx).remote_id())
 4720                                {
 4721                                    local.register_buffer_with_language_servers(
 4722                                        &buffer,
 4723                                        HashSet::default(),
 4724                                        cx,
 4725                                    );
 4726                                }
 4727                            }
 4728                        }
 4729
 4730                        for buffer in buffers_with_unknown_injections {
 4731                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4732                        }
 4733                    });
 4734                }
 4735            }
 4736        })
 4737    }
 4738
 4739    fn parse_modeline(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<Self>) -> bool {
 4740        let buffer = buffer_handle.read(cx);
 4741        let content = buffer.as_rope();
 4742
 4743        let modeline_settings = {
 4744            let settings_store = cx.global::<SettingsStore>();
 4745            let modeline_lines = settings_store
 4746                .raw_user_settings()
 4747                .and_then(|s| s.content.modeline_lines)
 4748                .or(settings_store.raw_default_settings().modeline_lines)
 4749                .unwrap_or(5);
 4750
 4751            const MAX_MODELINE_BYTES: usize = 1024;
 4752
 4753            let first_bytes =
 4754                content.clip_offset(content.len().min(MAX_MODELINE_BYTES), Bias::Left);
 4755            let mut first_lines = Vec::new();
 4756            let mut lines = content.chunks_in_range(0..first_bytes).lines();
 4757            for _ in 0..modeline_lines {
 4758                if let Some(line) = lines.next() {
 4759                    first_lines.push(line.to_string());
 4760                } else {
 4761                    break;
 4762                }
 4763            }
 4764            let first_lines_ref: Vec<_> = first_lines.iter().map(|line| line.as_str()).collect();
 4765
 4766            let last_start =
 4767                content.clip_offset(content.len().saturating_sub(MAX_MODELINE_BYTES), Bias::Left);
 4768            let mut last_lines = Vec::new();
 4769            let mut lines = content
 4770                .reversed_chunks_in_range(last_start..content.len())
 4771                .lines();
 4772            for _ in 0..modeline_lines {
 4773                if let Some(line) = lines.next() {
 4774                    last_lines.push(line.to_string());
 4775                } else {
 4776                    break;
 4777                }
 4778            }
 4779            let last_lines_ref: Vec<_> =
 4780                last_lines.iter().rev().map(|line| line.as_str()).collect();
 4781            modeline::parse_modeline(&first_lines_ref, &last_lines_ref)
 4782        };
 4783
 4784        log::debug!("Parsed modeline settings: {:?}", modeline_settings);
 4785
 4786        buffer_handle.update(cx, |buffer, _cx| buffer.set_modeline(modeline_settings))
 4787    }
 4788
 4789    fn detect_language_for_buffer(
 4790        &mut self,
 4791        buffer_handle: &Entity<Buffer>,
 4792        cx: &mut Context<Self>,
 4793    ) -> Option<language::AvailableLanguage> {
 4794        // If the buffer has a language, set it and start the language server if we haven't already.
 4795        let buffer = buffer_handle.read(cx);
 4796        let file = buffer.file()?;
 4797        let content = buffer.as_rope();
 4798        let modeline_settings = buffer.modeline().map(Arc::as_ref);
 4799
 4800        let available_language = if let Some(ModelineSettings {
 4801            mode: Some(mode_name),
 4802            ..
 4803        }) = modeline_settings
 4804        {
 4805            self.languages
 4806                .available_language_for_modeline_name(mode_name)
 4807        } else {
 4808            self.languages.language_for_file(file, Some(content), cx)
 4809        };
 4810        if let Some(available_language) = &available_language {
 4811            if let Some(Ok(Ok(new_language))) = self
 4812                .languages
 4813                .load_language(available_language)
 4814                .now_or_never()
 4815            {
 4816                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4817            }
 4818        } else {
 4819            cx.emit(LspStoreEvent::LanguageDetected {
 4820                buffer: buffer_handle.clone(),
 4821                new_language: None,
 4822            });
 4823        }
 4824
 4825        available_language
 4826    }
 4827
 4828    pub(crate) fn set_language_for_buffer(
 4829        &mut self,
 4830        buffer_entity: &Entity<Buffer>,
 4831        new_language: Arc<Language>,
 4832        cx: &mut Context<Self>,
 4833    ) {
 4834        let buffer = buffer_entity.read(cx);
 4835        let buffer_file = buffer.file().cloned();
 4836        let buffer_id = buffer.remote_id();
 4837        if let Some(local_store) = self.as_local_mut()
 4838            && local_store.registered_buffers.contains_key(&buffer_id)
 4839            && let Some(abs_path) =
 4840                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4841            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4842        {
 4843            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4844        }
 4845        buffer_entity.update(cx, |buffer, cx| {
 4846            if buffer
 4847                .language()
 4848                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4849            {
 4850                buffer.set_language_async(Some(new_language.clone()), cx);
 4851            }
 4852        });
 4853
 4854        let settings = LanguageSettings::resolve(
 4855            Some(&buffer_entity.read(cx)),
 4856            Some(&new_language.name()),
 4857            cx,
 4858        )
 4859        .into_owned();
 4860        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4861
 4862        let worktree_id = if let Some(file) = buffer_file {
 4863            let worktree = file.worktree.clone();
 4864
 4865            if let Some(local) = self.as_local_mut()
 4866                && local.registered_buffers.contains_key(&buffer_id)
 4867            {
 4868                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4869            }
 4870            Some(worktree.read(cx).id())
 4871        } else {
 4872            None
 4873        };
 4874
 4875        if settings.prettier.allowed
 4876            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4877        {
 4878            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4879            if let Some(prettier_store) = prettier_store {
 4880                prettier_store.update(cx, |prettier_store, cx| {
 4881                    prettier_store.install_default_prettier(
 4882                        worktree_id,
 4883                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4884                        cx,
 4885                    )
 4886                })
 4887            }
 4888        }
 4889
 4890        cx.emit(LspStoreEvent::LanguageDetected {
 4891            buffer: buffer_entity.clone(),
 4892            new_language: Some(new_language),
 4893        })
 4894    }
 4895
 4896    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4897        self.buffer_store.clone()
 4898    }
 4899
 4900    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4901        self.active_entry = active_entry;
 4902    }
 4903
 4904    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4905        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4906            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4907        {
 4908            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4909                summaries
 4910                    .iter()
 4911                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4912            });
 4913            if let Some(summary) = summaries.next() {
 4914                client
 4915                    .send(proto::UpdateDiagnosticSummary {
 4916                        project_id: downstream_project_id,
 4917                        worktree_id: worktree.id().to_proto(),
 4918                        summary: Some(summary),
 4919                        more_summaries: summaries.collect(),
 4920                    })
 4921                    .log_err();
 4922            }
 4923        }
 4924    }
 4925
 4926    fn is_capable_for_proto_request<R>(
 4927        &self,
 4928        buffer: &Entity<Buffer>,
 4929        request: &R,
 4930        cx: &App,
 4931    ) -> bool
 4932    where
 4933        R: LspCommand,
 4934    {
 4935        self.check_if_capable_for_proto_request(
 4936            buffer,
 4937            |capabilities| {
 4938                request.check_capabilities(AdapterServerCapabilities {
 4939                    server_capabilities: capabilities.clone(),
 4940                    code_action_kinds: None,
 4941                })
 4942            },
 4943            cx,
 4944        )
 4945    }
 4946
 4947    fn check_if_capable_for_proto_request<F>(
 4948        &self,
 4949        buffer: &Entity<Buffer>,
 4950        check: F,
 4951        cx: &App,
 4952    ) -> bool
 4953    where
 4954        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4955    {
 4956        let Some(language) = buffer.read(cx).language().cloned() else {
 4957            return false;
 4958        };
 4959        let registered_language_servers = self
 4960            .languages
 4961            .lsp_adapters(&language.name())
 4962            .into_iter()
 4963            .map(|lsp_adapter| lsp_adapter.name())
 4964            .collect::<HashSet<_>>();
 4965        self.language_server_statuses
 4966            .iter()
 4967            .filter_map(|(server_id, server_status)| {
 4968                // Include servers that are either registered for this language OR
 4969                // available to be loaded (for SSH remote mode where adapters like
 4970                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4971                // but only loaded on the server side)
 4972                let is_relevant = registered_language_servers.contains(&server_status.name)
 4973                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4974                is_relevant.then_some(server_id)
 4975            })
 4976            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4977            .any(check)
 4978    }
 4979
 4980    fn all_capable_for_proto_request<F>(
 4981        &self,
 4982        buffer: &Entity<Buffer>,
 4983        mut check: F,
 4984        cx: &App,
 4985    ) -> Vec<(lsp::LanguageServerId, lsp::LanguageServerName)>
 4986    where
 4987        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4988    {
 4989        let Some(language) = buffer.read(cx).language().cloned() else {
 4990            return Vec::default();
 4991        };
 4992        let registered_language_servers = self
 4993            .languages
 4994            .lsp_adapters(&language.name())
 4995            .into_iter()
 4996            .map(|lsp_adapter| lsp_adapter.name())
 4997            .collect::<HashSet<_>>();
 4998        self.language_server_statuses
 4999            .iter()
 5000            .filter_map(|(server_id, server_status)| {
 5001                // Include servers that are either registered for this language OR
 5002                // available to be loaded (for SSH remote mode where adapters like
 5003                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 5004                // but only loaded on the server side)
 5005                let is_relevant = registered_language_servers.contains(&server_status.name)
 5006                    || self.languages.is_lsp_adapter_available(&server_status.name);
 5007                is_relevant.then_some((server_id, &server_status.name))
 5008            })
 5009            .filter_map(|(server_id, server_name)| {
 5010                self.lsp_server_capabilities
 5011                    .get(server_id)
 5012                    .map(|c| (server_id, server_name, c))
 5013            })
 5014            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 5015            .map(|(server_id, server_name, _)| (*server_id, server_name.clone()))
 5016            .collect()
 5017    }
 5018
 5019    pub fn request_lsp<R>(
 5020        &mut self,
 5021        buffer: Entity<Buffer>,
 5022        server: LanguageServerToQuery,
 5023        request: R,
 5024        cx: &mut Context<Self>,
 5025    ) -> Task<Result<R::Response>>
 5026    where
 5027        R: LspCommand,
 5028        <R::LspRequest as lsp::request::Request>::Result: Send,
 5029        <R::LspRequest as lsp::request::Request>::Params: Send,
 5030    {
 5031        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 5032            return self.send_lsp_proto_request(
 5033                buffer,
 5034                upstream_client,
 5035                upstream_project_id,
 5036                request,
 5037                cx,
 5038            );
 5039        }
 5040
 5041        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 5042            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 5043                local
 5044                    .language_servers_for_buffer(buffer, cx)
 5045                    .find(|(_, server)| {
 5046                        request.check_capabilities(server.adapter_server_capabilities())
 5047                    })
 5048                    .map(|(_, server)| server.clone())
 5049            }),
 5050            LanguageServerToQuery::Other(id) => self
 5051                .language_server_for_local_buffer(buffer, id, cx)
 5052                .and_then(|(_, server)| {
 5053                    request
 5054                        .check_capabilities(server.adapter_server_capabilities())
 5055                        .then(|| Arc::clone(server))
 5056                }),
 5057        }) else {
 5058            return Task::ready(Ok(Default::default()));
 5059        };
 5060
 5061        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 5062
 5063        let Some(file) = file else {
 5064            return Task::ready(Ok(Default::default()));
 5065        };
 5066
 5067        let lsp_params = match request.to_lsp_params_or_response(
 5068            &file.abs_path(cx),
 5069            buffer.read(cx),
 5070            &language_server,
 5071            cx,
 5072        ) {
 5073            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 5074            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 5075            Err(err) => {
 5076                let message = format!(
 5077                    "{} via {} failed: {}",
 5078                    request.display_name(),
 5079                    language_server.name(),
 5080                    err
 5081                );
 5082                // rust-analyzer likes to error with this when its still loading up
 5083                if !message.ends_with("content modified") {
 5084                    log::warn!("{message}");
 5085                }
 5086                return Task::ready(Err(anyhow!(message)));
 5087            }
 5088        };
 5089
 5090        let status = request.status();
 5091        let request_timeout = ProjectSettings::get_global(cx)
 5092            .global_lsp_settings
 5093            .get_request_timeout();
 5094
 5095        cx.spawn(async move |this, cx| {
 5096            let lsp_request = language_server.request::<R::LspRequest>(lsp_params, request_timeout);
 5097
 5098            let id = lsp_request.id();
 5099            let _cleanup = if status.is_some() {
 5100                cx.update(|cx| {
 5101                    this.update(cx, |this, cx| {
 5102                        this.on_lsp_work_start(
 5103                            language_server.server_id(),
 5104                            ProgressToken::Number(id),
 5105                            LanguageServerProgress {
 5106                                is_disk_based_diagnostics_progress: false,
 5107                                is_cancellable: false,
 5108                                title: None,
 5109                                message: status.clone(),
 5110                                percentage: None,
 5111                                last_update_at: cx.background_executor().now(),
 5112                            },
 5113                            cx,
 5114                        );
 5115                    })
 5116                })
 5117                .log_err();
 5118
 5119                Some(defer(|| {
 5120                    cx.update(|cx| {
 5121                        this.update(cx, |this, cx| {
 5122                            this.on_lsp_work_end(
 5123                                language_server.server_id(),
 5124                                ProgressToken::Number(id),
 5125                                cx,
 5126                            );
 5127                        })
 5128                    })
 5129                    .log_err();
 5130                }))
 5131            } else {
 5132                None
 5133            };
 5134
 5135            let result = lsp_request.await.into_response();
 5136
 5137            let response = result.map_err(|err| {
 5138                let message = format!(
 5139                    "{} via {} failed: {}",
 5140                    request.display_name(),
 5141                    language_server.name(),
 5142                    err
 5143                );
 5144                // rust-analyzer likes to error with this when its still loading up
 5145                if !message.ends_with("content modified") {
 5146                    log::warn!("{message}");
 5147                }
 5148                anyhow::anyhow!(message)
 5149            })?;
 5150
 5151            request
 5152                .response_from_lsp(
 5153                    response,
 5154                    this.upgrade().context("no app context")?,
 5155                    buffer,
 5156                    language_server.server_id(),
 5157                    cx.clone(),
 5158                )
 5159                .await
 5160        })
 5161    }
 5162
 5163    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 5164        let mut language_formatters_to_check = Vec::new();
 5165        for buffer in self.buffer_store.read(cx).buffers() {
 5166            let buffer = buffer.read(cx);
 5167            let settings = LanguageSettings::for_buffer(buffer, cx);
 5168            if buffer.language().is_some() {
 5169                let buffer_file = File::from_dyn(buffer.file());
 5170                language_formatters_to_check.push((
 5171                    buffer_file.map(|f| f.worktree_id(cx)),
 5172                    settings.into_owned(),
 5173                ));
 5174            }
 5175        }
 5176
 5177        self.request_workspace_config_refresh();
 5178
 5179        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 5180            prettier_store.update(cx, |prettier_store, cx| {
 5181                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 5182            })
 5183        }
 5184
 5185        let new_semantic_token_rules = crate::project_settings::ProjectSettings::get_global(cx)
 5186            .global_lsp_settings
 5187            .semantic_token_rules
 5188            .clone();
 5189        self.semantic_token_config
 5190            .update_rules(new_semantic_token_rules);
 5191        // Always clear cached stylizers so that changes to language-specific
 5192        // semantic token rules (e.g. from extension install/uninstall) are
 5193        // picked up. Stylizers are recreated lazily, so this is cheap.
 5194        self.semantic_token_config.clear_stylizers();
 5195
 5196        let new_global_semantic_tokens_mode =
 5197            all_language_settings(None, cx).defaults.semantic_tokens;
 5198        if self
 5199            .semantic_token_config
 5200            .update_global_mode(new_global_semantic_tokens_mode)
 5201        {
 5202            self.restart_all_language_servers(cx);
 5203        }
 5204
 5205        cx.notify();
 5206    }
 5207
 5208    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 5209        let buffer_store = self.buffer_store.clone();
 5210        let Some(local) = self.as_local_mut() else {
 5211            return;
 5212        };
 5213        let mut adapters = BTreeMap::default();
 5214        let get_adapter = {
 5215            let languages = local.languages.clone();
 5216            let environment = local.environment.clone();
 5217            let weak = local.weak.clone();
 5218            let worktree_store = local.worktree_store.clone();
 5219            let http_client = local.http_client.clone();
 5220            let fs = local.fs.clone();
 5221            move |worktree_id, cx: &mut App| {
 5222                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 5223                Some(LocalLspAdapterDelegate::new(
 5224                    languages.clone(),
 5225                    &environment,
 5226                    weak.clone(),
 5227                    &worktree,
 5228                    http_client.clone(),
 5229                    fs.clone(),
 5230                    cx,
 5231                ))
 5232            }
 5233        };
 5234
 5235        let mut messages_to_report = Vec::new();
 5236        let (new_tree, to_stop) = {
 5237            let mut rebase = local.lsp_tree.rebase();
 5238            let buffers = buffer_store
 5239                .read(cx)
 5240                .buffers()
 5241                .filter_map(|buffer| {
 5242                    let raw_buffer = buffer.read(cx);
 5243                    if !local
 5244                        .registered_buffers
 5245                        .contains_key(&raw_buffer.remote_id())
 5246                    {
 5247                        return None;
 5248                    }
 5249                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5250                    let language = raw_buffer.language().cloned()?;
 5251                    Some((file, language, raw_buffer.remote_id()))
 5252                })
 5253                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5254            for (file, language, buffer_id) in buffers {
 5255                let worktree_id = file.worktree_id(cx);
 5256                let Some(worktree) = local
 5257                    .worktree_store
 5258                    .read(cx)
 5259                    .worktree_for_id(worktree_id, cx)
 5260                else {
 5261                    continue;
 5262                };
 5263
 5264                if let Some((_, apply)) = local.reuse_existing_language_server(
 5265                    rebase.server_tree(),
 5266                    &worktree,
 5267                    &language.name(),
 5268                    cx,
 5269                ) {
 5270                    (apply)(rebase.server_tree());
 5271                } else if let Some(lsp_delegate) = adapters
 5272                    .entry(worktree_id)
 5273                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5274                    .clone()
 5275                {
 5276                    let delegate =
 5277                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5278                    let path = file
 5279                        .path()
 5280                        .parent()
 5281                        .map(Arc::from)
 5282                        .unwrap_or_else(|| file.path().clone());
 5283                    let worktree_path = ProjectPath { worktree_id, path };
 5284                    let abs_path = file.abs_path(cx);
 5285                    let nodes = rebase
 5286                        .walk(
 5287                            worktree_path,
 5288                            language.name(),
 5289                            language.manifest(),
 5290                            delegate.clone(),
 5291                            cx,
 5292                        )
 5293                        .collect::<Vec<_>>();
 5294                    for node in nodes {
 5295                        let server_id = node.server_id_or_init(|disposition| {
 5296                            let path = &disposition.path;
 5297                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5298                            let key = LanguageServerSeed {
 5299                                worktree_id,
 5300                                name: disposition.server_name.clone(),
 5301                                settings: LanguageServerSeedSettings {
 5302                                    binary: disposition.settings.binary.clone(),
 5303                                    initialization_options: disposition
 5304                                        .settings
 5305                                        .initialization_options
 5306                                        .clone(),
 5307                                },
 5308                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5309                                    path.worktree_id,
 5310                                    &path.path,
 5311                                    language.name(),
 5312                                ),
 5313                            };
 5314                            local.language_server_ids.remove(&key);
 5315
 5316                            let server_id = local.get_or_insert_language_server(
 5317                                &worktree,
 5318                                lsp_delegate.clone(),
 5319                                disposition,
 5320                                &language.name(),
 5321                                cx,
 5322                            );
 5323                            if let Some(state) = local.language_servers.get(&server_id)
 5324                                && let Ok(uri) = uri
 5325                            {
 5326                                state.add_workspace_folder(uri);
 5327                            };
 5328                            server_id
 5329                        });
 5330
 5331                        if let Some(language_server_id) = server_id {
 5332                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5333                                language_server_id,
 5334                                name: node.name(),
 5335                                message:
 5336                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5337                                        proto::RegisteredForBuffer {
 5338                                            buffer_abs_path: abs_path
 5339                                                .to_string_lossy()
 5340                                                .into_owned(),
 5341                                            buffer_id: buffer_id.to_proto(),
 5342                                        },
 5343                                    ),
 5344                            });
 5345                        }
 5346                    }
 5347                } else {
 5348                    continue;
 5349                }
 5350            }
 5351            rebase.finish()
 5352        };
 5353        for message in messages_to_report {
 5354            cx.emit(message);
 5355        }
 5356        local.lsp_tree = new_tree;
 5357        for (id, _) in to_stop {
 5358            self.stop_local_language_server(id, cx).detach();
 5359        }
 5360    }
 5361
 5362    pub fn apply_code_action(
 5363        &self,
 5364        buffer_handle: Entity<Buffer>,
 5365        mut action: CodeAction,
 5366        push_to_history: bool,
 5367        cx: &mut Context<Self>,
 5368    ) -> Task<Result<ProjectTransaction>> {
 5369        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5370            let request = proto::ApplyCodeAction {
 5371                project_id,
 5372                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5373                action: Some(Self::serialize_code_action(&action)),
 5374            };
 5375            let buffer_store = self.buffer_store();
 5376            cx.spawn(async move |_, cx| {
 5377                let response = upstream_client
 5378                    .request(request)
 5379                    .await?
 5380                    .transaction
 5381                    .context("missing transaction")?;
 5382
 5383                buffer_store
 5384                    .update(cx, |buffer_store, cx| {
 5385                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5386                    })
 5387                    .await
 5388            })
 5389        } else if self.mode.is_local() {
 5390            let Some((_, lang_server, request_timeout)) = buffer_handle.update(cx, |buffer, cx| {
 5391                let request_timeout = ProjectSettings::get_global(cx)
 5392                    .global_lsp_settings
 5393                    .get_request_timeout();
 5394                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5395                    .map(|(adapter, server)| (adapter.clone(), server.clone(), request_timeout))
 5396            }) else {
 5397                return Task::ready(Ok(ProjectTransaction::default()));
 5398            };
 5399
 5400            cx.spawn(async move |this, cx| {
 5401                LocalLspStore::try_resolve_code_action(&lang_server, &mut action, request_timeout)
 5402                    .await
 5403                    .context("resolving a code action")?;
 5404                if let Some(edit) = action.lsp_action.edit()
 5405                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5406                        return LocalLspStore::deserialize_workspace_edit(
 5407                            this.upgrade().context("no app present")?,
 5408                            edit.clone(),
 5409                            push_to_history,
 5410
 5411                            lang_server.clone(),
 5412                            cx,
 5413                        )
 5414                        .await;
 5415                    }
 5416
 5417                let Some(command) = action.lsp_action.command() else {
 5418                    return Ok(ProjectTransaction::default())
 5419                };
 5420
 5421                let server_capabilities = lang_server.capabilities();
 5422                let available_commands = server_capabilities
 5423                    .execute_command_provider
 5424                    .as_ref()
 5425                    .map(|options| options.commands.as_slice())
 5426                    .unwrap_or_default();
 5427
 5428                if !available_commands.contains(&command.command) {
 5429                    log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5430                    return Ok(ProjectTransaction::default())
 5431                }
 5432
 5433                let request_timeout = cx.update(|app|
 5434                    ProjectSettings::get_global(app)
 5435                    .global_lsp_settings
 5436                    .get_request_timeout()
 5437                );
 5438
 5439                this.update(cx, |this, _| {
 5440                    this.as_local_mut()
 5441                        .unwrap()
 5442                        .last_workspace_edits_by_language_server
 5443                        .remove(&lang_server.server_id());
 5444                })?;
 5445
 5446                let _result = lang_server
 5447                    .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5448                        command: command.command.clone(),
 5449                        arguments: command.arguments.clone().unwrap_or_default(),
 5450                        ..lsp::ExecuteCommandParams::default()
 5451                    }, request_timeout)
 5452                    .await.into_response()
 5453                    .context("execute command")?;
 5454
 5455                return this.update(cx, |this, _| {
 5456                    this.as_local_mut()
 5457                        .unwrap()
 5458                        .last_workspace_edits_by_language_server
 5459                        .remove(&lang_server.server_id())
 5460                        .unwrap_or_default()
 5461                });
 5462            })
 5463        } else {
 5464            Task::ready(Err(anyhow!("no upstream client and not local")))
 5465        }
 5466    }
 5467
 5468    pub fn apply_code_action_kind(
 5469        &mut self,
 5470        buffers: HashSet<Entity<Buffer>>,
 5471        kind: CodeActionKind,
 5472        push_to_history: bool,
 5473        cx: &mut Context<Self>,
 5474    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5475        if self.as_local().is_some() {
 5476            cx.spawn(async move |lsp_store, cx| {
 5477                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5478                let result = LocalLspStore::execute_code_action_kind_locally(
 5479                    lsp_store.clone(),
 5480                    buffers,
 5481                    kind,
 5482                    push_to_history,
 5483                    cx,
 5484                )
 5485                .await;
 5486                lsp_store.update(cx, |lsp_store, _| {
 5487                    lsp_store.update_last_formatting_failure(&result);
 5488                })?;
 5489                result
 5490            })
 5491        } else if let Some((client, project_id)) = self.upstream_client() {
 5492            let buffer_store = self.buffer_store();
 5493            cx.spawn(async move |lsp_store, cx| {
 5494                let result = client
 5495                    .request(proto::ApplyCodeActionKind {
 5496                        project_id,
 5497                        kind: kind.as_str().to_owned(),
 5498                        buffer_ids: buffers
 5499                            .iter()
 5500                            .map(|buffer| {
 5501                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5502                            })
 5503                            .collect(),
 5504                    })
 5505                    .await
 5506                    .and_then(|result| result.transaction.context("missing transaction"));
 5507                lsp_store.update(cx, |lsp_store, _| {
 5508                    lsp_store.update_last_formatting_failure(&result);
 5509                })?;
 5510
 5511                let transaction_response = result?;
 5512                buffer_store
 5513                    .update(cx, |buffer_store, cx| {
 5514                        buffer_store.deserialize_project_transaction(
 5515                            transaction_response,
 5516                            push_to_history,
 5517                            cx,
 5518                        )
 5519                    })
 5520                    .await
 5521            })
 5522        } else {
 5523            Task::ready(Ok(ProjectTransaction::default()))
 5524        }
 5525    }
 5526
 5527    pub fn resolved_hint(
 5528        &mut self,
 5529        buffer_id: BufferId,
 5530        id: InlayId,
 5531        cx: &mut Context<Self>,
 5532    ) -> Option<ResolvedHint> {
 5533        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5534
 5535        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5536        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5537        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5538        let (server_id, resolve_data) = match &hint.resolve_state {
 5539            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5540            ResolveState::Resolving => {
 5541                return Some(ResolvedHint::Resolving(
 5542                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5543                ));
 5544            }
 5545            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5546        };
 5547
 5548        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5549        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5550        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5551            id,
 5552            cx.spawn(async move |lsp_store, cx| {
 5553                let resolved_hint = resolve_task.await;
 5554                lsp_store
 5555                    .update(cx, |lsp_store, _| {
 5556                        if let Some(old_inlay_hint) = lsp_store
 5557                            .lsp_data
 5558                            .get_mut(&buffer_id)
 5559                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5560                        {
 5561                            match resolved_hint {
 5562                                Ok(resolved_hint) => {
 5563                                    *old_inlay_hint = resolved_hint;
 5564                                }
 5565                                Err(e) => {
 5566                                    old_inlay_hint.resolve_state =
 5567                                        ResolveState::CanResolve(server_id, resolve_data);
 5568                                    log::error!("Inlay hint resolve failed: {e:#}");
 5569                                }
 5570                            }
 5571                        }
 5572                    })
 5573                    .ok();
 5574            })
 5575            .shared(),
 5576        );
 5577        debug_assert!(
 5578            previous_task.is_none(),
 5579            "Did not change hint's resolve state after spawning its resolve"
 5580        );
 5581        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5582        None
 5583    }
 5584
 5585    pub(crate) fn linked_edits(
 5586        &mut self,
 5587        buffer: &Entity<Buffer>,
 5588        position: Anchor,
 5589        cx: &mut Context<Self>,
 5590    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5591        let snapshot = buffer.read(cx).snapshot();
 5592        let scope = snapshot.language_scope_at(position);
 5593        let Some(server_id) = self
 5594            .as_local()
 5595            .and_then(|local| {
 5596                buffer.update(cx, |buffer, cx| {
 5597                    local
 5598                        .language_servers_for_buffer(buffer, cx)
 5599                        .filter(|(_, server)| {
 5600                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5601                        })
 5602                        .filter(|(adapter, _)| {
 5603                            scope
 5604                                .as_ref()
 5605                                .map(|scope| scope.language_allowed(&adapter.name))
 5606                                .unwrap_or(true)
 5607                        })
 5608                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5609                        .next()
 5610                })
 5611            })
 5612            .or_else(|| {
 5613                self.upstream_client()
 5614                    .is_some()
 5615                    .then_some(LanguageServerToQuery::FirstCapable)
 5616            })
 5617            .filter(|_| {
 5618                maybe!({
 5619                    buffer.read(cx).language_at(position)?;
 5620                    Some(
 5621                        LanguageSettings::for_buffer_at(&buffer.read(cx), position, cx)
 5622                            .linked_edits,
 5623                    )
 5624                }) == Some(true)
 5625            })
 5626        else {
 5627            return Task::ready(Ok(Vec::new()));
 5628        };
 5629
 5630        self.request_lsp(
 5631            buffer.clone(),
 5632            server_id,
 5633            LinkedEditingRange { position },
 5634            cx,
 5635        )
 5636    }
 5637
 5638    fn apply_on_type_formatting(
 5639        &mut self,
 5640        buffer: Entity<Buffer>,
 5641        position: Anchor,
 5642        trigger: String,
 5643        cx: &mut Context<Self>,
 5644    ) -> Task<Result<Option<Transaction>>> {
 5645        if let Some((client, project_id)) = self.upstream_client() {
 5646            if !self.check_if_capable_for_proto_request(
 5647                &buffer,
 5648                |capabilities| {
 5649                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5650                },
 5651                cx,
 5652            ) {
 5653                return Task::ready(Ok(None));
 5654            }
 5655            let request = proto::OnTypeFormatting {
 5656                project_id,
 5657                buffer_id: buffer.read(cx).remote_id().into(),
 5658                position: Some(serialize_anchor(&position)),
 5659                trigger,
 5660                version: serialize_version(&buffer.read(cx).version()),
 5661            };
 5662            cx.background_spawn(async move {
 5663                client
 5664                    .request(request)
 5665                    .await?
 5666                    .transaction
 5667                    .map(language::proto::deserialize_transaction)
 5668                    .transpose()
 5669            })
 5670        } else if let Some(local) = self.as_local_mut() {
 5671            let buffer_id = buffer.read(cx).remote_id();
 5672            local.buffers_being_formatted.insert(buffer_id);
 5673            cx.spawn(async move |this, cx| {
 5674                let _cleanup = defer({
 5675                    let this = this.clone();
 5676                    let mut cx = cx.clone();
 5677                    move || {
 5678                        this.update(&mut cx, |this, _| {
 5679                            if let Some(local) = this.as_local_mut() {
 5680                                local.buffers_being_formatted.remove(&buffer_id);
 5681                            }
 5682                        })
 5683                        .ok();
 5684                    }
 5685                });
 5686
 5687                buffer
 5688                    .update(cx, |buffer, _| {
 5689                        buffer.wait_for_edits(Some(position.timestamp()))
 5690                    })
 5691                    .await?;
 5692                this.update(cx, |this, cx| {
 5693                    let position = position.to_point_utf16(buffer.read(cx));
 5694                    this.on_type_format(buffer, position, trigger, false, cx)
 5695                })?
 5696                .await
 5697            })
 5698        } else {
 5699            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5700        }
 5701    }
 5702
 5703    pub fn on_type_format<T: ToPointUtf16>(
 5704        &mut self,
 5705        buffer: Entity<Buffer>,
 5706        position: T,
 5707        trigger: String,
 5708        push_to_history: bool,
 5709        cx: &mut Context<Self>,
 5710    ) -> Task<Result<Option<Transaction>>> {
 5711        let position = position.to_point_utf16(buffer.read(cx));
 5712        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5713    }
 5714
 5715    fn on_type_format_impl(
 5716        &mut self,
 5717        buffer: Entity<Buffer>,
 5718        position: PointUtf16,
 5719        trigger: String,
 5720        push_to_history: bool,
 5721        cx: &mut Context<Self>,
 5722    ) -> Task<Result<Option<Transaction>>> {
 5723        let options = buffer.update(cx, |buffer, cx| {
 5724            lsp_command::lsp_formatting_options(
 5725                LanguageSettings::for_buffer_at(buffer, position, cx).as_ref(),
 5726            )
 5727        });
 5728
 5729        cx.spawn(async move |this, cx| {
 5730            if let Some(waiter) =
 5731                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5732            {
 5733                waiter.await?;
 5734            }
 5735            cx.update(|cx| {
 5736                this.update(cx, |this, cx| {
 5737                    this.request_lsp(
 5738                        buffer.clone(),
 5739                        LanguageServerToQuery::FirstCapable,
 5740                        OnTypeFormatting {
 5741                            position,
 5742                            trigger,
 5743                            options,
 5744                            push_to_history,
 5745                        },
 5746                        cx,
 5747                    )
 5748                })
 5749            })?
 5750            .await
 5751        })
 5752    }
 5753
 5754    pub fn definitions(
 5755        &mut self,
 5756        buffer: &Entity<Buffer>,
 5757        position: PointUtf16,
 5758        cx: &mut Context<Self>,
 5759    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5760        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5761            let request = GetDefinitions { position };
 5762            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5763                return Task::ready(Ok(None));
 5764            }
 5765
 5766            let request_timeout = ProjectSettings::get_global(cx)
 5767                .global_lsp_settings
 5768                .get_request_timeout();
 5769
 5770            let request_task = upstream_client.request_lsp(
 5771                project_id,
 5772                None,
 5773                request_timeout,
 5774                cx.background_executor().clone(),
 5775                request.to_proto(project_id, buffer.read(cx)),
 5776            );
 5777            let buffer = buffer.clone();
 5778            cx.spawn(async move |weak_lsp_store, cx| {
 5779                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5780                    return Ok(None);
 5781                };
 5782                let Some(responses) = request_task.await? else {
 5783                    return Ok(None);
 5784                };
 5785                let actions = join_all(responses.payload.into_iter().map(|response| {
 5786                    GetDefinitions { position }.response_from_proto(
 5787                        response.response,
 5788                        lsp_store.clone(),
 5789                        buffer.clone(),
 5790                        cx.clone(),
 5791                    )
 5792                }))
 5793                .await;
 5794
 5795                Ok(Some(
 5796                    actions
 5797                        .into_iter()
 5798                        .collect::<Result<Vec<Vec<_>>>>()?
 5799                        .into_iter()
 5800                        .flatten()
 5801                        .dedup()
 5802                        .collect(),
 5803                ))
 5804            })
 5805        } else {
 5806            let definitions_task = self.request_multiple_lsp_locally(
 5807                buffer,
 5808                Some(position),
 5809                GetDefinitions { position },
 5810                cx,
 5811            );
 5812            cx.background_spawn(async move {
 5813                Ok(Some(
 5814                    definitions_task
 5815                        .await
 5816                        .into_iter()
 5817                        .flat_map(|(_, definitions)| definitions)
 5818                        .dedup()
 5819                        .collect(),
 5820                ))
 5821            })
 5822        }
 5823    }
 5824
 5825    pub fn declarations(
 5826        &mut self,
 5827        buffer: &Entity<Buffer>,
 5828        position: PointUtf16,
 5829        cx: &mut Context<Self>,
 5830    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5831        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5832            let request = GetDeclarations { position };
 5833            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5834                return Task::ready(Ok(None));
 5835            }
 5836            let request_timeout = ProjectSettings::get_global(cx)
 5837                .global_lsp_settings
 5838                .get_request_timeout();
 5839            let request_task = upstream_client.request_lsp(
 5840                project_id,
 5841                None,
 5842                request_timeout,
 5843                cx.background_executor().clone(),
 5844                request.to_proto(project_id, buffer.read(cx)),
 5845            );
 5846            let buffer = buffer.clone();
 5847            cx.spawn(async move |weak_lsp_store, cx| {
 5848                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5849                    return Ok(None);
 5850                };
 5851                let Some(responses) = request_task.await? else {
 5852                    return Ok(None);
 5853                };
 5854                let actions = join_all(responses.payload.into_iter().map(|response| {
 5855                    GetDeclarations { position }.response_from_proto(
 5856                        response.response,
 5857                        lsp_store.clone(),
 5858                        buffer.clone(),
 5859                        cx.clone(),
 5860                    )
 5861                }))
 5862                .await;
 5863
 5864                Ok(Some(
 5865                    actions
 5866                        .into_iter()
 5867                        .collect::<Result<Vec<Vec<_>>>>()?
 5868                        .into_iter()
 5869                        .flatten()
 5870                        .dedup()
 5871                        .collect(),
 5872                ))
 5873            })
 5874        } else {
 5875            let declarations_task = self.request_multiple_lsp_locally(
 5876                buffer,
 5877                Some(position),
 5878                GetDeclarations { position },
 5879                cx,
 5880            );
 5881            cx.background_spawn(async move {
 5882                Ok(Some(
 5883                    declarations_task
 5884                        .await
 5885                        .into_iter()
 5886                        .flat_map(|(_, declarations)| declarations)
 5887                        .dedup()
 5888                        .collect(),
 5889                ))
 5890            })
 5891        }
 5892    }
 5893
 5894    pub fn type_definitions(
 5895        &mut self,
 5896        buffer: &Entity<Buffer>,
 5897        position: PointUtf16,
 5898        cx: &mut Context<Self>,
 5899    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5900        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5901            let request = GetTypeDefinitions { position };
 5902            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5903                return Task::ready(Ok(None));
 5904            }
 5905            let request_timeout = ProjectSettings::get_global(cx)
 5906                .global_lsp_settings
 5907                .get_request_timeout();
 5908            let request_task = upstream_client.request_lsp(
 5909                project_id,
 5910                None,
 5911                request_timeout,
 5912                cx.background_executor().clone(),
 5913                request.to_proto(project_id, buffer.read(cx)),
 5914            );
 5915            let buffer = buffer.clone();
 5916            cx.spawn(async move |weak_lsp_store, cx| {
 5917                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5918                    return Ok(None);
 5919                };
 5920                let Some(responses) = request_task.await? else {
 5921                    return Ok(None);
 5922                };
 5923                let actions = join_all(responses.payload.into_iter().map(|response| {
 5924                    GetTypeDefinitions { position }.response_from_proto(
 5925                        response.response,
 5926                        lsp_store.clone(),
 5927                        buffer.clone(),
 5928                        cx.clone(),
 5929                    )
 5930                }))
 5931                .await;
 5932
 5933                Ok(Some(
 5934                    actions
 5935                        .into_iter()
 5936                        .collect::<Result<Vec<Vec<_>>>>()?
 5937                        .into_iter()
 5938                        .flatten()
 5939                        .dedup()
 5940                        .collect(),
 5941                ))
 5942            })
 5943        } else {
 5944            let type_definitions_task = self.request_multiple_lsp_locally(
 5945                buffer,
 5946                Some(position),
 5947                GetTypeDefinitions { position },
 5948                cx,
 5949            );
 5950            cx.background_spawn(async move {
 5951                Ok(Some(
 5952                    type_definitions_task
 5953                        .await
 5954                        .into_iter()
 5955                        .flat_map(|(_, type_definitions)| type_definitions)
 5956                        .dedup()
 5957                        .collect(),
 5958                ))
 5959            })
 5960        }
 5961    }
 5962
 5963    pub fn implementations(
 5964        &mut self,
 5965        buffer: &Entity<Buffer>,
 5966        position: PointUtf16,
 5967        cx: &mut Context<Self>,
 5968    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5969        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5970            let request = GetImplementations { position };
 5971            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5972                return Task::ready(Ok(None));
 5973            }
 5974
 5975            let request_timeout = ProjectSettings::get_global(cx)
 5976                .global_lsp_settings
 5977                .get_request_timeout();
 5978            let request_task = upstream_client.request_lsp(
 5979                project_id,
 5980                None,
 5981                request_timeout,
 5982                cx.background_executor().clone(),
 5983                request.to_proto(project_id, buffer.read(cx)),
 5984            );
 5985            let buffer = buffer.clone();
 5986            cx.spawn(async move |weak_lsp_store, cx| {
 5987                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5988                    return Ok(None);
 5989                };
 5990                let Some(responses) = request_task.await? else {
 5991                    return Ok(None);
 5992                };
 5993                let actions = join_all(responses.payload.into_iter().map(|response| {
 5994                    GetImplementations { position }.response_from_proto(
 5995                        response.response,
 5996                        lsp_store.clone(),
 5997                        buffer.clone(),
 5998                        cx.clone(),
 5999                    )
 6000                }))
 6001                .await;
 6002
 6003                Ok(Some(
 6004                    actions
 6005                        .into_iter()
 6006                        .collect::<Result<Vec<Vec<_>>>>()?
 6007                        .into_iter()
 6008                        .flatten()
 6009                        .dedup()
 6010                        .collect(),
 6011                ))
 6012            })
 6013        } else {
 6014            let implementations_task = self.request_multiple_lsp_locally(
 6015                buffer,
 6016                Some(position),
 6017                GetImplementations { position },
 6018                cx,
 6019            );
 6020            cx.background_spawn(async move {
 6021                Ok(Some(
 6022                    implementations_task
 6023                        .await
 6024                        .into_iter()
 6025                        .flat_map(|(_, implementations)| implementations)
 6026                        .dedup()
 6027                        .collect(),
 6028                ))
 6029            })
 6030        }
 6031    }
 6032
 6033    pub fn references(
 6034        &mut self,
 6035        buffer: &Entity<Buffer>,
 6036        position: PointUtf16,
 6037        cx: &mut Context<Self>,
 6038    ) -> Task<Result<Option<Vec<Location>>>> {
 6039        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6040            let request = GetReferences { position };
 6041            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6042                return Task::ready(Ok(None));
 6043            }
 6044
 6045            let request_timeout = ProjectSettings::get_global(cx)
 6046                .global_lsp_settings
 6047                .get_request_timeout();
 6048            let request_task = upstream_client.request_lsp(
 6049                project_id,
 6050                None,
 6051                request_timeout,
 6052                cx.background_executor().clone(),
 6053                request.to_proto(project_id, buffer.read(cx)),
 6054            );
 6055            let buffer = buffer.clone();
 6056            cx.spawn(async move |weak_lsp_store, cx| {
 6057                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6058                    return Ok(None);
 6059                };
 6060                let Some(responses) = request_task.await? else {
 6061                    return Ok(None);
 6062                };
 6063
 6064                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 6065                    GetReferences { position }.response_from_proto(
 6066                        lsp_response.response,
 6067                        lsp_store.clone(),
 6068                        buffer.clone(),
 6069                        cx.clone(),
 6070                    )
 6071                }))
 6072                .await
 6073                .into_iter()
 6074                .collect::<Result<Vec<Vec<_>>>>()?
 6075                .into_iter()
 6076                .flatten()
 6077                .dedup()
 6078                .collect();
 6079                Ok(Some(locations))
 6080            })
 6081        } else {
 6082            let references_task = self.request_multiple_lsp_locally(
 6083                buffer,
 6084                Some(position),
 6085                GetReferences { position },
 6086                cx,
 6087            );
 6088            cx.background_spawn(async move {
 6089                Ok(Some(
 6090                    references_task
 6091                        .await
 6092                        .into_iter()
 6093                        .flat_map(|(_, references)| references)
 6094                        .dedup()
 6095                        .collect(),
 6096                ))
 6097            })
 6098        }
 6099    }
 6100
 6101    pub fn code_actions(
 6102        &mut self,
 6103        buffer: &Entity<Buffer>,
 6104        range: Range<Anchor>,
 6105        kinds: Option<Vec<CodeActionKind>>,
 6106        cx: &mut Context<Self>,
 6107    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6108        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6109            let request = GetCodeActions {
 6110                range: range.clone(),
 6111                kinds: kinds.clone(),
 6112            };
 6113            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6114                return Task::ready(Ok(None));
 6115            }
 6116            let request_timeout = ProjectSettings::get_global(cx)
 6117                .global_lsp_settings
 6118                .get_request_timeout();
 6119            let request_task = upstream_client.request_lsp(
 6120                project_id,
 6121                None,
 6122                request_timeout,
 6123                cx.background_executor().clone(),
 6124                request.to_proto(project_id, buffer.read(cx)),
 6125            );
 6126            let buffer = buffer.clone();
 6127            cx.spawn(async move |weak_lsp_store, cx| {
 6128                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6129                    return Ok(None);
 6130                };
 6131                let Some(responses) = request_task.await? else {
 6132                    return Ok(None);
 6133                };
 6134                let actions = join_all(responses.payload.into_iter().map(|response| {
 6135                    GetCodeActions {
 6136                        range: range.clone(),
 6137                        kinds: kinds.clone(),
 6138                    }
 6139                    .response_from_proto(
 6140                        response.response,
 6141                        lsp_store.clone(),
 6142                        buffer.clone(),
 6143                        cx.clone(),
 6144                    )
 6145                }))
 6146                .await;
 6147
 6148                Ok(Some(
 6149                    actions
 6150                        .into_iter()
 6151                        .collect::<Result<Vec<Vec<_>>>>()?
 6152                        .into_iter()
 6153                        .flatten()
 6154                        .collect(),
 6155                ))
 6156            })
 6157        } else {
 6158            let all_actions_task = self.request_multiple_lsp_locally(
 6159                buffer,
 6160                Some(range.start),
 6161                GetCodeActions { range, kinds },
 6162                cx,
 6163            );
 6164            cx.background_spawn(async move {
 6165                Ok(Some(
 6166                    all_actions_task
 6167                        .await
 6168                        .into_iter()
 6169                        .flat_map(|(_, actions)| actions)
 6170                        .collect(),
 6171                ))
 6172            })
 6173        }
 6174    }
 6175
 6176    #[inline(never)]
 6177    pub fn completions(
 6178        &self,
 6179        buffer: &Entity<Buffer>,
 6180        position: PointUtf16,
 6181        context: CompletionContext,
 6182        cx: &mut Context<Self>,
 6183    ) -> Task<Result<Vec<CompletionResponse>>> {
 6184        let language_registry = self.languages.clone();
 6185
 6186        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6187            let snapshot = buffer.read(cx).snapshot();
 6188            let offset = position.to_offset(&snapshot);
 6189            let scope = snapshot.language_scope_at(offset);
 6190            let capable_lsps = self.all_capable_for_proto_request(
 6191                buffer,
 6192                |server_name, capabilities| {
 6193                    capabilities.completion_provider.is_some()
 6194                        && scope
 6195                            .as_ref()
 6196                            .map(|scope| scope.language_allowed(server_name))
 6197                            .unwrap_or(true)
 6198                },
 6199                cx,
 6200            );
 6201            if capable_lsps.is_empty() {
 6202                return Task::ready(Ok(Vec::new()));
 6203            }
 6204
 6205            let language = buffer.read(cx).language().cloned();
 6206
 6207            let buffer = buffer.clone();
 6208
 6209            cx.spawn(async move |this, cx| {
 6210                let requests = join_all(
 6211                    capable_lsps
 6212                        .into_iter()
 6213                        .map(|(id, server_name)| {
 6214                            let request = GetCompletions {
 6215                                position,
 6216                                context: context.clone(),
 6217                                server_id: Some(id),
 6218                            };
 6219                            let buffer = buffer.clone();
 6220                            let language = language.clone();
 6221                            let lsp_adapter = language.as_ref().and_then(|language| {
 6222                                let adapters = language_registry.lsp_adapters(&language.name());
 6223                                adapters
 6224                                    .iter()
 6225                                    .find(|adapter| adapter.name() == server_name)
 6226                                    .or_else(|| adapters.first())
 6227                                    .cloned()
 6228                            });
 6229                            let upstream_client = upstream_client.clone();
 6230                            let response = this
 6231                                .update(cx, |this, cx| {
 6232                                    this.send_lsp_proto_request(
 6233                                        buffer,
 6234                                        upstream_client,
 6235                                        project_id,
 6236                                        request,
 6237                                        cx,
 6238                                    )
 6239                                })
 6240                                .log_err();
 6241                            async move {
 6242                                let response = response?.await.log_err()?;
 6243
 6244                                let completions = populate_labels_for_completions(
 6245                                    response.completions,
 6246                                    language,
 6247                                    lsp_adapter,
 6248                                )
 6249                                .await;
 6250
 6251                                Some(CompletionResponse {
 6252                                    completions,
 6253                                    display_options: CompletionDisplayOptions::default(),
 6254                                    is_incomplete: response.is_incomplete,
 6255                                })
 6256                            }
 6257                        })
 6258                        .collect::<Vec<_>>(),
 6259                );
 6260                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6261            })
 6262        } else if let Some(local) = self.as_local() {
 6263            let snapshot = buffer.read(cx).snapshot();
 6264            let offset = position.to_offset(&snapshot);
 6265            let scope = snapshot.language_scope_at(offset);
 6266            let language = snapshot.language().cloned();
 6267            let completion_settings = LanguageSettings::for_buffer(&buffer.read(cx), cx)
 6268                .completions
 6269                .clone();
 6270            if !completion_settings.lsp {
 6271                return Task::ready(Ok(Vec::new()));
 6272            }
 6273
 6274            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6275                local
 6276                    .language_servers_for_buffer(buffer, cx)
 6277                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6278                    .filter(|(adapter, _)| {
 6279                        scope
 6280                            .as_ref()
 6281                            .map(|scope| scope.language_allowed(&adapter.name))
 6282                            .unwrap_or(true)
 6283                    })
 6284                    .map(|(_, server)| server.server_id())
 6285                    .collect()
 6286            });
 6287
 6288            let buffer = buffer.clone();
 6289            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6290            let lsp_timeout = if lsp_timeout > 0 {
 6291                Some(Duration::from_millis(lsp_timeout))
 6292            } else {
 6293                None
 6294            };
 6295            cx.spawn(async move |this,  cx| {
 6296                let mut tasks = Vec::with_capacity(server_ids.len());
 6297                this.update(cx, |lsp_store, cx| {
 6298                    for server_id in server_ids {
 6299                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6300                        let lsp_timeout = lsp_timeout
 6301                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6302                        let mut timeout = cx.background_spawn(async move {
 6303                            match lsp_timeout {
 6304                                Some(lsp_timeout) => {
 6305                                    lsp_timeout.await;
 6306                                    true
 6307                                },
 6308                                None => false,
 6309                            }
 6310                        }).fuse();
 6311                        let mut lsp_request = lsp_store.request_lsp(
 6312                            buffer.clone(),
 6313                            LanguageServerToQuery::Other(server_id),
 6314                            GetCompletions {
 6315                                position,
 6316                                context: context.clone(),
 6317                                server_id: Some(server_id),
 6318                            },
 6319                            cx,
 6320                        ).fuse();
 6321                        let new_task = cx.background_spawn(async move {
 6322                            select_biased! {
 6323                                response = lsp_request => anyhow::Ok(Some(response?)),
 6324                                timeout_happened = timeout => {
 6325                                    if timeout_happened {
 6326                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6327                                        Ok(None)
 6328                                    } else {
 6329                                        let completions = lsp_request.await?;
 6330                                        Ok(Some(completions))
 6331                                    }
 6332                                },
 6333                            }
 6334                        });
 6335                        tasks.push((lsp_adapter, new_task));
 6336                    }
 6337                })?;
 6338
 6339                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6340                    let completion_response = task.await.ok()??;
 6341                    let completions = populate_labels_for_completions(
 6342                            completion_response.completions,
 6343                            language.clone(),
 6344                            lsp_adapter,
 6345                        )
 6346                        .await;
 6347                    Some(CompletionResponse {
 6348                        completions,
 6349                        display_options: CompletionDisplayOptions::default(),
 6350                        is_incomplete: completion_response.is_incomplete,
 6351                    })
 6352                });
 6353
 6354                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6355
 6356                Ok(responses.into_iter().flatten().collect())
 6357            })
 6358        } else {
 6359            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6360        }
 6361    }
 6362
 6363    pub fn resolve_completions(
 6364        &self,
 6365        buffer: Entity<Buffer>,
 6366        completion_indices: Vec<usize>,
 6367        completions: Rc<RefCell<Box<[Completion]>>>,
 6368        cx: &mut Context<Self>,
 6369    ) -> Task<Result<bool>> {
 6370        let client = self.upstream_client();
 6371        let buffer_id = buffer.read(cx).remote_id();
 6372        let buffer_snapshot = buffer.read(cx).snapshot();
 6373
 6374        if !self.check_if_capable_for_proto_request(
 6375            &buffer,
 6376            GetCompletions::can_resolve_completions,
 6377            cx,
 6378        ) {
 6379            return Task::ready(Ok(false));
 6380        }
 6381        cx.spawn(async move |lsp_store, cx| {
 6382            let request_timeout = cx.update(|app| {
 6383                ProjectSettings::get_global(app)
 6384                    .global_lsp_settings
 6385                    .get_request_timeout()
 6386            });
 6387
 6388            let mut did_resolve = false;
 6389            if let Some((client, project_id)) = client {
 6390                for completion_index in completion_indices {
 6391                    let server_id = {
 6392                        let completion = &completions.borrow()[completion_index];
 6393                        completion.source.server_id()
 6394                    };
 6395                    if let Some(server_id) = server_id {
 6396                        if Self::resolve_completion_remote(
 6397                            project_id,
 6398                            server_id,
 6399                            buffer_id,
 6400                            completions.clone(),
 6401                            completion_index,
 6402                            client.clone(),
 6403                        )
 6404                        .await
 6405                        .log_err()
 6406                        .is_some()
 6407                        {
 6408                            did_resolve = true;
 6409                        }
 6410                    } else {
 6411                        resolve_word_completion(
 6412                            &buffer_snapshot,
 6413                            &mut completions.borrow_mut()[completion_index],
 6414                        );
 6415                    }
 6416                }
 6417            } else {
 6418                for completion_index in completion_indices {
 6419                    let server_id = {
 6420                        let completion = &completions.borrow()[completion_index];
 6421                        completion.source.server_id()
 6422                    };
 6423                    if let Some(server_id) = server_id {
 6424                        let server_and_adapter = lsp_store
 6425                            .read_with(cx, |lsp_store, _| {
 6426                                let server = lsp_store.language_server_for_id(server_id)?;
 6427                                let adapter =
 6428                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6429                                Some((server, adapter))
 6430                            })
 6431                            .ok()
 6432                            .flatten();
 6433                        let Some((server, adapter)) = server_and_adapter else {
 6434                            continue;
 6435                        };
 6436
 6437                        let resolved = Self::resolve_completion_local(
 6438                            server,
 6439                            completions.clone(),
 6440                            completion_index,
 6441                            request_timeout,
 6442                        )
 6443                        .await
 6444                        .log_err()
 6445                        .is_some();
 6446                        if resolved {
 6447                            Self::regenerate_completion_labels(
 6448                                adapter,
 6449                                &buffer_snapshot,
 6450                                completions.clone(),
 6451                                completion_index,
 6452                            )
 6453                            .await
 6454                            .log_err();
 6455                            did_resolve = true;
 6456                        }
 6457                    } else {
 6458                        resolve_word_completion(
 6459                            &buffer_snapshot,
 6460                            &mut completions.borrow_mut()[completion_index],
 6461                        );
 6462                    }
 6463                }
 6464            }
 6465
 6466            Ok(did_resolve)
 6467        })
 6468    }
 6469
 6470    async fn resolve_completion_local(
 6471        server: Arc<lsp::LanguageServer>,
 6472        completions: Rc<RefCell<Box<[Completion]>>>,
 6473        completion_index: usize,
 6474        request_timeout: Duration,
 6475    ) -> Result<()> {
 6476        let server_id = server.server_id();
 6477        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6478            return Ok(());
 6479        }
 6480
 6481        let request = {
 6482            let completion = &completions.borrow()[completion_index];
 6483            match &completion.source {
 6484                CompletionSource::Lsp {
 6485                    lsp_completion,
 6486                    resolved,
 6487                    server_id: completion_server_id,
 6488                    ..
 6489                } => {
 6490                    if *resolved {
 6491                        return Ok(());
 6492                    }
 6493                    anyhow::ensure!(
 6494                        server_id == *completion_server_id,
 6495                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6496                    );
 6497                    server.request::<lsp::request::ResolveCompletionItem>(
 6498                        *lsp_completion.clone(),
 6499                        request_timeout,
 6500                    )
 6501                }
 6502                CompletionSource::BufferWord { .. }
 6503                | CompletionSource::Dap { .. }
 6504                | CompletionSource::Custom => {
 6505                    return Ok(());
 6506                }
 6507            }
 6508        };
 6509        let resolved_completion = request
 6510            .await
 6511            .into_response()
 6512            .context("resolve completion")?;
 6513
 6514        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6515        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6516
 6517        let mut completions = completions.borrow_mut();
 6518        let completion = &mut completions[completion_index];
 6519        if let CompletionSource::Lsp {
 6520            lsp_completion,
 6521            resolved,
 6522            server_id: completion_server_id,
 6523            ..
 6524        } = &mut completion.source
 6525        {
 6526            if *resolved {
 6527                return Ok(());
 6528            }
 6529            anyhow::ensure!(
 6530                server_id == *completion_server_id,
 6531                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6532            );
 6533            **lsp_completion = resolved_completion;
 6534            *resolved = true;
 6535        }
 6536        Ok(())
 6537    }
 6538
 6539    async fn regenerate_completion_labels(
 6540        adapter: Arc<CachedLspAdapter>,
 6541        snapshot: &BufferSnapshot,
 6542        completions: Rc<RefCell<Box<[Completion]>>>,
 6543        completion_index: usize,
 6544    ) -> Result<()> {
 6545        let completion_item = completions.borrow()[completion_index]
 6546            .source
 6547            .lsp_completion(true)
 6548            .map(Cow::into_owned);
 6549        if let Some(lsp_documentation) = completion_item
 6550            .as_ref()
 6551            .and_then(|completion_item| completion_item.documentation.clone())
 6552        {
 6553            let mut completions = completions.borrow_mut();
 6554            let completion = &mut completions[completion_index];
 6555            completion.documentation = Some(lsp_documentation.into());
 6556        } else {
 6557            let mut completions = completions.borrow_mut();
 6558            let completion = &mut completions[completion_index];
 6559            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6560        }
 6561
 6562        let mut new_label = match completion_item {
 6563            Some(completion_item) => {
 6564                // Some language servers always return `detail` lazily via resolve, regardless of
 6565                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6566                // See: https://github.com/yioneko/vtsls/issues/213
 6567                let language = snapshot.language();
 6568                match language {
 6569                    Some(language) => {
 6570                        adapter
 6571                            .labels_for_completions(
 6572                                std::slice::from_ref(&completion_item),
 6573                                language,
 6574                            )
 6575                            .await?
 6576                    }
 6577                    None => Vec::new(),
 6578                }
 6579                .pop()
 6580                .flatten()
 6581                .unwrap_or_else(|| {
 6582                    CodeLabel::fallback_for_completion(
 6583                        &completion_item,
 6584                        language.map(|language| language.as_ref()),
 6585                    )
 6586                })
 6587            }
 6588            None => CodeLabel::plain(
 6589                completions.borrow()[completion_index].new_text.clone(),
 6590                None,
 6591            ),
 6592        };
 6593        ensure_uniform_list_compatible_label(&mut new_label);
 6594
 6595        let mut completions = completions.borrow_mut();
 6596        let completion = &mut completions[completion_index];
 6597        if completion.label.filter_text() == new_label.filter_text() {
 6598            completion.label = new_label;
 6599        } else {
 6600            log::error!(
 6601                "Resolved completion changed display label from {} to {}. \
 6602                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6603                completion.label.text(),
 6604                new_label.text(),
 6605                completion.label.filter_text(),
 6606                new_label.filter_text()
 6607            );
 6608        }
 6609
 6610        Ok(())
 6611    }
 6612
 6613    async fn resolve_completion_remote(
 6614        project_id: u64,
 6615        server_id: LanguageServerId,
 6616        buffer_id: BufferId,
 6617        completions: Rc<RefCell<Box<[Completion]>>>,
 6618        completion_index: usize,
 6619        client: AnyProtoClient,
 6620    ) -> Result<()> {
 6621        let lsp_completion = {
 6622            let completion = &completions.borrow()[completion_index];
 6623            match &completion.source {
 6624                CompletionSource::Lsp {
 6625                    lsp_completion,
 6626                    resolved,
 6627                    server_id: completion_server_id,
 6628                    ..
 6629                } => {
 6630                    anyhow::ensure!(
 6631                        server_id == *completion_server_id,
 6632                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6633                    );
 6634                    if *resolved {
 6635                        return Ok(());
 6636                    }
 6637                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6638                }
 6639                CompletionSource::Custom
 6640                | CompletionSource::Dap { .. }
 6641                | CompletionSource::BufferWord { .. } => {
 6642                    return Ok(());
 6643                }
 6644            }
 6645        };
 6646        let request = proto::ResolveCompletionDocumentation {
 6647            project_id,
 6648            language_server_id: server_id.0 as u64,
 6649            lsp_completion,
 6650            buffer_id: buffer_id.into(),
 6651        };
 6652
 6653        let response = client
 6654            .request(request)
 6655            .await
 6656            .context("completion documentation resolve proto request")?;
 6657        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6658
 6659        let documentation = if response.documentation.is_empty() {
 6660            CompletionDocumentation::Undocumented
 6661        } else if response.documentation_is_markdown {
 6662            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6663        } else if response.documentation.lines().count() <= 1 {
 6664            CompletionDocumentation::SingleLine(response.documentation.into())
 6665        } else {
 6666            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6667        };
 6668
 6669        let mut completions = completions.borrow_mut();
 6670        let completion = &mut completions[completion_index];
 6671        completion.documentation = Some(documentation);
 6672        if let CompletionSource::Lsp {
 6673            insert_range,
 6674            lsp_completion,
 6675            resolved,
 6676            server_id: completion_server_id,
 6677            lsp_defaults: _,
 6678        } = &mut completion.source
 6679        {
 6680            let completion_insert_range = response
 6681                .old_insert_start
 6682                .and_then(deserialize_anchor)
 6683                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6684            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6685
 6686            if *resolved {
 6687                return Ok(());
 6688            }
 6689            anyhow::ensure!(
 6690                server_id == *completion_server_id,
 6691                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6692            );
 6693            **lsp_completion = resolved_lsp_completion;
 6694            *resolved = true;
 6695        }
 6696
 6697        let replace_range = response
 6698            .old_replace_start
 6699            .and_then(deserialize_anchor)
 6700            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6701        if let Some((old_replace_start, old_replace_end)) = replace_range
 6702            && !response.new_text.is_empty()
 6703        {
 6704            completion.new_text = response.new_text;
 6705            completion.replace_range = old_replace_start..old_replace_end;
 6706        }
 6707
 6708        Ok(())
 6709    }
 6710
 6711    pub fn apply_additional_edits_for_completion(
 6712        &self,
 6713        buffer_handle: Entity<Buffer>,
 6714        completions: Rc<RefCell<Box<[Completion]>>>,
 6715        completion_index: usize,
 6716        push_to_history: bool,
 6717        all_commit_ranges: Vec<Range<language::Anchor>>,
 6718        cx: &mut Context<Self>,
 6719    ) -> Task<Result<Option<Transaction>>> {
 6720        if let Some((client, project_id)) = self.upstream_client() {
 6721            let buffer = buffer_handle.read(cx);
 6722            let buffer_id = buffer.remote_id();
 6723            cx.spawn(async move |_, cx| {
 6724                let request = {
 6725                    let completion = completions.borrow()[completion_index].clone();
 6726                    proto::ApplyCompletionAdditionalEdits {
 6727                        project_id,
 6728                        buffer_id: buffer_id.into(),
 6729                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6730                            replace_range: completion.replace_range,
 6731                            new_text: completion.new_text,
 6732                            source: completion.source,
 6733                        })),
 6734                        all_commit_ranges: all_commit_ranges
 6735                            .iter()
 6736                            .cloned()
 6737                            .map(language::proto::serialize_anchor_range)
 6738                            .collect(),
 6739                    }
 6740                };
 6741
 6742                let Some(transaction) = client.request(request).await?.transaction else {
 6743                    return Ok(None);
 6744                };
 6745
 6746                let transaction = language::proto::deserialize_transaction(transaction)?;
 6747                buffer_handle
 6748                    .update(cx, |buffer, _| {
 6749                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6750                    })
 6751                    .await?;
 6752                if push_to_history {
 6753                    buffer_handle.update(cx, |buffer, _| {
 6754                        buffer.push_transaction(transaction.clone(), Instant::now());
 6755                        buffer.finalize_last_transaction();
 6756                    });
 6757                }
 6758                Ok(Some(transaction))
 6759            })
 6760        } else {
 6761            let request_timeout = ProjectSettings::get_global(cx)
 6762                .global_lsp_settings
 6763                .get_request_timeout();
 6764
 6765            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6766                let completion = &completions.borrow()[completion_index];
 6767                let server_id = completion.source.server_id()?;
 6768                Some(
 6769                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6770                        .1
 6771                        .clone(),
 6772                )
 6773            }) else {
 6774                return Task::ready(Ok(None));
 6775            };
 6776
 6777            cx.spawn(async move |this, cx| {
 6778                Self::resolve_completion_local(
 6779                    server.clone(),
 6780                    completions.clone(),
 6781                    completion_index,
 6782                    request_timeout,
 6783                )
 6784                .await
 6785                .context("resolving completion")?;
 6786                let completion = completions.borrow()[completion_index].clone();
 6787                let additional_text_edits = completion
 6788                    .source
 6789                    .lsp_completion(true)
 6790                    .as_ref()
 6791                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6792                if let Some(edits) = additional_text_edits {
 6793                    let edits = this
 6794                        .update(cx, |this, cx| {
 6795                            this.as_local_mut().unwrap().edits_from_lsp(
 6796                                &buffer_handle,
 6797                                edits,
 6798                                server.server_id(),
 6799                                None,
 6800                                cx,
 6801                            )
 6802                        })?
 6803                        .await?;
 6804
 6805                    buffer_handle.update(cx, |buffer, cx| {
 6806                        buffer.finalize_last_transaction();
 6807                        buffer.start_transaction();
 6808
 6809                        for (range, text) in edits {
 6810                            let primary = &completion.replace_range;
 6811
 6812                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6813                            // and the primary completion is just an insertion (empty range), then this is likely
 6814                            // an auto-import scenario and should not be considered overlapping
 6815                            // https://github.com/zed-industries/zed/issues/26136
 6816                            let is_file_start_auto_import = {
 6817                                let snapshot = buffer.snapshot();
 6818                                let primary_start_point = primary.start.to_point(&snapshot);
 6819                                let range_start_point = range.start.to_point(&snapshot);
 6820
 6821                                let result = primary_start_point.row == 0
 6822                                    && primary_start_point.column == 0
 6823                                    && range_start_point.row == 0
 6824                                    && range_start_point.column == 0;
 6825
 6826                                result
 6827                            };
 6828
 6829                            let has_overlap = if is_file_start_auto_import {
 6830                                false
 6831                            } else {
 6832                                all_commit_ranges.iter().any(|commit_range| {
 6833                                    let start_within =
 6834                                        commit_range.start.cmp(&range.start, buffer).is_le()
 6835                                            && commit_range.end.cmp(&range.start, buffer).is_ge();
 6836                                    let end_within =
 6837                                        range.start.cmp(&commit_range.end, buffer).is_le()
 6838                                            && range.end.cmp(&commit_range.end, buffer).is_ge();
 6839                                    start_within || end_within
 6840                                })
 6841                            };
 6842
 6843                            //Skip additional edits which overlap with the primary completion edit
 6844                            //https://github.com/zed-industries/zed/pull/1871
 6845                            if !has_overlap {
 6846                                buffer.edit([(range, text)], None, cx);
 6847                            }
 6848                        }
 6849
 6850                        let transaction = if buffer.end_transaction(cx).is_some() {
 6851                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6852                            if !push_to_history {
 6853                                buffer.forget_transaction(transaction.id);
 6854                            }
 6855                            Some(transaction)
 6856                        } else {
 6857                            None
 6858                        };
 6859                        Ok(transaction)
 6860                    })
 6861                } else {
 6862                    Ok(None)
 6863                }
 6864            })
 6865        }
 6866    }
 6867
 6868    pub fn pull_diagnostics(
 6869        &mut self,
 6870        buffer: Entity<Buffer>,
 6871        cx: &mut Context<Self>,
 6872    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6873        let buffer_id = buffer.read(cx).remote_id();
 6874
 6875        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6876            let mut suitable_capabilities = None;
 6877            // Are we capable for proto request?
 6878            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6879                &buffer,
 6880                |capabilities| {
 6881                    if let Some(caps) = &capabilities.diagnostic_provider {
 6882                        suitable_capabilities = Some(caps.clone());
 6883                        true
 6884                    } else {
 6885                        false
 6886                    }
 6887                },
 6888                cx,
 6889            );
 6890            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6891            let Some(dynamic_caps) = suitable_capabilities else {
 6892                return Task::ready(Ok(None));
 6893            };
 6894            assert!(any_server_has_diagnostics_provider);
 6895
 6896            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6897            let request = GetDocumentDiagnostics {
 6898                previous_result_id: None,
 6899                identifier,
 6900                registration_id: None,
 6901            };
 6902            let request_timeout = ProjectSettings::get_global(cx)
 6903                .global_lsp_settings
 6904                .get_request_timeout();
 6905            let request_task = client.request_lsp(
 6906                upstream_project_id,
 6907                None,
 6908                request_timeout,
 6909                cx.background_executor().clone(),
 6910                request.to_proto(upstream_project_id, buffer.read(cx)),
 6911            );
 6912            cx.background_spawn(async move {
 6913                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6914                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6915                // Do not attempt to further process the dummy responses here.
 6916                let _response = request_task.await?;
 6917                Ok(None)
 6918            })
 6919        } else {
 6920            let servers = buffer.update(cx, |buffer, cx| {
 6921                self.running_language_servers_for_local_buffer(buffer, cx)
 6922                    .map(|(_, server)| server.clone())
 6923                    .collect::<Vec<_>>()
 6924            });
 6925
 6926            let pull_diagnostics = servers
 6927                .into_iter()
 6928                .flat_map(|server| {
 6929                    let result = maybe!({
 6930                        let local = self.as_local()?;
 6931                        let server_id = server.server_id();
 6932                        let providers_with_identifiers = local
 6933                            .language_server_dynamic_registrations
 6934                            .get(&server_id)
 6935                            .into_iter()
 6936                            .flat_map(|registrations| registrations.diagnostics.clone())
 6937                            .collect::<Vec<_>>();
 6938                        Some(
 6939                            providers_with_identifiers
 6940                                .into_iter()
 6941                                .map(|(registration_id, dynamic_caps)| {
 6942                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6943                                    let registration_id = registration_id.map(SharedString::from);
 6944                                    let result_id = self.result_id_for_buffer_pull(
 6945                                        server_id,
 6946                                        buffer_id,
 6947                                        &registration_id,
 6948                                        cx,
 6949                                    );
 6950                                    self.request_lsp(
 6951                                        buffer.clone(),
 6952                                        LanguageServerToQuery::Other(server_id),
 6953                                        GetDocumentDiagnostics {
 6954                                            previous_result_id: result_id,
 6955                                            registration_id,
 6956                                            identifier,
 6957                                        },
 6958                                        cx,
 6959                                    )
 6960                                })
 6961                                .collect::<Vec<_>>(),
 6962                        )
 6963                    });
 6964
 6965                    result.unwrap_or_default()
 6966                })
 6967                .collect::<Vec<_>>();
 6968
 6969            cx.background_spawn(async move {
 6970                let mut responses = Vec::new();
 6971                for diagnostics in join_all(pull_diagnostics).await {
 6972                    responses.extend(diagnostics?);
 6973                }
 6974                Ok(Some(responses))
 6975            })
 6976        }
 6977    }
 6978
 6979    pub fn applicable_inlay_chunks(
 6980        &mut self,
 6981        buffer: &Entity<Buffer>,
 6982        ranges: &[Range<text::Anchor>],
 6983        cx: &mut Context<Self>,
 6984    ) -> Vec<Range<BufferRow>> {
 6985        let buffer_snapshot = buffer.read(cx).snapshot();
 6986        let ranges = ranges
 6987            .iter()
 6988            .map(|range| range.to_point(&buffer_snapshot))
 6989            .collect::<Vec<_>>();
 6990
 6991        self.latest_lsp_data(buffer, cx)
 6992            .inlay_hints
 6993            .applicable_chunks(ranges.as_slice())
 6994            .map(|chunk| chunk.row_range())
 6995            .collect()
 6996    }
 6997
 6998    pub fn invalidate_inlay_hints<'a>(
 6999        &'a mut self,
 7000        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 7001    ) {
 7002        for buffer_id in for_buffers {
 7003            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 7004                lsp_data.inlay_hints.clear();
 7005            }
 7006        }
 7007    }
 7008
 7009    pub fn inlay_hints(
 7010        &mut self,
 7011        invalidate: InvalidationStrategy,
 7012        buffer: Entity<Buffer>,
 7013        ranges: Vec<Range<text::Anchor>>,
 7014        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 7015        cx: &mut Context<Self>,
 7016    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 7017        let next_hint_id = self.next_hint_id.clone();
 7018        let lsp_data = self.latest_lsp_data(&buffer, cx);
 7019        let query_version = lsp_data.buffer_version.clone();
 7020        let mut lsp_refresh_requested = false;
 7021        let for_server = if let InvalidationStrategy::RefreshRequested {
 7022            server_id,
 7023            request_id,
 7024        } = invalidate
 7025        {
 7026            let invalidated = lsp_data
 7027                .inlay_hints
 7028                .invalidate_for_server_refresh(server_id, request_id);
 7029            lsp_refresh_requested = invalidated;
 7030            Some(server_id)
 7031        } else {
 7032            None
 7033        };
 7034        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 7035        let known_chunks = known_chunks
 7036            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 7037            .map(|(_, known_chunks)| known_chunks)
 7038            .unwrap_or_default();
 7039
 7040        let buffer_snapshot = buffer.read(cx).snapshot();
 7041        let ranges = ranges
 7042            .iter()
 7043            .map(|range| range.to_point(&buffer_snapshot))
 7044            .collect::<Vec<_>>();
 7045
 7046        let mut hint_fetch_tasks = Vec::new();
 7047        let mut cached_inlay_hints = None;
 7048        let mut ranges_to_query = None;
 7049        let applicable_chunks = existing_inlay_hints
 7050            .applicable_chunks(ranges.as_slice())
 7051            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7052            .collect::<Vec<_>>();
 7053        if applicable_chunks.is_empty() {
 7054            return HashMap::default();
 7055        }
 7056
 7057        for row_chunk in applicable_chunks {
 7058            match (
 7059                existing_inlay_hints
 7060                    .cached_hints(&row_chunk)
 7061                    .filter(|_| !lsp_refresh_requested)
 7062                    .cloned(),
 7063                existing_inlay_hints
 7064                    .fetched_hints(&row_chunk)
 7065                    .as_ref()
 7066                    .filter(|_| !lsp_refresh_requested)
 7067                    .cloned(),
 7068            ) {
 7069                (None, None) => {
 7070                    let chunk_range = row_chunk.anchor_range();
 7071                    ranges_to_query
 7072                        .get_or_insert_with(Vec::new)
 7073                        .push((row_chunk, chunk_range));
 7074                }
 7075                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7076                (Some(cached_hints), None) => {
 7077                    for (server_id, cached_hints) in cached_hints {
 7078                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7079                            cached_inlay_hints
 7080                                .get_or_insert_with(HashMap::default)
 7081                                .entry(row_chunk.row_range())
 7082                                .or_insert_with(HashMap::default)
 7083                                .entry(server_id)
 7084                                .or_insert_with(Vec::new)
 7085                                .extend(cached_hints);
 7086                        }
 7087                    }
 7088                }
 7089                (Some(cached_hints), Some(fetched_hints)) => {
 7090                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7091                    for (server_id, cached_hints) in cached_hints {
 7092                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7093                            cached_inlay_hints
 7094                                .get_or_insert_with(HashMap::default)
 7095                                .entry(row_chunk.row_range())
 7096                                .or_insert_with(HashMap::default)
 7097                                .entry(server_id)
 7098                                .or_insert_with(Vec::new)
 7099                                .extend(cached_hints);
 7100                        }
 7101                    }
 7102                }
 7103            }
 7104        }
 7105
 7106        if hint_fetch_tasks.is_empty()
 7107            && ranges_to_query
 7108                .as_ref()
 7109                .is_none_or(|ranges| ranges.is_empty())
 7110            && let Some(cached_inlay_hints) = cached_inlay_hints
 7111        {
 7112            cached_inlay_hints
 7113                .into_iter()
 7114                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7115                .collect()
 7116        } else {
 7117            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7118                // When a server refresh was requested, other servers' cached hints
 7119                // are unaffected by the refresh and must be included in the result.
 7120                // Otherwise apply_fetched_hints (with should_invalidate()=true)
 7121                // removes all visible hints but only adds back the requesting
 7122                // server's new hints, permanently losing other servers' hints.
 7123                let other_servers_cached: CacheInlayHints = if lsp_refresh_requested {
 7124                    lsp_data
 7125                        .inlay_hints
 7126                        .cached_hints(&chunk)
 7127                        .cloned()
 7128                        .unwrap_or_default()
 7129                } else {
 7130                    HashMap::default()
 7131                };
 7132
 7133                let next_hint_id = next_hint_id.clone();
 7134                let buffer = buffer.clone();
 7135                let query_version = query_version.clone();
 7136                let new_inlay_hints = cx
 7137                    .spawn(async move |lsp_store, cx| {
 7138                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7139                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7140                        })?;
 7141                        new_fetch_task
 7142                            .await
 7143                            .and_then(|new_hints_by_server| {
 7144                                lsp_store.update(cx, |lsp_store, cx| {
 7145                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7146                                    let update_cache = lsp_data.buffer_version == query_version;
 7147                                    if new_hints_by_server.is_empty() {
 7148                                        if update_cache {
 7149                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7150                                        }
 7151                                        other_servers_cached
 7152                                    } else {
 7153                                        let mut result = other_servers_cached;
 7154                                        for (server_id, new_hints) in new_hints_by_server {
 7155                                            let new_hints = new_hints
 7156                                                .into_iter()
 7157                                                .map(|new_hint| {
 7158                                                    (
 7159                                                        InlayId::Hint(next_hint_id.fetch_add(
 7160                                                            1,
 7161                                                            atomic::Ordering::AcqRel,
 7162                                                        )),
 7163                                                        new_hint,
 7164                                                    )
 7165                                                })
 7166                                                .collect::<Vec<_>>();
 7167                                            if update_cache {
 7168                                                lsp_data.inlay_hints.insert_new_hints(
 7169                                                    chunk,
 7170                                                    server_id,
 7171                                                    new_hints.clone(),
 7172                                                );
 7173                                            }
 7174                                            result.insert(server_id, new_hints);
 7175                                        }
 7176                                        result
 7177                                    }
 7178                                })
 7179                            })
 7180                            .map_err(Arc::new)
 7181                    })
 7182                    .shared();
 7183
 7184                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7185                *fetch_task = Some(new_inlay_hints.clone());
 7186                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7187            }
 7188
 7189            cached_inlay_hints
 7190                .unwrap_or_default()
 7191                .into_iter()
 7192                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7193                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7194                    (
 7195                        chunk.row_range(),
 7196                        cx.spawn(async move |_, _| {
 7197                            hints_fetch.await.map_err(|e| {
 7198                                if e.error_code() != ErrorCode::Internal {
 7199                                    anyhow!(e.error_code())
 7200                                } else {
 7201                                    anyhow!("{e:#}")
 7202                                }
 7203                            })
 7204                        }),
 7205                    )
 7206                }))
 7207                .collect()
 7208        }
 7209    }
 7210
 7211    fn fetch_inlay_hints(
 7212        &mut self,
 7213        for_server: Option<LanguageServerId>,
 7214        buffer: &Entity<Buffer>,
 7215        range: Range<Anchor>,
 7216        cx: &mut Context<Self>,
 7217    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7218        let request = InlayHints {
 7219            range: range.clone(),
 7220        };
 7221        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7222            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7223                return Task::ready(Ok(HashMap::default()));
 7224            }
 7225            let request_timeout = ProjectSettings::get_global(cx)
 7226                .global_lsp_settings
 7227                .get_request_timeout();
 7228            let request_task = upstream_client.request_lsp(
 7229                project_id,
 7230                for_server.map(|id| id.to_proto()),
 7231                request_timeout,
 7232                cx.background_executor().clone(),
 7233                request.to_proto(project_id, buffer.read(cx)),
 7234            );
 7235            let buffer = buffer.clone();
 7236            cx.spawn(async move |weak_lsp_store, cx| {
 7237                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7238                    return Ok(HashMap::default());
 7239                };
 7240                let Some(responses) = request_task.await? else {
 7241                    return Ok(HashMap::default());
 7242                };
 7243
 7244                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7245                    let lsp_store = lsp_store.clone();
 7246                    let buffer = buffer.clone();
 7247                    let cx = cx.clone();
 7248                    let request = request.clone();
 7249                    async move {
 7250                        (
 7251                            LanguageServerId::from_proto(response.server_id),
 7252                            request
 7253                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7254                                .await,
 7255                        )
 7256                    }
 7257                }))
 7258                .await;
 7259
 7260                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7261                let mut has_errors = false;
 7262                let inlay_hints = inlay_hints
 7263                    .into_iter()
 7264                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7265                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7266                        Err(e) => {
 7267                            has_errors = true;
 7268                            log::error!("{e:#}");
 7269                            None
 7270                        }
 7271                    })
 7272                    .map(|(server_id, mut new_hints)| {
 7273                        new_hints.retain(|hint| {
 7274                            hint.position.is_valid(&buffer_snapshot)
 7275                                && range.start.is_valid(&buffer_snapshot)
 7276                                && range.end.is_valid(&buffer_snapshot)
 7277                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7278                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7279                        });
 7280                        (server_id, new_hints)
 7281                    })
 7282                    .collect::<HashMap<_, _>>();
 7283                anyhow::ensure!(
 7284                    !has_errors || !inlay_hints.is_empty(),
 7285                    "Failed to fetch inlay hints"
 7286                );
 7287                Ok(inlay_hints)
 7288            })
 7289        } else {
 7290            let inlay_hints_task = match for_server {
 7291                Some(server_id) => {
 7292                    let server_task = self.request_lsp(
 7293                        buffer.clone(),
 7294                        LanguageServerToQuery::Other(server_id),
 7295                        request,
 7296                        cx,
 7297                    );
 7298                    cx.background_spawn(async move {
 7299                        let mut responses = Vec::new();
 7300                        match server_task.await {
 7301                            Ok(response) => responses.push((server_id, response)),
 7302                            // rust-analyzer likes to error with this when its still loading up
 7303                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7304                            Err(e) => log::error!(
 7305                                "Error handling response for inlay hints request: {e:#}"
 7306                            ),
 7307                        }
 7308                        responses
 7309                    })
 7310                }
 7311                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7312            };
 7313            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7314            cx.background_spawn(async move {
 7315                Ok(inlay_hints_task
 7316                    .await
 7317                    .into_iter()
 7318                    .map(|(server_id, mut new_hints)| {
 7319                        new_hints.retain(|hint| {
 7320                            hint.position.is_valid(&buffer_snapshot)
 7321                                && range.start.is_valid(&buffer_snapshot)
 7322                                && range.end.is_valid(&buffer_snapshot)
 7323                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7324                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7325                        });
 7326                        (server_id, new_hints)
 7327                    })
 7328                    .collect())
 7329            })
 7330        }
 7331    }
 7332
 7333    fn diagnostic_registration_exists(
 7334        &self,
 7335        server_id: LanguageServerId,
 7336        registration_id: &Option<SharedString>,
 7337    ) -> bool {
 7338        let Some(local) = self.as_local() else {
 7339            return false;
 7340        };
 7341        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7342        else {
 7343            return false;
 7344        };
 7345        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7346        registrations.diagnostics.contains_key(&registration_key)
 7347    }
 7348
 7349    pub fn pull_diagnostics_for_buffer(
 7350        &mut self,
 7351        buffer: Entity<Buffer>,
 7352        cx: &mut Context<Self>,
 7353    ) -> Task<anyhow::Result<()>> {
 7354        let diagnostics = self.pull_diagnostics(buffer, cx);
 7355        cx.spawn(async move |lsp_store, cx| {
 7356            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7357                return Ok(());
 7358            };
 7359            lsp_store.update(cx, |lsp_store, cx| {
 7360                if lsp_store.as_local().is_none() {
 7361                    return;
 7362                }
 7363
 7364                let mut unchanged_buffers = HashMap::default();
 7365                let server_diagnostics_updates = diagnostics
 7366                    .into_iter()
 7367                    .filter_map(|diagnostics_set| match diagnostics_set {
 7368                        LspPullDiagnostics::Response {
 7369                            server_id,
 7370                            uri,
 7371                            diagnostics,
 7372                            registration_id,
 7373                        } => Some((server_id, uri, diagnostics, registration_id)),
 7374                        LspPullDiagnostics::Default => None,
 7375                    })
 7376                    .filter(|(server_id, _, _, registration_id)| {
 7377                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7378                    })
 7379                    .fold(
 7380                        HashMap::default(),
 7381                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7382                            let (result_id, diagnostics) = match diagnostics {
 7383                                PulledDiagnostics::Unchanged { result_id } => {
 7384                                    unchanged_buffers
 7385                                        .entry(new_registration_id.clone())
 7386                                        .or_insert_with(HashSet::default)
 7387                                        .insert(uri.clone());
 7388                                    (Some(result_id), Vec::new())
 7389                                }
 7390                                PulledDiagnostics::Changed {
 7391                                    result_id,
 7392                                    diagnostics,
 7393                                } => (result_id, diagnostics),
 7394                            };
 7395                            let disk_based_sources = Cow::Owned(
 7396                                lsp_store
 7397                                    .language_server_adapter_for_id(server_id)
 7398                                    .as_ref()
 7399                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7400                                    .unwrap_or(&[])
 7401                                    .to_vec(),
 7402                            );
 7403                            acc.entry(server_id)
 7404                                .or_insert_with(HashMap::default)
 7405                                .entry(new_registration_id.clone())
 7406                                .or_insert_with(Vec::new)
 7407                                .push(DocumentDiagnosticsUpdate {
 7408                                    server_id,
 7409                                    diagnostics: lsp::PublishDiagnosticsParams {
 7410                                        uri,
 7411                                        diagnostics,
 7412                                        version: None,
 7413                                    },
 7414                                    result_id: result_id.map(SharedString::new),
 7415                                    disk_based_sources,
 7416                                    registration_id: new_registration_id,
 7417                                });
 7418                            acc
 7419                        },
 7420                    );
 7421
 7422                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7423                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7424                        lsp_store
 7425                            .merge_lsp_diagnostics(
 7426                                DiagnosticSourceKind::Pulled,
 7427                                diagnostic_updates,
 7428                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7429                                    DiagnosticSourceKind::Pulled => {
 7430                                        old_diagnostic.registration_id != registration_id
 7431                                            || unchanged_buffers
 7432                                                .get(&old_diagnostic.registration_id)
 7433                                                .is_some_and(|unchanged_buffers| {
 7434                                                    unchanged_buffers.contains(&document_uri)
 7435                                                })
 7436                                    }
 7437                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7438                                        true
 7439                                    }
 7440                                },
 7441                                cx,
 7442                            )
 7443                            .log_err();
 7444                    }
 7445                }
 7446            })
 7447        })
 7448    }
 7449
 7450    pub fn signature_help<T: ToPointUtf16>(
 7451        &mut self,
 7452        buffer: &Entity<Buffer>,
 7453        position: T,
 7454        cx: &mut Context<Self>,
 7455    ) -> Task<Option<Vec<SignatureHelp>>> {
 7456        let position = position.to_point_utf16(buffer.read(cx));
 7457
 7458        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7459            let request = GetSignatureHelp { position };
 7460            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7461                return Task::ready(None);
 7462            }
 7463            let request_timeout = ProjectSettings::get_global(cx)
 7464                .global_lsp_settings
 7465                .get_request_timeout();
 7466            let request_task = client.request_lsp(
 7467                upstream_project_id,
 7468                None,
 7469                request_timeout,
 7470                cx.background_executor().clone(),
 7471                request.to_proto(upstream_project_id, buffer.read(cx)),
 7472            );
 7473            let buffer = buffer.clone();
 7474            cx.spawn(async move |weak_lsp_store, cx| {
 7475                let lsp_store = weak_lsp_store.upgrade()?;
 7476                let signatures = join_all(
 7477                    request_task
 7478                        .await
 7479                        .log_err()
 7480                        .flatten()
 7481                        .map(|response| response.payload)
 7482                        .unwrap_or_default()
 7483                        .into_iter()
 7484                        .map(|response| {
 7485                            let response = GetSignatureHelp { position }.response_from_proto(
 7486                                response.response,
 7487                                lsp_store.clone(),
 7488                                buffer.clone(),
 7489                                cx.clone(),
 7490                            );
 7491                            async move { response.await.log_err().flatten() }
 7492                        }),
 7493                )
 7494                .await
 7495                .into_iter()
 7496                .flatten()
 7497                .collect();
 7498                Some(signatures)
 7499            })
 7500        } else {
 7501            let all_actions_task = self.request_multiple_lsp_locally(
 7502                buffer,
 7503                Some(position),
 7504                GetSignatureHelp { position },
 7505                cx,
 7506            );
 7507            cx.background_spawn(async move {
 7508                Some(
 7509                    all_actions_task
 7510                        .await
 7511                        .into_iter()
 7512                        .flat_map(|(_, actions)| actions)
 7513                        .collect::<Vec<_>>(),
 7514                )
 7515            })
 7516        }
 7517    }
 7518
 7519    pub fn hover(
 7520        &mut self,
 7521        buffer: &Entity<Buffer>,
 7522        position: PointUtf16,
 7523        cx: &mut Context<Self>,
 7524    ) -> Task<Option<Vec<Hover>>> {
 7525        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7526            let request = GetHover { position };
 7527            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7528                return Task::ready(None);
 7529            }
 7530            let request_timeout = ProjectSettings::get_global(cx)
 7531                .global_lsp_settings
 7532                .get_request_timeout();
 7533            let request_task = client.request_lsp(
 7534                upstream_project_id,
 7535                None,
 7536                request_timeout,
 7537                cx.background_executor().clone(),
 7538                request.to_proto(upstream_project_id, buffer.read(cx)),
 7539            );
 7540            let buffer = buffer.clone();
 7541            cx.spawn(async move |weak_lsp_store, cx| {
 7542                let lsp_store = weak_lsp_store.upgrade()?;
 7543                let hovers = join_all(
 7544                    request_task
 7545                        .await
 7546                        .log_err()
 7547                        .flatten()
 7548                        .map(|response| response.payload)
 7549                        .unwrap_or_default()
 7550                        .into_iter()
 7551                        .map(|response| {
 7552                            let response = GetHover { position }.response_from_proto(
 7553                                response.response,
 7554                                lsp_store.clone(),
 7555                                buffer.clone(),
 7556                                cx.clone(),
 7557                            );
 7558                            async move {
 7559                                response
 7560                                    .await
 7561                                    .log_err()
 7562                                    .flatten()
 7563                                    .and_then(remove_empty_hover_blocks)
 7564                            }
 7565                        }),
 7566                )
 7567                .await
 7568                .into_iter()
 7569                .flatten()
 7570                .collect();
 7571                Some(hovers)
 7572            })
 7573        } else {
 7574            let all_actions_task = self.request_multiple_lsp_locally(
 7575                buffer,
 7576                Some(position),
 7577                GetHover { position },
 7578                cx,
 7579            );
 7580            cx.background_spawn(async move {
 7581                Some(
 7582                    all_actions_task
 7583                        .await
 7584                        .into_iter()
 7585                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7586                        .collect::<Vec<Hover>>(),
 7587                )
 7588            })
 7589        }
 7590    }
 7591
 7592    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7593        let language_registry = self.languages.clone();
 7594
 7595        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7596            let request = upstream_client.request(proto::GetProjectSymbols {
 7597                project_id: *project_id,
 7598                query: query.to_string(),
 7599            });
 7600            cx.foreground_executor().spawn(async move {
 7601                let response = request.await?;
 7602                let mut symbols = Vec::new();
 7603                let core_symbols = response
 7604                    .symbols
 7605                    .into_iter()
 7606                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7607                    .collect::<Vec<_>>();
 7608                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7609                    .await;
 7610                Ok(symbols)
 7611            })
 7612        } else if let Some(local) = self.as_local() {
 7613            struct WorkspaceSymbolsResult {
 7614                server_id: LanguageServerId,
 7615                lsp_adapter: Arc<CachedLspAdapter>,
 7616                worktree: WeakEntity<Worktree>,
 7617                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7618            }
 7619
 7620            let mut requests = Vec::new();
 7621            let mut requested_servers = BTreeSet::new();
 7622            let request_timeout = ProjectSettings::get_global(cx)
 7623                .global_lsp_settings
 7624                .get_request_timeout();
 7625
 7626            for (seed, state) in local.language_server_ids.iter() {
 7627                let Some(worktree_handle) = self
 7628                    .worktree_store
 7629                    .read(cx)
 7630                    .worktree_for_id(seed.worktree_id, cx)
 7631                else {
 7632                    continue;
 7633                };
 7634
 7635                let worktree = worktree_handle.read(cx);
 7636                if !worktree.is_visible() {
 7637                    continue;
 7638                }
 7639
 7640                if !requested_servers.insert(state.id) {
 7641                    continue;
 7642                }
 7643
 7644                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7645                    Some(LanguageServerState::Running {
 7646                        adapter, server, ..
 7647                    }) => (adapter.clone(), server),
 7648
 7649                    _ => continue,
 7650                };
 7651
 7652                let supports_workspace_symbol_request =
 7653                    match server.capabilities().workspace_symbol_provider {
 7654                        Some(OneOf::Left(supported)) => supported,
 7655                        Some(OneOf::Right(_)) => true,
 7656                        None => false,
 7657                    };
 7658
 7659                if !supports_workspace_symbol_request {
 7660                    continue;
 7661                }
 7662
 7663                let worktree_handle = worktree_handle.clone();
 7664                let server_id = server.server_id();
 7665                requests.push(
 7666                    server
 7667                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7668                            lsp::WorkspaceSymbolParams {
 7669                                query: query.to_string(),
 7670                                ..Default::default()
 7671                            },
 7672                            request_timeout,
 7673                        )
 7674                        .map(move |response| {
 7675                            let lsp_symbols = response
 7676                                .into_response()
 7677                                .context("workspace symbols request")
 7678                                .log_err()
 7679                                .flatten()
 7680                                .map(|symbol_response| match symbol_response {
 7681                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7682                                        flat_responses
 7683                                            .into_iter()
 7684                                            .map(|lsp_symbol| {
 7685                                                (
 7686                                                    lsp_symbol.name,
 7687                                                    lsp_symbol.kind,
 7688                                                    lsp_symbol.location,
 7689                                                    lsp_symbol.container_name,
 7690                                                )
 7691                                            })
 7692                                            .collect::<Vec<_>>()
 7693                                    }
 7694                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7695                                        nested_responses
 7696                                            .into_iter()
 7697                                            .filter_map(|lsp_symbol| {
 7698                                                let location = match lsp_symbol.location {
 7699                                                    OneOf::Left(location) => location,
 7700                                                    OneOf::Right(_) => {
 7701                                                        log::error!(
 7702                                                            "Unexpected: client capabilities \
 7703                                                            forbid symbol resolutions in \
 7704                                                            workspace.symbol.resolveSupport"
 7705                                                        );
 7706                                                        return None;
 7707                                                    }
 7708                                                };
 7709                                                Some((
 7710                                                    lsp_symbol.name,
 7711                                                    lsp_symbol.kind,
 7712                                                    location,
 7713                                                    lsp_symbol.container_name,
 7714                                                ))
 7715                                            })
 7716                                            .collect::<Vec<_>>()
 7717                                    }
 7718                                })
 7719                                .unwrap_or_default();
 7720
 7721                            WorkspaceSymbolsResult {
 7722                                server_id,
 7723                                lsp_adapter,
 7724                                worktree: worktree_handle.downgrade(),
 7725                                lsp_symbols,
 7726                            }
 7727                        }),
 7728                );
 7729            }
 7730
 7731            cx.spawn(async move |this, cx| {
 7732                let responses = futures::future::join_all(requests).await;
 7733                let this = match this.upgrade() {
 7734                    Some(this) => this,
 7735                    None => return Ok(Vec::new()),
 7736                };
 7737
 7738                let mut symbols = Vec::new();
 7739                for result in responses {
 7740                    let core_symbols = this.update(cx, |this, cx| {
 7741                        result
 7742                            .lsp_symbols
 7743                            .into_iter()
 7744                            .filter_map(
 7745                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7746                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7747                                    let source_worktree = result.worktree.upgrade()?;
 7748                                    let source_worktree_id = source_worktree.read(cx).id();
 7749
 7750                                    let path = if let Some((tree, rel_path)) =
 7751                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7752                                    {
 7753                                        let worktree_id = tree.read(cx).id();
 7754                                        SymbolLocation::InProject(ProjectPath {
 7755                                            worktree_id,
 7756                                            path: rel_path,
 7757                                        })
 7758                                    } else {
 7759                                        SymbolLocation::OutsideProject {
 7760                                            signature: this.symbol_signature(&abs_path),
 7761                                            abs_path: abs_path.into(),
 7762                                        }
 7763                                    };
 7764
 7765                                    Some(CoreSymbol {
 7766                                        source_language_server_id: result.server_id,
 7767                                        language_server_name: result.lsp_adapter.name.clone(),
 7768                                        source_worktree_id,
 7769                                        path,
 7770                                        kind: symbol_kind,
 7771                                        name: collapse_newlines(&symbol_name, ""),
 7772                                        range: range_from_lsp(symbol_location.range),
 7773                                        container_name: container_name
 7774                                            .map(|c| collapse_newlines(&c, "")),
 7775                                    })
 7776                                },
 7777                            )
 7778                            .collect::<Vec<_>>()
 7779                    });
 7780
 7781                    populate_labels_for_symbols(
 7782                        core_symbols,
 7783                        &language_registry,
 7784                        Some(result.lsp_adapter),
 7785                        &mut symbols,
 7786                    )
 7787                    .await;
 7788                }
 7789
 7790                Ok(symbols)
 7791            })
 7792        } else {
 7793            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7794        }
 7795    }
 7796
 7797    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7798        let mut summary = DiagnosticSummary::default();
 7799        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7800            summary.error_count += path_summary.error_count;
 7801            summary.warning_count += path_summary.warning_count;
 7802        }
 7803        summary
 7804    }
 7805
 7806    /// Returns the diagnostic summary for a specific project path.
 7807    pub fn diagnostic_summary_for_path(
 7808        &self,
 7809        project_path: &ProjectPath,
 7810        _: &App,
 7811    ) -> DiagnosticSummary {
 7812        if let Some(summaries) = self
 7813            .diagnostic_summaries
 7814            .get(&project_path.worktree_id)
 7815            .and_then(|map| map.get(&project_path.path))
 7816        {
 7817            let (error_count, warning_count) = summaries.iter().fold(
 7818                (0, 0),
 7819                |(error_count, warning_count), (_language_server_id, summary)| {
 7820                    (
 7821                        error_count + summary.error_count,
 7822                        warning_count + summary.warning_count,
 7823                    )
 7824                },
 7825            );
 7826
 7827            DiagnosticSummary {
 7828                error_count,
 7829                warning_count,
 7830            }
 7831        } else {
 7832            DiagnosticSummary::default()
 7833        }
 7834    }
 7835
 7836    pub fn diagnostic_summaries<'a>(
 7837        &'a self,
 7838        include_ignored: bool,
 7839        cx: &'a App,
 7840    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7841        self.worktree_store
 7842            .read(cx)
 7843            .visible_worktrees(cx)
 7844            .filter_map(|worktree| {
 7845                let worktree = worktree.read(cx);
 7846                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7847            })
 7848            .flat_map(move |(worktree, summaries)| {
 7849                let worktree_id = worktree.id();
 7850                summaries
 7851                    .iter()
 7852                    .filter(move |(path, _)| {
 7853                        include_ignored
 7854                            || worktree
 7855                                .entry_for_path(path.as_ref())
 7856                                .is_some_and(|entry| !entry.is_ignored)
 7857                    })
 7858                    .flat_map(move |(path, summaries)| {
 7859                        summaries.iter().map(move |(server_id, summary)| {
 7860                            (
 7861                                ProjectPath {
 7862                                    worktree_id,
 7863                                    path: path.clone(),
 7864                                },
 7865                                *server_id,
 7866                                *summary,
 7867                            )
 7868                        })
 7869                    })
 7870            })
 7871    }
 7872
 7873    pub fn on_buffer_edited(
 7874        &mut self,
 7875        buffer: Entity<Buffer>,
 7876        cx: &mut Context<Self>,
 7877    ) -> Option<()> {
 7878        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7879            Some(
 7880                self.as_local()?
 7881                    .language_servers_for_buffer(buffer, cx)
 7882                    .map(|i| i.1.clone())
 7883                    .collect(),
 7884            )
 7885        })?;
 7886
 7887        let buffer = buffer.read(cx);
 7888        let file = File::from_dyn(buffer.file())?;
 7889        let abs_path = file.as_local()?.abs_path(cx);
 7890        let uri = lsp::Uri::from_file_path(&abs_path)
 7891            .ok()
 7892            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7893            .log_err()?;
 7894        let next_snapshot = buffer.text_snapshot();
 7895        for language_server in language_servers {
 7896            let language_server = language_server.clone();
 7897
 7898            let buffer_snapshots = self
 7899                .as_local_mut()?
 7900                .buffer_snapshots
 7901                .get_mut(&buffer.remote_id())
 7902                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7903            let previous_snapshot = buffer_snapshots.last()?;
 7904
 7905            let build_incremental_change = || {
 7906                buffer
 7907                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7908                        previous_snapshot.snapshot.version(),
 7909                    )
 7910                    .map(|edit| {
 7911                        let edit_start = edit.new.start.0;
 7912                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7913                        let new_text = next_snapshot
 7914                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7915                            .collect();
 7916                        lsp::TextDocumentContentChangeEvent {
 7917                            range: Some(lsp::Range::new(
 7918                                point_to_lsp(edit_start),
 7919                                point_to_lsp(edit_end),
 7920                            )),
 7921                            range_length: None,
 7922                            text: new_text,
 7923                        }
 7924                    })
 7925                    .collect()
 7926            };
 7927
 7928            let document_sync_kind = language_server
 7929                .capabilities()
 7930                .text_document_sync
 7931                .as_ref()
 7932                .and_then(|sync| match sync {
 7933                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7934                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7935                });
 7936
 7937            let content_changes: Vec<_> = match document_sync_kind {
 7938                Some(lsp::TextDocumentSyncKind::FULL) => {
 7939                    vec![lsp::TextDocumentContentChangeEvent {
 7940                        range: None,
 7941                        range_length: None,
 7942                        text: next_snapshot.text(),
 7943                    }]
 7944                }
 7945                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7946                _ => {
 7947                    #[cfg(any(test, feature = "test-support"))]
 7948                    {
 7949                        build_incremental_change()
 7950                    }
 7951
 7952                    #[cfg(not(any(test, feature = "test-support")))]
 7953                    {
 7954                        continue;
 7955                    }
 7956                }
 7957            };
 7958
 7959            let next_version = previous_snapshot.version + 1;
 7960            buffer_snapshots.push(LspBufferSnapshot {
 7961                version: next_version,
 7962                snapshot: next_snapshot.clone(),
 7963            });
 7964
 7965            language_server
 7966                .notify::<lsp::notification::DidChangeTextDocument>(
 7967                    lsp::DidChangeTextDocumentParams {
 7968                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7969                            uri.clone(),
 7970                            next_version,
 7971                        ),
 7972                        content_changes,
 7973                    },
 7974                )
 7975                .ok();
 7976            self.pull_workspace_diagnostics(language_server.server_id());
 7977        }
 7978
 7979        None
 7980    }
 7981
 7982    pub fn on_buffer_saved(
 7983        &mut self,
 7984        buffer: Entity<Buffer>,
 7985        cx: &mut Context<Self>,
 7986    ) -> Option<()> {
 7987        let file = File::from_dyn(buffer.read(cx).file())?;
 7988        let worktree_id = file.worktree_id(cx);
 7989        let abs_path = file.as_local()?.abs_path(cx);
 7990        let text_document = lsp::TextDocumentIdentifier {
 7991            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7992        };
 7993        let local = self.as_local()?;
 7994
 7995        for server in local.language_servers_for_worktree(worktree_id) {
 7996            if let Some(include_text) = include_text(server.as_ref()) {
 7997                let text = if include_text {
 7998                    Some(buffer.read(cx).text())
 7999                } else {
 8000                    None
 8001                };
 8002                server
 8003                    .notify::<lsp::notification::DidSaveTextDocument>(
 8004                        lsp::DidSaveTextDocumentParams {
 8005                            text_document: text_document.clone(),
 8006                            text,
 8007                        },
 8008                    )
 8009                    .ok();
 8010            }
 8011        }
 8012
 8013        let language_servers = buffer.update(cx, |buffer, cx| {
 8014            local.language_server_ids_for_buffer(buffer, cx)
 8015        });
 8016        for language_server_id in language_servers {
 8017            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8018        }
 8019
 8020        None
 8021    }
 8022
 8023    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8024        maybe!(async move {
 8025            let mut refreshed_servers = HashSet::default();
 8026            let servers = lsp_store
 8027                .update(cx, |lsp_store, cx| {
 8028                    let local = lsp_store.as_local()?;
 8029
 8030                    let servers = local
 8031                        .language_server_ids
 8032                        .iter()
 8033                        .filter_map(|(seed, state)| {
 8034                            let worktree = lsp_store
 8035                                .worktree_store
 8036                                .read(cx)
 8037                                .worktree_for_id(seed.worktree_id, cx);
 8038                            let delegate: Arc<dyn LspAdapterDelegate> =
 8039                                worktree.map(|worktree| {
 8040                                    LocalLspAdapterDelegate::new(
 8041                                        local.languages.clone(),
 8042                                        &local.environment,
 8043                                        cx.weak_entity(),
 8044                                        &worktree,
 8045                                        local.http_client.clone(),
 8046                                        local.fs.clone(),
 8047                                        cx,
 8048                                    )
 8049                                })?;
 8050                            let server_id = state.id;
 8051
 8052                            let states = local.language_servers.get(&server_id)?;
 8053
 8054                            match states {
 8055                                LanguageServerState::Starting { .. } => None,
 8056                                LanguageServerState::Running {
 8057                                    adapter, server, ..
 8058                                } => {
 8059                                    let adapter = adapter.clone();
 8060                                    let server = server.clone();
 8061                                    refreshed_servers.insert(server.name());
 8062                                    let toolchain = seed.toolchain.clone();
 8063                                    Some(cx.spawn(async move |_, cx| {
 8064                                        let settings =
 8065                                            LocalLspStore::workspace_configuration_for_adapter(
 8066                                                adapter.adapter.clone(),
 8067                                                &delegate,
 8068                                                toolchain,
 8069                                                None,
 8070                                                cx,
 8071                                            )
 8072                                            .await
 8073                                            .ok()?;
 8074                                        server
 8075                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8076                                                lsp::DidChangeConfigurationParams { settings },
 8077                                            )
 8078                                            .ok()?;
 8079                                        Some(())
 8080                                    }))
 8081                                }
 8082                            }
 8083                        })
 8084                        .collect::<Vec<_>>();
 8085
 8086                    Some(servers)
 8087                })
 8088                .ok()
 8089                .flatten()?;
 8090
 8091            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8092            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8093            // to stop and unregister its language server wrapper.
 8094            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8095            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8096            let _: Vec<Option<()>> = join_all(servers).await;
 8097
 8098            Some(())
 8099        })
 8100        .await;
 8101    }
 8102
 8103    fn maintain_workspace_config(
 8104        external_refresh_requests: watch::Receiver<()>,
 8105        cx: &mut Context<Self>,
 8106    ) -> Task<Result<()>> {
 8107        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8108        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8109
 8110        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8111            *settings_changed_tx.borrow_mut() = ();
 8112        });
 8113
 8114        let mut joint_future =
 8115            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8116        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8117        // - 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).
 8118        // - 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.
 8119        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8120        // - 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,
 8121        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8122        cx.spawn(async move |this, cx| {
 8123            while let Some(()) = joint_future.next().await {
 8124                this.update(cx, |this, cx| {
 8125                    this.refresh_server_tree(cx);
 8126                })
 8127                .ok();
 8128
 8129                Self::refresh_workspace_configurations(&this, cx).await;
 8130            }
 8131
 8132            drop(settings_observation);
 8133            anyhow::Ok(())
 8134        })
 8135    }
 8136
 8137    pub fn running_language_servers_for_local_buffer<'a>(
 8138        &'a self,
 8139        buffer: &Buffer,
 8140        cx: &mut App,
 8141    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8142        let local = self.as_local();
 8143        let language_server_ids = local
 8144            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8145            .unwrap_or_default();
 8146
 8147        language_server_ids
 8148            .into_iter()
 8149            .filter_map(
 8150                move |server_id| match local?.language_servers.get(&server_id)? {
 8151                    LanguageServerState::Running {
 8152                        adapter, server, ..
 8153                    } => Some((adapter, server)),
 8154                    _ => None,
 8155                },
 8156            )
 8157    }
 8158
 8159    pub fn language_servers_for_local_buffer(
 8160        &self,
 8161        buffer: &Buffer,
 8162        cx: &mut App,
 8163    ) -> Vec<LanguageServerId> {
 8164        let local = self.as_local();
 8165        local
 8166            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8167            .unwrap_or_default()
 8168    }
 8169
 8170    pub fn language_server_for_local_buffer<'a>(
 8171        &'a self,
 8172        buffer: &'a Buffer,
 8173        server_id: LanguageServerId,
 8174        cx: &'a mut App,
 8175    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8176        self.as_local()?
 8177            .language_servers_for_buffer(buffer, cx)
 8178            .find(|(_, s)| s.server_id() == server_id)
 8179    }
 8180
 8181    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8182        self.diagnostic_summaries.remove(&id_to_remove);
 8183        if let Some(local) = self.as_local_mut() {
 8184            let to_remove = local.remove_worktree(id_to_remove, cx);
 8185            for server in to_remove {
 8186                self.language_server_statuses.remove(&server);
 8187            }
 8188        }
 8189    }
 8190
 8191    fn invalidate_diagnostic_summaries_for_removed_entries(
 8192        &mut self,
 8193        worktree_id: WorktreeId,
 8194        changes: &UpdatedEntriesSet,
 8195        cx: &mut Context<Self>,
 8196    ) {
 8197        let Some(summaries_for_tree) = self.diagnostic_summaries.get_mut(&worktree_id) else {
 8198            return;
 8199        };
 8200
 8201        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
 8202        let mut cleared_server_ids: HashSet<LanguageServerId> = HashSet::default();
 8203        let downstream = self.downstream_client.clone();
 8204
 8205        for (path, _, _) in changes
 8206            .iter()
 8207            .filter(|(_, _, change)| *change == PathChange::Removed)
 8208        {
 8209            if let Some(summaries_by_server_id) = summaries_for_tree.remove(path) {
 8210                for (server_id, _) in &summaries_by_server_id {
 8211                    cleared_server_ids.insert(*server_id);
 8212                    if let Some((client, project_id)) = &downstream {
 8213                        client
 8214                            .send(proto::UpdateDiagnosticSummary {
 8215                                project_id: *project_id,
 8216                                worktree_id: worktree_id.to_proto(),
 8217                                summary: Some(proto::DiagnosticSummary {
 8218                                    path: path.as_ref().to_proto(),
 8219                                    language_server_id: server_id.0 as u64,
 8220                                    error_count: 0,
 8221                                    warning_count: 0,
 8222                                }),
 8223                                more_summaries: Vec::new(),
 8224                            })
 8225                            .ok();
 8226                    }
 8227                }
 8228                cleared_paths.push(ProjectPath {
 8229                    worktree_id,
 8230                    path: path.clone(),
 8231                });
 8232            }
 8233        }
 8234
 8235        if !cleared_paths.is_empty() {
 8236            for server_id in cleared_server_ids {
 8237                cx.emit(LspStoreEvent::DiagnosticsUpdated {
 8238                    server_id,
 8239                    paths: cleared_paths.clone(),
 8240                });
 8241            }
 8242        }
 8243    }
 8244
 8245    pub fn shared(
 8246        &mut self,
 8247        project_id: u64,
 8248        downstream_client: AnyProtoClient,
 8249        _: &mut Context<Self>,
 8250    ) {
 8251        self.downstream_client = Some((downstream_client.clone(), project_id));
 8252
 8253        for (server_id, status) in &self.language_server_statuses {
 8254            if let Some(server) = self.language_server_for_id(*server_id) {
 8255                downstream_client
 8256                    .send(proto::StartLanguageServer {
 8257                        project_id,
 8258                        server: Some(proto::LanguageServer {
 8259                            id: server_id.to_proto(),
 8260                            name: status.name.to_string(),
 8261                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8262                        }),
 8263                        capabilities: serde_json::to_string(&server.capabilities())
 8264                            .expect("serializing server LSP capabilities"),
 8265                    })
 8266                    .log_err();
 8267            }
 8268        }
 8269    }
 8270
 8271    pub fn disconnected_from_host(&mut self) {
 8272        self.downstream_client.take();
 8273    }
 8274
 8275    pub fn disconnected_from_ssh_remote(&mut self) {
 8276        if let LspStoreMode::Remote(RemoteLspStore {
 8277            upstream_client, ..
 8278        }) = &mut self.mode
 8279        {
 8280            upstream_client.take();
 8281        }
 8282    }
 8283
 8284    pub(crate) fn set_language_server_statuses_from_proto(
 8285        &mut self,
 8286        project: WeakEntity<Project>,
 8287        language_servers: Vec<proto::LanguageServer>,
 8288        server_capabilities: Vec<String>,
 8289        cx: &mut Context<Self>,
 8290    ) {
 8291        let lsp_logs = cx
 8292            .try_global::<GlobalLogStore>()
 8293            .map(|lsp_store| lsp_store.0.clone());
 8294
 8295        self.language_server_statuses = language_servers
 8296            .into_iter()
 8297            .zip(server_capabilities)
 8298            .map(|(server, server_capabilities)| {
 8299                let server_id = LanguageServerId(server.id as usize);
 8300                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8301                    self.lsp_server_capabilities
 8302                        .insert(server_id, server_capabilities);
 8303                }
 8304
 8305                let name = LanguageServerName::from_proto(server.name);
 8306                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8307
 8308                if let Some(lsp_logs) = &lsp_logs {
 8309                    lsp_logs.update(cx, |lsp_logs, cx| {
 8310                        lsp_logs.add_language_server(
 8311                            // Only remote clients get their language servers set from proto
 8312                            LanguageServerKind::Remote {
 8313                                project: project.clone(),
 8314                            },
 8315                            server_id,
 8316                            Some(name.clone()),
 8317                            worktree,
 8318                            None,
 8319                            cx,
 8320                        );
 8321                    });
 8322                }
 8323
 8324                (
 8325                    server_id,
 8326                    LanguageServerStatus {
 8327                        name,
 8328                        server_version: None,
 8329                        server_readable_version: None,
 8330                        pending_work: Default::default(),
 8331                        has_pending_diagnostic_updates: false,
 8332                        progress_tokens: Default::default(),
 8333                        worktree,
 8334                        binary: None,
 8335                        configuration: None,
 8336                        workspace_folders: BTreeSet::new(),
 8337                        process_id: None,
 8338                    },
 8339                )
 8340            })
 8341            .collect();
 8342    }
 8343
 8344    #[cfg(feature = "test-support")]
 8345    pub fn update_diagnostic_entries(
 8346        &mut self,
 8347        server_id: LanguageServerId,
 8348        abs_path: PathBuf,
 8349        result_id: Option<SharedString>,
 8350        version: Option<i32>,
 8351        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8352        cx: &mut Context<Self>,
 8353    ) -> anyhow::Result<()> {
 8354        self.merge_diagnostic_entries(
 8355            vec![DocumentDiagnosticsUpdate {
 8356                diagnostics: DocumentDiagnostics {
 8357                    diagnostics,
 8358                    document_abs_path: abs_path,
 8359                    version,
 8360                },
 8361                result_id,
 8362                server_id,
 8363                disk_based_sources: Cow::Borrowed(&[]),
 8364                registration_id: None,
 8365            }],
 8366            |_, _, _| false,
 8367            cx,
 8368        )?;
 8369        Ok(())
 8370    }
 8371
 8372    pub fn merge_diagnostic_entries<'a>(
 8373        &mut self,
 8374        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8375        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8376        cx: &mut Context<Self>,
 8377    ) -> anyhow::Result<()> {
 8378        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8379        let mut updated_diagnostics_paths = HashMap::default();
 8380        for mut update in diagnostic_updates {
 8381            let abs_path = &update.diagnostics.document_abs_path;
 8382            let server_id = update.server_id;
 8383            let Some((worktree, relative_path)) =
 8384                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8385            else {
 8386                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8387                return Ok(());
 8388            };
 8389
 8390            let worktree_id = worktree.read(cx).id();
 8391            let project_path = ProjectPath {
 8392                worktree_id,
 8393                path: relative_path,
 8394            };
 8395
 8396            let document_uri = lsp::Uri::from_file_path(abs_path)
 8397                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8398            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8399                let snapshot = buffer_handle.read(cx).snapshot();
 8400                let buffer = buffer_handle.read(cx);
 8401                let reused_diagnostics = buffer
 8402                    .buffer_diagnostics(Some(server_id))
 8403                    .iter()
 8404                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8405                    .map(|v| {
 8406                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8407                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8408                        DiagnosticEntry {
 8409                            range: start..end,
 8410                            diagnostic: v.diagnostic.clone(),
 8411                        }
 8412                    })
 8413                    .collect::<Vec<_>>();
 8414
 8415                self.as_local_mut()
 8416                    .context("cannot merge diagnostics on a remote LspStore")?
 8417                    .update_buffer_diagnostics(
 8418                        &buffer_handle,
 8419                        server_id,
 8420                        Some(update.registration_id),
 8421                        update.result_id,
 8422                        update.diagnostics.version,
 8423                        update.diagnostics.diagnostics.clone(),
 8424                        reused_diagnostics.clone(),
 8425                        cx,
 8426                    )?;
 8427
 8428                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8429            } else if let Some(local) = self.as_local() {
 8430                let reused_diagnostics = local
 8431                    .diagnostics
 8432                    .get(&worktree_id)
 8433                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8434                    .and_then(|diagnostics_by_server_id| {
 8435                        diagnostics_by_server_id
 8436                            .binary_search_by_key(&server_id, |e| e.0)
 8437                            .ok()
 8438                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8439                    })
 8440                    .into_iter()
 8441                    .flatten()
 8442                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8443
 8444                update
 8445                    .diagnostics
 8446                    .diagnostics
 8447                    .extend(reused_diagnostics.cloned());
 8448            }
 8449
 8450            let updated = worktree.update(cx, |worktree, cx| {
 8451                self.update_worktree_diagnostics(
 8452                    worktree.id(),
 8453                    server_id,
 8454                    project_path.path.clone(),
 8455                    update.diagnostics.diagnostics,
 8456                    cx,
 8457                )
 8458            })?;
 8459            match updated {
 8460                ControlFlow::Continue(new_summary) => {
 8461                    if let Some((project_id, new_summary)) = new_summary {
 8462                        match &mut diagnostics_summary {
 8463                            Some(diagnostics_summary) => {
 8464                                diagnostics_summary
 8465                                    .more_summaries
 8466                                    .push(proto::DiagnosticSummary {
 8467                                        path: project_path.path.as_ref().to_proto(),
 8468                                        language_server_id: server_id.0 as u64,
 8469                                        error_count: new_summary.error_count,
 8470                                        warning_count: new_summary.warning_count,
 8471                                    })
 8472                            }
 8473                            None => {
 8474                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8475                                    project_id,
 8476                                    worktree_id: worktree_id.to_proto(),
 8477                                    summary: Some(proto::DiagnosticSummary {
 8478                                        path: project_path.path.as_ref().to_proto(),
 8479                                        language_server_id: server_id.0 as u64,
 8480                                        error_count: new_summary.error_count,
 8481                                        warning_count: new_summary.warning_count,
 8482                                    }),
 8483                                    more_summaries: Vec::new(),
 8484                                })
 8485                            }
 8486                        }
 8487                    }
 8488                    updated_diagnostics_paths
 8489                        .entry(server_id)
 8490                        .or_insert_with(Vec::new)
 8491                        .push(project_path);
 8492                }
 8493                ControlFlow::Break(()) => {}
 8494            }
 8495        }
 8496
 8497        if let Some((diagnostics_summary, (downstream_client, _))) =
 8498            diagnostics_summary.zip(self.downstream_client.as_ref())
 8499        {
 8500            downstream_client.send(diagnostics_summary).log_err();
 8501        }
 8502        for (server_id, paths) in updated_diagnostics_paths {
 8503            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8504        }
 8505        Ok(())
 8506    }
 8507
 8508    fn update_worktree_diagnostics(
 8509        &mut self,
 8510        worktree_id: WorktreeId,
 8511        server_id: LanguageServerId,
 8512        path_in_worktree: Arc<RelPath>,
 8513        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8514        _: &mut Context<Worktree>,
 8515    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8516        let local = match &mut self.mode {
 8517            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8518            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8519        };
 8520
 8521        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8522        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8523        let summaries_by_server_id = summaries_for_tree
 8524            .entry(path_in_worktree.clone())
 8525            .or_default();
 8526
 8527        let old_summary = summaries_by_server_id
 8528            .remove(&server_id)
 8529            .unwrap_or_default();
 8530
 8531        let new_summary = DiagnosticSummary::new(&diagnostics);
 8532        if diagnostics.is_empty() {
 8533            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8534            {
 8535                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8536                    diagnostics_by_server_id.remove(ix);
 8537                }
 8538                if diagnostics_by_server_id.is_empty() {
 8539                    diagnostics_for_tree.remove(&path_in_worktree);
 8540                }
 8541            }
 8542        } else {
 8543            summaries_by_server_id.insert(server_id, new_summary);
 8544            let diagnostics_by_server_id = diagnostics_for_tree
 8545                .entry(path_in_worktree.clone())
 8546                .or_default();
 8547            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8548                Ok(ix) => {
 8549                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8550                }
 8551                Err(ix) => {
 8552                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8553                }
 8554            }
 8555        }
 8556
 8557        if !old_summary.is_empty() || !new_summary.is_empty() {
 8558            if let Some((_, project_id)) = &self.downstream_client {
 8559                Ok(ControlFlow::Continue(Some((
 8560                    *project_id,
 8561                    proto::DiagnosticSummary {
 8562                        path: path_in_worktree.to_proto(),
 8563                        language_server_id: server_id.0 as u64,
 8564                        error_count: new_summary.error_count as u32,
 8565                        warning_count: new_summary.warning_count as u32,
 8566                    },
 8567                ))))
 8568            } else {
 8569                Ok(ControlFlow::Continue(None))
 8570            }
 8571        } else {
 8572            Ok(ControlFlow::Break(()))
 8573        }
 8574    }
 8575
 8576    pub fn open_buffer_for_symbol(
 8577        &mut self,
 8578        symbol: &Symbol,
 8579        cx: &mut Context<Self>,
 8580    ) -> Task<Result<Entity<Buffer>>> {
 8581        if let Some((client, project_id)) = self.upstream_client() {
 8582            let request = client.request(proto::OpenBufferForSymbol {
 8583                project_id,
 8584                symbol: Some(Self::serialize_symbol(symbol)),
 8585            });
 8586            cx.spawn(async move |this, cx| {
 8587                let response = request.await?;
 8588                let buffer_id = BufferId::new(response.buffer_id)?;
 8589                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8590                    .await
 8591            })
 8592        } else if let Some(local) = self.as_local() {
 8593            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8594                seed.worktree_id == symbol.source_worktree_id
 8595                    && state.id == symbol.source_language_server_id
 8596                    && symbol.language_server_name == seed.name
 8597            });
 8598            if !is_valid {
 8599                return Task::ready(Err(anyhow!(
 8600                    "language server for worktree and language not found"
 8601                )));
 8602            };
 8603
 8604            let symbol_abs_path = match &symbol.path {
 8605                SymbolLocation::InProject(project_path) => self
 8606                    .worktree_store
 8607                    .read(cx)
 8608                    .absolutize(&project_path, cx)
 8609                    .context("no such worktree"),
 8610                SymbolLocation::OutsideProject {
 8611                    abs_path,
 8612                    signature: _,
 8613                } => Ok(abs_path.to_path_buf()),
 8614            };
 8615            let symbol_abs_path = match symbol_abs_path {
 8616                Ok(abs_path) => abs_path,
 8617                Err(err) => return Task::ready(Err(err)),
 8618            };
 8619            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8620                uri
 8621            } else {
 8622                return Task::ready(Err(anyhow!("invalid symbol path")));
 8623            };
 8624
 8625            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8626        } else {
 8627            Task::ready(Err(anyhow!("no upstream client or local store")))
 8628        }
 8629    }
 8630
 8631    pub(crate) fn open_local_buffer_via_lsp(
 8632        &mut self,
 8633        abs_path: lsp::Uri,
 8634        language_server_id: LanguageServerId,
 8635        cx: &mut Context<Self>,
 8636    ) -> Task<Result<Entity<Buffer>>> {
 8637        let path_style = self.worktree_store.read(cx).path_style();
 8638        cx.spawn(async move |lsp_store, cx| {
 8639            // Escape percent-encoded string.
 8640            let current_scheme = abs_path.scheme().to_owned();
 8641            // Uri is immutable, so we can't modify the scheme
 8642
 8643            let abs_path = abs_path
 8644                .to_file_path_ext(path_style)
 8645                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8646            let p = abs_path.clone();
 8647            let yarn_worktree = lsp_store
 8648                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8649                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8650                        cx.spawn(async move |this, cx| {
 8651                            let t = this
 8652                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8653                                .ok()?;
 8654                            t.await
 8655                        })
 8656                    }),
 8657                    None => Task::ready(None),
 8658                })?
 8659                .await;
 8660            let (worktree_root_target, known_relative_path) =
 8661                if let Some((zip_root, relative_path)) = yarn_worktree {
 8662                    (zip_root, Some(relative_path))
 8663                } else {
 8664                    (Arc::<Path>::from(abs_path.as_path()), None)
 8665                };
 8666            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8667                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8668                    worktree_store.find_worktree(&worktree_root_target, cx)
 8669                })
 8670            })?;
 8671            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8672                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8673                (result.0, relative_path, None)
 8674            } else {
 8675                let worktree = lsp_store
 8676                    .update(cx, |lsp_store, cx| {
 8677                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8678                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8679                        })
 8680                    })?
 8681                    .await?;
 8682                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8683                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8684                    lsp_store
 8685                        .update(cx, |lsp_store, cx| {
 8686                            if let Some(local) = lsp_store.as_local_mut() {
 8687                                local.register_language_server_for_invisible_worktree(
 8688                                    &worktree,
 8689                                    language_server_id,
 8690                                    cx,
 8691                                )
 8692                            }
 8693                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8694                                Some(status) => status.worktree,
 8695                                None => None,
 8696                            }
 8697                        })
 8698                        .ok()
 8699                        .flatten()
 8700                        .zip(Some(worktree_root.clone()))
 8701                } else {
 8702                    None
 8703                };
 8704                let relative_path = if let Some(known_path) = known_relative_path {
 8705                    known_path
 8706                } else {
 8707                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8708                        .into_arc()
 8709                };
 8710                (worktree, relative_path, source_ws)
 8711            };
 8712            let project_path = ProjectPath {
 8713                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8714                path: relative_path,
 8715            };
 8716            let buffer = lsp_store
 8717                .update(cx, |lsp_store, cx| {
 8718                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8719                        buffer_store.open_buffer(project_path, cx)
 8720                    })
 8721                })?
 8722                .await?;
 8723            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8724            if let Some((source_ws, worktree_root)) = source_ws {
 8725                buffer.update(cx, |buffer, cx| {
 8726                    let settings = WorktreeSettings::get(
 8727                        Some(
 8728                            (&ProjectPath {
 8729                                worktree_id: source_ws,
 8730                                path: Arc::from(RelPath::empty()),
 8731                            })
 8732                                .into(),
 8733                        ),
 8734                        cx,
 8735                    );
 8736                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8737                    if is_read_only {
 8738                        buffer.set_capability(Capability::ReadOnly, cx);
 8739                    }
 8740                });
 8741            }
 8742            Ok(buffer)
 8743        })
 8744    }
 8745
 8746    fn local_lsp_servers_for_buffer(
 8747        &self,
 8748        buffer: &Entity<Buffer>,
 8749        cx: &mut Context<Self>,
 8750    ) -> Vec<LanguageServerId> {
 8751        let Some(local) = self.as_local() else {
 8752            return Vec::new();
 8753        };
 8754
 8755        let snapshot = buffer.read(cx).snapshot();
 8756
 8757        buffer.update(cx, |buffer, cx| {
 8758            local
 8759                .language_servers_for_buffer(buffer, cx)
 8760                .map(|(_, server)| server.server_id())
 8761                .filter(|server_id| {
 8762                    self.as_local().is_none_or(|local| {
 8763                        local
 8764                            .buffers_opened_in_servers
 8765                            .get(&snapshot.remote_id())
 8766                            .is_some_and(|servers| servers.contains(server_id))
 8767                    })
 8768                })
 8769                .collect()
 8770        })
 8771    }
 8772
 8773    fn request_multiple_lsp_locally<P, R>(
 8774        &mut self,
 8775        buffer: &Entity<Buffer>,
 8776        position: Option<P>,
 8777        request: R,
 8778        cx: &mut Context<Self>,
 8779    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8780    where
 8781        P: ToOffset,
 8782        R: LspCommand + Clone,
 8783        <R::LspRequest as lsp::request::Request>::Result: Send,
 8784        <R::LspRequest as lsp::request::Request>::Params: Send,
 8785    {
 8786        let Some(local) = self.as_local() else {
 8787            return Task::ready(Vec::new());
 8788        };
 8789
 8790        let snapshot = buffer.read(cx).snapshot();
 8791        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8792
 8793        let server_ids = buffer.update(cx, |buffer, cx| {
 8794            local
 8795                .language_servers_for_buffer(buffer, cx)
 8796                .filter(|(adapter, _)| {
 8797                    scope
 8798                        .as_ref()
 8799                        .map(|scope| scope.language_allowed(&adapter.name))
 8800                        .unwrap_or(true)
 8801                })
 8802                .map(|(_, server)| server.server_id())
 8803                .filter(|server_id| {
 8804                    self.as_local().is_none_or(|local| {
 8805                        local
 8806                            .buffers_opened_in_servers
 8807                            .get(&snapshot.remote_id())
 8808                            .is_some_and(|servers| servers.contains(server_id))
 8809                    })
 8810                })
 8811                .collect::<Vec<_>>()
 8812        });
 8813
 8814        let mut response_results = server_ids
 8815            .into_iter()
 8816            .map(|server_id| {
 8817                let task = self.request_lsp(
 8818                    buffer.clone(),
 8819                    LanguageServerToQuery::Other(server_id),
 8820                    request.clone(),
 8821                    cx,
 8822                );
 8823                async move { (server_id, task.await) }
 8824            })
 8825            .collect::<FuturesUnordered<_>>();
 8826
 8827        cx.background_spawn(async move {
 8828            let mut responses = Vec::with_capacity(response_results.len());
 8829            while let Some((server_id, response_result)) = response_results.next().await {
 8830                match response_result {
 8831                    Ok(response) => responses.push((server_id, response)),
 8832                    // rust-analyzer likes to error with this when its still loading up
 8833                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8834                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8835                }
 8836            }
 8837            responses
 8838        })
 8839    }
 8840
 8841    async fn handle_lsp_get_completions(
 8842        this: Entity<Self>,
 8843        envelope: TypedEnvelope<proto::GetCompletions>,
 8844        mut cx: AsyncApp,
 8845    ) -> Result<proto::GetCompletionsResponse> {
 8846        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8847
 8848        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8849        let buffer_handle = this.update(&mut cx, |this, cx| {
 8850            this.buffer_store.read(cx).get_existing(buffer_id)
 8851        })?;
 8852        let request = GetCompletions::from_proto(
 8853            envelope.payload,
 8854            this.clone(),
 8855            buffer_handle.clone(),
 8856            cx.clone(),
 8857        )
 8858        .await?;
 8859
 8860        let server_to_query = match request.server_id {
 8861            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8862            None => LanguageServerToQuery::FirstCapable,
 8863        };
 8864
 8865        let response = this
 8866            .update(&mut cx, |this, cx| {
 8867                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8868            })
 8869            .await?;
 8870        this.update(&mut cx, |this, cx| {
 8871            Ok(GetCompletions::response_to_proto(
 8872                response,
 8873                this,
 8874                sender_id,
 8875                &buffer_handle.read(cx).version(),
 8876                cx,
 8877            ))
 8878        })
 8879    }
 8880
 8881    async fn handle_lsp_command<T: LspCommand>(
 8882        this: Entity<Self>,
 8883        envelope: TypedEnvelope<T::ProtoRequest>,
 8884        mut cx: AsyncApp,
 8885    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8886    where
 8887        <T::LspRequest as lsp::request::Request>::Params: Send,
 8888        <T::LspRequest as lsp::request::Request>::Result: Send,
 8889    {
 8890        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8891        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8892        let buffer_handle = this.update(&mut cx, |this, cx| {
 8893            this.buffer_store.read(cx).get_existing(buffer_id)
 8894        })?;
 8895        let request = T::from_proto(
 8896            envelope.payload,
 8897            this.clone(),
 8898            buffer_handle.clone(),
 8899            cx.clone(),
 8900        )
 8901        .await?;
 8902        let response = this
 8903            .update(&mut cx, |this, cx| {
 8904                this.request_lsp(
 8905                    buffer_handle.clone(),
 8906                    LanguageServerToQuery::FirstCapable,
 8907                    request,
 8908                    cx,
 8909                )
 8910            })
 8911            .await?;
 8912        this.update(&mut cx, |this, cx| {
 8913            Ok(T::response_to_proto(
 8914                response,
 8915                this,
 8916                sender_id,
 8917                &buffer_handle.read(cx).version(),
 8918                cx,
 8919            ))
 8920        })
 8921    }
 8922
 8923    async fn handle_lsp_query(
 8924        lsp_store: Entity<Self>,
 8925        envelope: TypedEnvelope<proto::LspQuery>,
 8926        mut cx: AsyncApp,
 8927    ) -> Result<proto::Ack> {
 8928        use proto::lsp_query::Request;
 8929        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8930        let lsp_query = envelope.payload;
 8931        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8932        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8933        match lsp_query.request.context("invalid LSP query request")? {
 8934            Request::GetReferences(get_references) => {
 8935                let position = get_references.position.clone().and_then(deserialize_anchor);
 8936                Self::query_lsp_locally::<GetReferences>(
 8937                    lsp_store,
 8938                    server_id,
 8939                    sender_id,
 8940                    lsp_request_id,
 8941                    get_references,
 8942                    position,
 8943                    &mut cx,
 8944                )
 8945                .await?;
 8946            }
 8947            Request::GetDocumentColor(get_document_color) => {
 8948                Self::query_lsp_locally::<GetDocumentColor>(
 8949                    lsp_store,
 8950                    server_id,
 8951                    sender_id,
 8952                    lsp_request_id,
 8953                    get_document_color,
 8954                    None,
 8955                    &mut cx,
 8956                )
 8957                .await?;
 8958            }
 8959            Request::GetFoldingRanges(get_folding_ranges) => {
 8960                Self::query_lsp_locally::<GetFoldingRanges>(
 8961                    lsp_store,
 8962                    server_id,
 8963                    sender_id,
 8964                    lsp_request_id,
 8965                    get_folding_ranges,
 8966                    None,
 8967                    &mut cx,
 8968                )
 8969                .await?;
 8970            }
 8971            Request::GetDocumentSymbols(get_document_symbols) => {
 8972                Self::query_lsp_locally::<GetDocumentSymbols>(
 8973                    lsp_store,
 8974                    server_id,
 8975                    sender_id,
 8976                    lsp_request_id,
 8977                    get_document_symbols,
 8978                    None,
 8979                    &mut cx,
 8980                )
 8981                .await?;
 8982            }
 8983            Request::GetHover(get_hover) => {
 8984                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8985                Self::query_lsp_locally::<GetHover>(
 8986                    lsp_store,
 8987                    server_id,
 8988                    sender_id,
 8989                    lsp_request_id,
 8990                    get_hover,
 8991                    position,
 8992                    &mut cx,
 8993                )
 8994                .await?;
 8995            }
 8996            Request::GetCodeActions(get_code_actions) => {
 8997                Self::query_lsp_locally::<GetCodeActions>(
 8998                    lsp_store,
 8999                    server_id,
 9000                    sender_id,
 9001                    lsp_request_id,
 9002                    get_code_actions,
 9003                    None,
 9004                    &mut cx,
 9005                )
 9006                .await?;
 9007            }
 9008            Request::GetSignatureHelp(get_signature_help) => {
 9009                let position = get_signature_help
 9010                    .position
 9011                    .clone()
 9012                    .and_then(deserialize_anchor);
 9013                Self::query_lsp_locally::<GetSignatureHelp>(
 9014                    lsp_store,
 9015                    server_id,
 9016                    sender_id,
 9017                    lsp_request_id,
 9018                    get_signature_help,
 9019                    position,
 9020                    &mut cx,
 9021                )
 9022                .await?;
 9023            }
 9024            Request::GetCodeLens(get_code_lens) => {
 9025                Self::query_lsp_locally::<GetCodeLens>(
 9026                    lsp_store,
 9027                    server_id,
 9028                    sender_id,
 9029                    lsp_request_id,
 9030                    get_code_lens,
 9031                    None,
 9032                    &mut cx,
 9033                )
 9034                .await?;
 9035            }
 9036            Request::GetDefinition(get_definition) => {
 9037                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9038                Self::query_lsp_locally::<GetDefinitions>(
 9039                    lsp_store,
 9040                    server_id,
 9041                    sender_id,
 9042                    lsp_request_id,
 9043                    get_definition,
 9044                    position,
 9045                    &mut cx,
 9046                )
 9047                .await?;
 9048            }
 9049            Request::GetDeclaration(get_declaration) => {
 9050                let position = get_declaration
 9051                    .position
 9052                    .clone()
 9053                    .and_then(deserialize_anchor);
 9054                Self::query_lsp_locally::<GetDeclarations>(
 9055                    lsp_store,
 9056                    server_id,
 9057                    sender_id,
 9058                    lsp_request_id,
 9059                    get_declaration,
 9060                    position,
 9061                    &mut cx,
 9062                )
 9063                .await?;
 9064            }
 9065            Request::GetTypeDefinition(get_type_definition) => {
 9066                let position = get_type_definition
 9067                    .position
 9068                    .clone()
 9069                    .and_then(deserialize_anchor);
 9070                Self::query_lsp_locally::<GetTypeDefinitions>(
 9071                    lsp_store,
 9072                    server_id,
 9073                    sender_id,
 9074                    lsp_request_id,
 9075                    get_type_definition,
 9076                    position,
 9077                    &mut cx,
 9078                )
 9079                .await?;
 9080            }
 9081            Request::GetImplementation(get_implementation) => {
 9082                let position = get_implementation
 9083                    .position
 9084                    .clone()
 9085                    .and_then(deserialize_anchor);
 9086                Self::query_lsp_locally::<GetImplementations>(
 9087                    lsp_store,
 9088                    server_id,
 9089                    sender_id,
 9090                    lsp_request_id,
 9091                    get_implementation,
 9092                    position,
 9093                    &mut cx,
 9094                )
 9095                .await?;
 9096            }
 9097            Request::InlayHints(inlay_hints) => {
 9098                let query_start = inlay_hints
 9099                    .start
 9100                    .clone()
 9101                    .and_then(deserialize_anchor)
 9102                    .context("invalid inlay hints range start")?;
 9103                let query_end = inlay_hints
 9104                    .end
 9105                    .clone()
 9106                    .and_then(deserialize_anchor)
 9107                    .context("invalid inlay hints range end")?;
 9108                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9109                    &lsp_store,
 9110                    server_id,
 9111                    lsp_request_id,
 9112                    &inlay_hints,
 9113                    query_start..query_end,
 9114                    &mut cx,
 9115                )
 9116                .await
 9117                .context("preparing inlay hints request")?;
 9118                Self::query_lsp_locally::<InlayHints>(
 9119                    lsp_store,
 9120                    server_id,
 9121                    sender_id,
 9122                    lsp_request_id,
 9123                    inlay_hints,
 9124                    None,
 9125                    &mut cx,
 9126                )
 9127                .await
 9128                .context("querying for inlay hints")?
 9129            }
 9130            //////////////////////////////
 9131            // Below are LSP queries that need to fetch more data,
 9132            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 9133            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9134                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 9135                    &lsp_store,
 9136                    &get_document_diagnostics,
 9137                    &mut cx,
 9138                )
 9139                .await?;
 9140                lsp_store.update(&mut cx, |lsp_store, cx| {
 9141                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9142                    let key = LspKey {
 9143                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9144                        server_queried: server_id,
 9145                    };
 9146                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9147                    ) {
 9148                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9149                            lsp_requests.clear();
 9150                        };
 9151                    }
 9152
 9153                    lsp_data.lsp_requests.entry(key).or_default().insert(
 9154                        lsp_request_id,
 9155                        cx.spawn(async move |lsp_store, cx| {
 9156                            let diagnostics_pull = lsp_store
 9157                                .update(cx, |lsp_store, cx| {
 9158                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9159                                })
 9160                                .ok();
 9161                            if let Some(diagnostics_pull) = diagnostics_pull {
 9162                                match diagnostics_pull.await {
 9163                                    Ok(()) => {}
 9164                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9165                                };
 9166                            }
 9167                        }),
 9168                    );
 9169                });
 9170            }
 9171            Request::SemanticTokens(semantic_tokens) => {
 9172                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 9173                    &lsp_store,
 9174                    &semantic_tokens,
 9175                    &mut cx,
 9176                )
 9177                .await?;
 9178                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9179                lsp_store.update(&mut cx, |lsp_store, cx| {
 9180                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9181                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9182                        let key = LspKey {
 9183                            request_type: TypeId::of::<SemanticTokensFull>(),
 9184                            server_queried: server_id,
 9185                        };
 9186                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9187                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9188                                lsp_requests.clear();
 9189                            };
 9190                        }
 9191
 9192                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9193                            lsp_request_id,
 9194                            cx.spawn(async move |lsp_store, cx| {
 9195                                let tokens_fetch = lsp_store
 9196                                    .update(cx, |lsp_store, cx| {
 9197                                        lsp_store
 9198                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9199                                    })
 9200                                    .ok();
 9201                                if let Some(tokens_fetch) = tokens_fetch {
 9202                                    let new_tokens = tokens_fetch.await;
 9203                                    if let Some(new_tokens) = new_tokens {
 9204                                        lsp_store
 9205                                            .update(cx, |lsp_store, cx| {
 9206                                                let response = new_tokens
 9207                                                    .into_iter()
 9208                                                    .map(|(server_id, response)| {
 9209                                                        (
 9210                                                            server_id.to_proto(),
 9211                                                            SemanticTokensFull::response_to_proto(
 9212                                                                response,
 9213                                                                lsp_store,
 9214                                                                sender_id,
 9215                                                                &buffer_version,
 9216                                                                cx,
 9217                                                            ),
 9218                                                        )
 9219                                                    })
 9220                                                    .collect::<HashMap<_, _>>();
 9221                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9222                                                    project_id,
 9223                                                    lsp_request_id,
 9224                                                    response,
 9225                                                ) {
 9226                                                    Ok(()) => {}
 9227                                                    Err(e) => {
 9228                                                        log::error!(
 9229                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9230                                                        )
 9231                                                    }
 9232                                                }
 9233                                            })
 9234                                            .ok();
 9235                                    }
 9236                                }
 9237                            }),
 9238                        );
 9239                    }
 9240                });
 9241            }
 9242        }
 9243        Ok(proto::Ack {})
 9244    }
 9245
 9246    async fn handle_lsp_query_response(
 9247        lsp_store: Entity<Self>,
 9248        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9249        cx: AsyncApp,
 9250    ) -> Result<()> {
 9251        lsp_store.read_with(&cx, |lsp_store, _| {
 9252            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9253                upstream_client.handle_lsp_response(envelope.clone());
 9254            }
 9255        });
 9256        Ok(())
 9257    }
 9258
 9259    async fn handle_apply_code_action(
 9260        this: Entity<Self>,
 9261        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9262        mut cx: AsyncApp,
 9263    ) -> Result<proto::ApplyCodeActionResponse> {
 9264        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9265        let action =
 9266            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9267        let apply_code_action = this.update(&mut cx, |this, cx| {
 9268            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9269            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9270            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9271        })?;
 9272
 9273        let project_transaction = apply_code_action.await?;
 9274        let project_transaction = this.update(&mut cx, |this, cx| {
 9275            this.buffer_store.update(cx, |buffer_store, cx| {
 9276                buffer_store.serialize_project_transaction_for_peer(
 9277                    project_transaction,
 9278                    sender_id,
 9279                    cx,
 9280                )
 9281            })
 9282        });
 9283        Ok(proto::ApplyCodeActionResponse {
 9284            transaction: Some(project_transaction),
 9285        })
 9286    }
 9287
 9288    async fn handle_register_buffer_with_language_servers(
 9289        this: Entity<Self>,
 9290        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9291        mut cx: AsyncApp,
 9292    ) -> Result<proto::Ack> {
 9293        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9294        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9295        this.update(&mut cx, |this, cx| {
 9296            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9297                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9298                    project_id: upstream_project_id,
 9299                    buffer_id: buffer_id.to_proto(),
 9300                    only_servers: envelope.payload.only_servers,
 9301                });
 9302            }
 9303
 9304            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9305                anyhow::bail!("buffer is not open");
 9306            };
 9307
 9308            let handle = this.register_buffer_with_language_servers(
 9309                &buffer,
 9310                envelope
 9311                    .payload
 9312                    .only_servers
 9313                    .into_iter()
 9314                    .filter_map(|selector| {
 9315                        Some(match selector.selector? {
 9316                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9317                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9318                            }
 9319                            proto::language_server_selector::Selector::Name(name) => {
 9320                                LanguageServerSelector::Name(LanguageServerName(
 9321                                    SharedString::from(name),
 9322                                ))
 9323                            }
 9324                        })
 9325                    })
 9326                    .collect(),
 9327                false,
 9328                cx,
 9329            );
 9330            // Pull diagnostics for the buffer even if it was already registered.
 9331            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9332            // but it's unclear if we need it.
 9333            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9334                .detach();
 9335            this.buffer_store().update(cx, |buffer_store, _| {
 9336                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9337            });
 9338
 9339            Ok(())
 9340        })?;
 9341        Ok(proto::Ack {})
 9342    }
 9343
 9344    async fn handle_rename_project_entry(
 9345        this: Entity<Self>,
 9346        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9347        mut cx: AsyncApp,
 9348    ) -> Result<proto::ProjectEntryResponse> {
 9349        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9350        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9351        let new_path =
 9352            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9353
 9354        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9355            .update(&mut cx, |this, cx| {
 9356                let (worktree, entry) = this
 9357                    .worktree_store
 9358                    .read(cx)
 9359                    .worktree_and_entry_for_id(entry_id, cx)?;
 9360                let new_worktree = this
 9361                    .worktree_store
 9362                    .read(cx)
 9363                    .worktree_for_id(new_worktree_id, cx)?;
 9364                Some((
 9365                    this.worktree_store.clone(),
 9366                    worktree,
 9367                    new_worktree,
 9368                    entry.clone(),
 9369                ))
 9370            })
 9371            .context("worktree not found")?;
 9372        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9373            (worktree.absolutize(&old_entry.path), worktree.id())
 9374        });
 9375        let new_abs_path =
 9376            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9377
 9378        let _transaction = Self::will_rename_entry(
 9379            this.downgrade(),
 9380            old_worktree_id,
 9381            &old_abs_path,
 9382            &new_abs_path,
 9383            old_entry.is_dir(),
 9384            cx.clone(),
 9385        )
 9386        .await;
 9387        let response = WorktreeStore::handle_rename_project_entry(
 9388            worktree_store,
 9389            envelope.payload,
 9390            cx.clone(),
 9391        )
 9392        .await;
 9393        this.read_with(&cx, |this, _| {
 9394            this.did_rename_entry(
 9395                old_worktree_id,
 9396                &old_abs_path,
 9397                &new_abs_path,
 9398                old_entry.is_dir(),
 9399            );
 9400        });
 9401        response
 9402    }
 9403
 9404    async fn handle_update_diagnostic_summary(
 9405        this: Entity<Self>,
 9406        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9407        mut cx: AsyncApp,
 9408    ) -> Result<()> {
 9409        this.update(&mut cx, |lsp_store, cx| {
 9410            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9411            let mut updated_diagnostics_paths = HashMap::default();
 9412            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9413            for message_summary in envelope
 9414                .payload
 9415                .summary
 9416                .into_iter()
 9417                .chain(envelope.payload.more_summaries)
 9418            {
 9419                let project_path = ProjectPath {
 9420                    worktree_id,
 9421                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9422                };
 9423                let path = project_path.path.clone();
 9424                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9425                let summary = DiagnosticSummary {
 9426                    error_count: message_summary.error_count as usize,
 9427                    warning_count: message_summary.warning_count as usize,
 9428                };
 9429
 9430                if summary.is_empty() {
 9431                    if let Some(worktree_summaries) =
 9432                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9433                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9434                    {
 9435                        summaries.remove(&server_id);
 9436                        if summaries.is_empty() {
 9437                            worktree_summaries.remove(&path);
 9438                        }
 9439                    }
 9440                } else {
 9441                    lsp_store
 9442                        .diagnostic_summaries
 9443                        .entry(worktree_id)
 9444                        .or_default()
 9445                        .entry(path)
 9446                        .or_default()
 9447                        .insert(server_id, summary);
 9448                }
 9449
 9450                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9451                    match &mut diagnostics_summary {
 9452                        Some(diagnostics_summary) => {
 9453                            diagnostics_summary
 9454                                .more_summaries
 9455                                .push(proto::DiagnosticSummary {
 9456                                    path: project_path.path.as_ref().to_proto(),
 9457                                    language_server_id: server_id.0 as u64,
 9458                                    error_count: summary.error_count as u32,
 9459                                    warning_count: summary.warning_count as u32,
 9460                                })
 9461                        }
 9462                        None => {
 9463                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9464                                project_id: *project_id,
 9465                                worktree_id: worktree_id.to_proto(),
 9466                                summary: Some(proto::DiagnosticSummary {
 9467                                    path: project_path.path.as_ref().to_proto(),
 9468                                    language_server_id: server_id.0 as u64,
 9469                                    error_count: summary.error_count as u32,
 9470                                    warning_count: summary.warning_count as u32,
 9471                                }),
 9472                                more_summaries: Vec::new(),
 9473                            })
 9474                        }
 9475                    }
 9476                }
 9477                updated_diagnostics_paths
 9478                    .entry(server_id)
 9479                    .or_insert_with(Vec::new)
 9480                    .push(project_path);
 9481            }
 9482
 9483            if let Some((diagnostics_summary, (downstream_client, _))) =
 9484                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9485            {
 9486                downstream_client.send(diagnostics_summary).log_err();
 9487            }
 9488            for (server_id, paths) in updated_diagnostics_paths {
 9489                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9490            }
 9491            Ok(())
 9492        })
 9493    }
 9494
 9495    async fn handle_start_language_server(
 9496        lsp_store: Entity<Self>,
 9497        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9498        mut cx: AsyncApp,
 9499    ) -> Result<()> {
 9500        let server = envelope.payload.server.context("invalid server")?;
 9501        let server_capabilities =
 9502            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9503                .with_context(|| {
 9504                    format!(
 9505                        "incorrect server capabilities {}",
 9506                        envelope.payload.capabilities
 9507                    )
 9508                })?;
 9509        lsp_store.update(&mut cx, |lsp_store, cx| {
 9510            let server_id = LanguageServerId(server.id as usize);
 9511            let server_name = LanguageServerName::from_proto(server.name.clone());
 9512            lsp_store
 9513                .lsp_server_capabilities
 9514                .insert(server_id, server_capabilities);
 9515            lsp_store.language_server_statuses.insert(
 9516                server_id,
 9517                LanguageServerStatus {
 9518                    name: server_name.clone(),
 9519                    server_version: None,
 9520                    server_readable_version: None,
 9521                    pending_work: Default::default(),
 9522                    has_pending_diagnostic_updates: false,
 9523                    progress_tokens: Default::default(),
 9524                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9525                    binary: None,
 9526                    configuration: None,
 9527                    workspace_folders: BTreeSet::new(),
 9528                    process_id: None,
 9529                },
 9530            );
 9531            cx.emit(LspStoreEvent::LanguageServerAdded(
 9532                server_id,
 9533                server_name,
 9534                server.worktree_id.map(WorktreeId::from_proto),
 9535            ));
 9536            cx.notify();
 9537        });
 9538        Ok(())
 9539    }
 9540
 9541    async fn handle_update_language_server(
 9542        lsp_store: Entity<Self>,
 9543        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9544        mut cx: AsyncApp,
 9545    ) -> Result<()> {
 9546        lsp_store.update(&mut cx, |lsp_store, cx| {
 9547            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9548
 9549            match envelope.payload.variant.context("invalid variant")? {
 9550                proto::update_language_server::Variant::WorkStart(payload) => {
 9551                    lsp_store.on_lsp_work_start(
 9552                        language_server_id,
 9553                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9554                            .context("invalid progress token value")?,
 9555                        LanguageServerProgress {
 9556                            title: payload.title,
 9557                            is_disk_based_diagnostics_progress: false,
 9558                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9559                            message: payload.message,
 9560                            percentage: payload.percentage.map(|p| p as usize),
 9561                            last_update_at: cx.background_executor().now(),
 9562                        },
 9563                        cx,
 9564                    );
 9565                }
 9566                proto::update_language_server::Variant::WorkProgress(payload) => {
 9567                    lsp_store.on_lsp_work_progress(
 9568                        language_server_id,
 9569                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9570                            .context("invalid progress token value")?,
 9571                        LanguageServerProgress {
 9572                            title: None,
 9573                            is_disk_based_diagnostics_progress: false,
 9574                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9575                            message: payload.message,
 9576                            percentage: payload.percentage.map(|p| p as usize),
 9577                            last_update_at: cx.background_executor().now(),
 9578                        },
 9579                        cx,
 9580                    );
 9581                }
 9582
 9583                proto::update_language_server::Variant::WorkEnd(payload) => {
 9584                    lsp_store.on_lsp_work_end(
 9585                        language_server_id,
 9586                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9587                            .context("invalid progress token value")?,
 9588                        cx,
 9589                    );
 9590                }
 9591
 9592                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9593                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9594                }
 9595
 9596                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9597                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9598                }
 9599
 9600                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9601                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9602                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9603                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9604                        language_server_id,
 9605                        name: envelope
 9606                            .payload
 9607                            .server_name
 9608                            .map(SharedString::new)
 9609                            .map(LanguageServerName),
 9610                        message: non_lsp,
 9611                    });
 9612                }
 9613            }
 9614
 9615            Ok(())
 9616        })
 9617    }
 9618
 9619    async fn handle_language_server_log(
 9620        this: Entity<Self>,
 9621        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9622        mut cx: AsyncApp,
 9623    ) -> Result<()> {
 9624        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9625        let log_type = envelope
 9626            .payload
 9627            .log_type
 9628            .map(LanguageServerLogType::from_proto)
 9629            .context("invalid language server log type")?;
 9630
 9631        let message = envelope.payload.message;
 9632
 9633        this.update(&mut cx, |_, cx| {
 9634            cx.emit(LspStoreEvent::LanguageServerLog(
 9635                language_server_id,
 9636                log_type,
 9637                message,
 9638            ));
 9639        });
 9640        Ok(())
 9641    }
 9642
 9643    async fn handle_lsp_ext_cancel_flycheck(
 9644        lsp_store: Entity<Self>,
 9645        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9646        cx: AsyncApp,
 9647    ) -> Result<proto::Ack> {
 9648        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9649        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9650            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9651                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9652            } else {
 9653                None
 9654            }
 9655        });
 9656        if let Some(task) = task {
 9657            task.context("handling lsp ext cancel flycheck")?;
 9658        }
 9659
 9660        Ok(proto::Ack {})
 9661    }
 9662
 9663    async fn handle_lsp_ext_run_flycheck(
 9664        lsp_store: Entity<Self>,
 9665        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9666        mut cx: AsyncApp,
 9667    ) -> Result<proto::Ack> {
 9668        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9669        lsp_store.update(&mut cx, |lsp_store, cx| {
 9670            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9671                let text_document = if envelope.payload.current_file_only {
 9672                    let buffer_id = envelope
 9673                        .payload
 9674                        .buffer_id
 9675                        .map(|id| BufferId::new(id))
 9676                        .transpose()?;
 9677                    buffer_id
 9678                        .and_then(|buffer_id| {
 9679                            lsp_store
 9680                                .buffer_store()
 9681                                .read(cx)
 9682                                .get(buffer_id)
 9683                                .and_then(|buffer| {
 9684                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9685                                })
 9686                                .map(|path| make_text_document_identifier(&path))
 9687                        })
 9688                        .transpose()?
 9689                } else {
 9690                    None
 9691                };
 9692                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9693                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9694                )?;
 9695            }
 9696            anyhow::Ok(())
 9697        })?;
 9698
 9699        Ok(proto::Ack {})
 9700    }
 9701
 9702    async fn handle_lsp_ext_clear_flycheck(
 9703        lsp_store: Entity<Self>,
 9704        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9705        cx: AsyncApp,
 9706    ) -> Result<proto::Ack> {
 9707        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9708        lsp_store.read_with(&cx, |lsp_store, _| {
 9709            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9710                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9711            } else {
 9712                None
 9713            }
 9714        });
 9715
 9716        Ok(proto::Ack {})
 9717    }
 9718
 9719    pub fn disk_based_diagnostics_started(
 9720        &mut self,
 9721        language_server_id: LanguageServerId,
 9722        cx: &mut Context<Self>,
 9723    ) {
 9724        if let Some(language_server_status) =
 9725            self.language_server_statuses.get_mut(&language_server_id)
 9726        {
 9727            language_server_status.has_pending_diagnostic_updates = true;
 9728        }
 9729
 9730        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9731        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9732            language_server_id,
 9733            name: self
 9734                .language_server_adapter_for_id(language_server_id)
 9735                .map(|adapter| adapter.name()),
 9736            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9737                Default::default(),
 9738            ),
 9739        })
 9740    }
 9741
 9742    pub fn disk_based_diagnostics_finished(
 9743        &mut self,
 9744        language_server_id: LanguageServerId,
 9745        cx: &mut Context<Self>,
 9746    ) {
 9747        if let Some(language_server_status) =
 9748            self.language_server_statuses.get_mut(&language_server_id)
 9749        {
 9750            language_server_status.has_pending_diagnostic_updates = false;
 9751        }
 9752
 9753        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9754        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9755            language_server_id,
 9756            name: self
 9757                .language_server_adapter_for_id(language_server_id)
 9758                .map(|adapter| adapter.name()),
 9759            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9760                Default::default(),
 9761            ),
 9762        })
 9763    }
 9764
 9765    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9766    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9767    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9768    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9769    // the language server might take some time to publish diagnostics.
 9770    fn simulate_disk_based_diagnostics_events_if_needed(
 9771        &mut self,
 9772        language_server_id: LanguageServerId,
 9773        cx: &mut Context<Self>,
 9774    ) {
 9775        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9776
 9777        let Some(LanguageServerState::Running {
 9778            simulate_disk_based_diagnostics_completion,
 9779            adapter,
 9780            ..
 9781        }) = self
 9782            .as_local_mut()
 9783            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9784        else {
 9785            return;
 9786        };
 9787
 9788        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9789            return;
 9790        }
 9791
 9792        let prev_task =
 9793            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9794                cx.background_executor()
 9795                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9796                    .await;
 9797
 9798                this.update(cx, |this, cx| {
 9799                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9800
 9801                    if let Some(LanguageServerState::Running {
 9802                        simulate_disk_based_diagnostics_completion,
 9803                        ..
 9804                    }) = this.as_local_mut().and_then(|local_store| {
 9805                        local_store.language_servers.get_mut(&language_server_id)
 9806                    }) {
 9807                        *simulate_disk_based_diagnostics_completion = None;
 9808                    }
 9809                })
 9810                .ok();
 9811            }));
 9812
 9813        if prev_task.is_none() {
 9814            self.disk_based_diagnostics_started(language_server_id, cx);
 9815        }
 9816    }
 9817
 9818    pub fn language_server_statuses(
 9819        &self,
 9820    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9821        self.language_server_statuses
 9822            .iter()
 9823            .map(|(key, value)| (*key, value))
 9824    }
 9825
 9826    pub(super) fn did_rename_entry(
 9827        &self,
 9828        worktree_id: WorktreeId,
 9829        old_path: &Path,
 9830        new_path: &Path,
 9831        is_dir: bool,
 9832    ) {
 9833        maybe!({
 9834            let local_store = self.as_local()?;
 9835
 9836            let old_uri = lsp::Uri::from_file_path(old_path)
 9837                .ok()
 9838                .map(|uri| uri.to_string())?;
 9839            let new_uri = lsp::Uri::from_file_path(new_path)
 9840                .ok()
 9841                .map(|uri| uri.to_string())?;
 9842
 9843            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9844                let Some(filter) = local_store
 9845                    .language_server_paths_watched_for_rename
 9846                    .get(&language_server.server_id())
 9847                else {
 9848                    continue;
 9849                };
 9850
 9851                if filter.should_send_did_rename(&old_uri, is_dir) {
 9852                    language_server
 9853                        .notify::<DidRenameFiles>(RenameFilesParams {
 9854                            files: vec![FileRename {
 9855                                old_uri: old_uri.clone(),
 9856                                new_uri: new_uri.clone(),
 9857                            }],
 9858                        })
 9859                        .ok();
 9860                }
 9861            }
 9862            Some(())
 9863        });
 9864    }
 9865
 9866    pub(super) fn will_rename_entry(
 9867        this: WeakEntity<Self>,
 9868        worktree_id: WorktreeId,
 9869        old_path: &Path,
 9870        new_path: &Path,
 9871        is_dir: bool,
 9872        cx: AsyncApp,
 9873    ) -> Task<ProjectTransaction> {
 9874        let old_uri = lsp::Uri::from_file_path(old_path)
 9875            .ok()
 9876            .map(|uri| uri.to_string());
 9877        let new_uri = lsp::Uri::from_file_path(new_path)
 9878            .ok()
 9879            .map(|uri| uri.to_string());
 9880        cx.spawn(async move |cx| {
 9881            let mut tasks = vec![];
 9882            this.update(cx, |this, cx| {
 9883                let local_store = this.as_local()?;
 9884                let old_uri = old_uri?;
 9885                let new_uri = new_uri?;
 9886                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9887                    let Some(filter) = local_store
 9888                        .language_server_paths_watched_for_rename
 9889                        .get(&language_server.server_id())
 9890                    else {
 9891                        continue;
 9892                    };
 9893
 9894                    if !filter.should_send_will_rename(&old_uri, is_dir) {
 9895                        continue;
 9896                    }
 9897                    let request_timeout = ProjectSettings::get_global(cx)
 9898                        .global_lsp_settings
 9899                        .get_request_timeout();
 9900
 9901                    let apply_edit = cx.spawn({
 9902                        let old_uri = old_uri.clone();
 9903                        let new_uri = new_uri.clone();
 9904                        let language_server = language_server.clone();
 9905                        async move |this, cx| {
 9906                            let edit = language_server
 9907                                .request::<WillRenameFiles>(
 9908                                    RenameFilesParams {
 9909                                        files: vec![FileRename { old_uri, new_uri }],
 9910                                    },
 9911                                    request_timeout,
 9912                                )
 9913                                .await
 9914                                .into_response()
 9915                                .context("will rename files")
 9916                                .log_err()
 9917                                .flatten()?;
 9918
 9919                            LocalLspStore::deserialize_workspace_edit(
 9920                                this.upgrade()?,
 9921                                edit,
 9922                                false,
 9923                                language_server.clone(),
 9924                                cx,
 9925                            )
 9926                            .await
 9927                            .ok()
 9928                        }
 9929                    });
 9930                    tasks.push(apply_edit);
 9931                }
 9932                Some(())
 9933            })
 9934            .ok()
 9935            .flatten();
 9936            let mut merged_transaction = ProjectTransaction::default();
 9937            for task in tasks {
 9938                // Await on tasks sequentially so that the order of application of edits is deterministic
 9939                // (at least with regards to the order of registration of language servers)
 9940                if let Some(transaction) = task.await {
 9941                    for (buffer, buffer_transaction) in transaction.0 {
 9942                        merged_transaction.0.insert(buffer, buffer_transaction);
 9943                    }
 9944                }
 9945            }
 9946            merged_transaction
 9947        })
 9948    }
 9949
 9950    fn lsp_notify_abs_paths_changed(
 9951        &mut self,
 9952        server_id: LanguageServerId,
 9953        changes: Vec<PathEvent>,
 9954    ) {
 9955        maybe!({
 9956            let server = self.language_server_for_id(server_id)?;
 9957            let changes = changes
 9958                .into_iter()
 9959                .filter_map(|event| {
 9960                    let typ = match event.kind? {
 9961                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9962                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9963                        PathEventKind::Changed | PathEventKind::Rescan => {
 9964                            lsp::FileChangeType::CHANGED
 9965                        }
 9966                    };
 9967                    Some(lsp::FileEvent {
 9968                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9969                        typ,
 9970                    })
 9971                })
 9972                .collect::<Vec<_>>();
 9973            if !changes.is_empty() {
 9974                server
 9975                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9976                        lsp::DidChangeWatchedFilesParams { changes },
 9977                    )
 9978                    .ok();
 9979            }
 9980            Some(())
 9981        });
 9982    }
 9983
 9984    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9985        self.as_local()?.language_server_for_id(id)
 9986    }
 9987
 9988    fn on_lsp_progress(
 9989        &mut self,
 9990        progress_params: lsp::ProgressParams,
 9991        language_server_id: LanguageServerId,
 9992        disk_based_diagnostics_progress_token: Option<String>,
 9993        cx: &mut Context<Self>,
 9994    ) {
 9995        match progress_params.value {
 9996            lsp::ProgressParamsValue::WorkDone(progress) => {
 9997                self.handle_work_done_progress(
 9998                    progress,
 9999                    language_server_id,
10000                    disk_based_diagnostics_progress_token,
10001                    ProgressToken::from_lsp(progress_params.token),
10002                    cx,
10003                );
10004            }
10005            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
10006                let registration_id = match progress_params.token {
10007                    lsp::NumberOrString::Number(_) => None,
10008                    lsp::NumberOrString::String(token) => token
10009                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
10010                        .map(|(_, id)| id.to_owned()),
10011                };
10012                if let Some(LanguageServerState::Running {
10013                    workspace_diagnostics_refresh_tasks,
10014                    ..
10015                }) = self
10016                    .as_local_mut()
10017                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
10018                    && let Some(workspace_diagnostics) =
10019                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
10020                {
10021                    workspace_diagnostics.progress_tx.try_send(()).ok();
10022                    self.apply_workspace_diagnostic_report(
10023                        language_server_id,
10024                        report,
10025                        registration_id.map(SharedString::from),
10026                        cx,
10027                    )
10028                }
10029            }
10030        }
10031    }
10032
10033    fn handle_work_done_progress(
10034        &mut self,
10035        progress: lsp::WorkDoneProgress,
10036        language_server_id: LanguageServerId,
10037        disk_based_diagnostics_progress_token: Option<String>,
10038        token: ProgressToken,
10039        cx: &mut Context<Self>,
10040    ) {
10041        let language_server_status =
10042            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10043                status
10044            } else {
10045                return;
10046            };
10047
10048        if !language_server_status.progress_tokens.contains(&token) {
10049            return;
10050        }
10051
10052        let is_disk_based_diagnostics_progress =
10053            if let (Some(disk_based_token), ProgressToken::String(token)) =
10054                (&disk_based_diagnostics_progress_token, &token)
10055            {
10056                token.starts_with(disk_based_token)
10057            } else {
10058                false
10059            };
10060
10061        match progress {
10062            lsp::WorkDoneProgress::Begin(report) => {
10063                if is_disk_based_diagnostics_progress {
10064                    self.disk_based_diagnostics_started(language_server_id, cx);
10065                }
10066                self.on_lsp_work_start(
10067                    language_server_id,
10068                    token.clone(),
10069                    LanguageServerProgress {
10070                        title: Some(report.title),
10071                        is_disk_based_diagnostics_progress,
10072                        is_cancellable: report.cancellable.unwrap_or(false),
10073                        message: report.message.clone(),
10074                        percentage: report.percentage.map(|p| p as usize),
10075                        last_update_at: cx.background_executor().now(),
10076                    },
10077                    cx,
10078                );
10079            }
10080            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10081                language_server_id,
10082                token,
10083                LanguageServerProgress {
10084                    title: None,
10085                    is_disk_based_diagnostics_progress,
10086                    is_cancellable: report.cancellable.unwrap_or(false),
10087                    message: report.message,
10088                    percentage: report.percentage.map(|p| p as usize),
10089                    last_update_at: cx.background_executor().now(),
10090                },
10091                cx,
10092            ),
10093            lsp::WorkDoneProgress::End(_) => {
10094                language_server_status.progress_tokens.remove(&token);
10095                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10096                if is_disk_based_diagnostics_progress {
10097                    self.disk_based_diagnostics_finished(language_server_id, cx);
10098                }
10099            }
10100        }
10101    }
10102
10103    fn on_lsp_work_start(
10104        &mut self,
10105        language_server_id: LanguageServerId,
10106        token: ProgressToken,
10107        progress: LanguageServerProgress,
10108        cx: &mut Context<Self>,
10109    ) {
10110        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10111            status.pending_work.insert(token.clone(), progress.clone());
10112            cx.notify();
10113        }
10114        cx.emit(LspStoreEvent::LanguageServerUpdate {
10115            language_server_id,
10116            name: self
10117                .language_server_adapter_for_id(language_server_id)
10118                .map(|adapter| adapter.name()),
10119            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10120                token: Some(token.to_proto()),
10121                title: progress.title,
10122                message: progress.message,
10123                percentage: progress.percentage.map(|p| p as u32),
10124                is_cancellable: Some(progress.is_cancellable),
10125            }),
10126        })
10127    }
10128
10129    fn on_lsp_work_progress(
10130        &mut self,
10131        language_server_id: LanguageServerId,
10132        token: ProgressToken,
10133        progress: LanguageServerProgress,
10134        cx: &mut Context<Self>,
10135    ) {
10136        let mut did_update = false;
10137        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10138            match status.pending_work.entry(token.clone()) {
10139                btree_map::Entry::Vacant(entry) => {
10140                    entry.insert(progress.clone());
10141                    did_update = true;
10142                }
10143                btree_map::Entry::Occupied(mut entry) => {
10144                    let entry = entry.get_mut();
10145                    if (progress.last_update_at - entry.last_update_at)
10146                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10147                    {
10148                        entry.last_update_at = progress.last_update_at;
10149                        if progress.message.is_some() {
10150                            entry.message = progress.message.clone();
10151                        }
10152                        if progress.percentage.is_some() {
10153                            entry.percentage = progress.percentage;
10154                        }
10155                        if progress.is_cancellable != entry.is_cancellable {
10156                            entry.is_cancellable = progress.is_cancellable;
10157                        }
10158                        did_update = true;
10159                    }
10160                }
10161            }
10162        }
10163
10164        if did_update {
10165            cx.emit(LspStoreEvent::LanguageServerUpdate {
10166                language_server_id,
10167                name: self
10168                    .language_server_adapter_for_id(language_server_id)
10169                    .map(|adapter| adapter.name()),
10170                message: proto::update_language_server::Variant::WorkProgress(
10171                    proto::LspWorkProgress {
10172                        token: Some(token.to_proto()),
10173                        message: progress.message,
10174                        percentage: progress.percentage.map(|p| p as u32),
10175                        is_cancellable: Some(progress.is_cancellable),
10176                    },
10177                ),
10178            })
10179        }
10180    }
10181
10182    fn on_lsp_work_end(
10183        &mut self,
10184        language_server_id: LanguageServerId,
10185        token: ProgressToken,
10186        cx: &mut Context<Self>,
10187    ) {
10188        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10189            if let Some(work) = status.pending_work.remove(&token)
10190                && !work.is_disk_based_diagnostics_progress
10191            {
10192                cx.emit(LspStoreEvent::RefreshInlayHints {
10193                    server_id: language_server_id,
10194                    request_id: None,
10195                });
10196            }
10197            cx.notify();
10198        }
10199
10200        cx.emit(LspStoreEvent::LanguageServerUpdate {
10201            language_server_id,
10202            name: self
10203                .language_server_adapter_for_id(language_server_id)
10204                .map(|adapter| adapter.name()),
10205            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10206                token: Some(token.to_proto()),
10207            }),
10208        })
10209    }
10210
10211    pub async fn handle_resolve_completion_documentation(
10212        this: Entity<Self>,
10213        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10214        mut cx: AsyncApp,
10215    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10216        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10217
10218        let completion = this
10219            .read_with(&cx, |this, cx| {
10220                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10221                let server = this
10222                    .language_server_for_id(id)
10223                    .with_context(|| format!("No language server {id}"))?;
10224
10225                let request_timeout = ProjectSettings::get_global(cx)
10226                    .global_lsp_settings
10227                    .get_request_timeout();
10228
10229                anyhow::Ok(cx.background_spawn(async move {
10230                    let can_resolve = server
10231                        .capabilities()
10232                        .completion_provider
10233                        .as_ref()
10234                        .and_then(|options| options.resolve_provider)
10235                        .unwrap_or(false);
10236                    if can_resolve {
10237                        server
10238                            .request::<lsp::request::ResolveCompletionItem>(
10239                                lsp_completion,
10240                                request_timeout,
10241                            )
10242                            .await
10243                            .into_response()
10244                            .context("resolve completion item")
10245                    } else {
10246                        anyhow::Ok(lsp_completion)
10247                    }
10248                }))
10249            })?
10250            .await?;
10251
10252        let mut documentation_is_markdown = false;
10253        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10254        let documentation = match completion.documentation {
10255            Some(lsp::Documentation::String(text)) => text,
10256
10257            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10258                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10259                value
10260            }
10261
10262            _ => String::new(),
10263        };
10264
10265        // If we have a new buffer_id, that means we're talking to a new client
10266        // and want to check for new text_edits in the completion too.
10267        let mut old_replace_start = None;
10268        let mut old_replace_end = None;
10269        let mut old_insert_start = None;
10270        let mut old_insert_end = None;
10271        let mut new_text = String::default();
10272        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10273            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10274                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10275                anyhow::Ok(buffer.read(cx).snapshot())
10276            })?;
10277
10278            if let Some(text_edit) = completion.text_edit.as_ref() {
10279                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10280
10281                if let Some(mut edit) = edit {
10282                    LineEnding::normalize(&mut edit.new_text);
10283
10284                    new_text = edit.new_text;
10285                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10286                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10287                    if let Some(insert_range) = edit.insert_range {
10288                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10289                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10290                    }
10291                }
10292            }
10293        }
10294
10295        Ok(proto::ResolveCompletionDocumentationResponse {
10296            documentation,
10297            documentation_is_markdown,
10298            old_replace_start,
10299            old_replace_end,
10300            new_text,
10301            lsp_completion,
10302            old_insert_start,
10303            old_insert_end,
10304        })
10305    }
10306
10307    async fn handle_on_type_formatting(
10308        this: Entity<Self>,
10309        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10310        mut cx: AsyncApp,
10311    ) -> Result<proto::OnTypeFormattingResponse> {
10312        let on_type_formatting = this.update(&mut cx, |this, cx| {
10313            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10314            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10315            let position = envelope
10316                .payload
10317                .position
10318                .and_then(deserialize_anchor)
10319                .context("invalid position")?;
10320            anyhow::Ok(this.apply_on_type_formatting(
10321                buffer,
10322                position,
10323                envelope.payload.trigger.clone(),
10324                cx,
10325            ))
10326        })?;
10327
10328        let transaction = on_type_formatting
10329            .await?
10330            .as_ref()
10331            .map(language::proto::serialize_transaction);
10332        Ok(proto::OnTypeFormattingResponse { transaction })
10333    }
10334
10335    async fn handle_pull_workspace_diagnostics(
10336        lsp_store: Entity<Self>,
10337        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10338        mut cx: AsyncApp,
10339    ) -> Result<proto::Ack> {
10340        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10341        lsp_store.update(&mut cx, |lsp_store, _| {
10342            lsp_store.pull_workspace_diagnostics(server_id);
10343        });
10344        Ok(proto::Ack {})
10345    }
10346
10347    async fn handle_open_buffer_for_symbol(
10348        this: Entity<Self>,
10349        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10350        mut cx: AsyncApp,
10351    ) -> Result<proto::OpenBufferForSymbolResponse> {
10352        let peer_id = envelope.original_sender_id().unwrap_or_default();
10353        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10354        let symbol = Self::deserialize_symbol(symbol)?;
10355        this.read_with(&cx, |this, _| {
10356            if let SymbolLocation::OutsideProject {
10357                abs_path,
10358                signature,
10359            } = &symbol.path
10360            {
10361                let new_signature = this.symbol_signature(&abs_path);
10362                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10363            }
10364            Ok(())
10365        })?;
10366        let buffer = this
10367            .update(&mut cx, |this, cx| {
10368                this.open_buffer_for_symbol(
10369                    &Symbol {
10370                        language_server_name: symbol.language_server_name,
10371                        source_worktree_id: symbol.source_worktree_id,
10372                        source_language_server_id: symbol.source_language_server_id,
10373                        path: symbol.path,
10374                        name: symbol.name,
10375                        kind: symbol.kind,
10376                        range: symbol.range,
10377                        label: CodeLabel::default(),
10378                        container_name: symbol.container_name,
10379                    },
10380                    cx,
10381                )
10382            })
10383            .await?;
10384
10385        this.update(&mut cx, |this, cx| {
10386            let is_private = buffer
10387                .read(cx)
10388                .file()
10389                .map(|f| f.is_private())
10390                .unwrap_or_default();
10391            if is_private {
10392                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10393            } else {
10394                this.buffer_store
10395                    .update(cx, |buffer_store, cx| {
10396                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10397                    })
10398                    .detach_and_log_err(cx);
10399                let buffer_id = buffer.read(cx).remote_id().to_proto();
10400                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10401            }
10402        })
10403    }
10404
10405    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10406        let mut hasher = Sha256::new();
10407        hasher.update(abs_path.to_string_lossy().as_bytes());
10408        hasher.update(self.nonce.to_be_bytes());
10409        hasher.finalize().as_slice().try_into().unwrap()
10410    }
10411
10412    pub async fn handle_get_project_symbols(
10413        this: Entity<Self>,
10414        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10415        mut cx: AsyncApp,
10416    ) -> Result<proto::GetProjectSymbolsResponse> {
10417        let symbols = this
10418            .update(&mut cx, |this, cx| {
10419                this.symbols(&envelope.payload.query, cx)
10420            })
10421            .await?;
10422
10423        Ok(proto::GetProjectSymbolsResponse {
10424            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10425        })
10426    }
10427
10428    pub async fn handle_restart_language_servers(
10429        this: Entity<Self>,
10430        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10431        mut cx: AsyncApp,
10432    ) -> Result<proto::Ack> {
10433        this.update(&mut cx, |lsp_store, cx| {
10434            let buffers =
10435                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10436            lsp_store.restart_language_servers_for_buffers(
10437                buffers,
10438                envelope
10439                    .payload
10440                    .only_servers
10441                    .into_iter()
10442                    .filter_map(|selector| {
10443                        Some(match selector.selector? {
10444                            proto::language_server_selector::Selector::ServerId(server_id) => {
10445                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10446                            }
10447                            proto::language_server_selector::Selector::Name(name) => {
10448                                LanguageServerSelector::Name(LanguageServerName(
10449                                    SharedString::from(name),
10450                                ))
10451                            }
10452                        })
10453                    })
10454                    .collect(),
10455                cx,
10456            );
10457        });
10458
10459        Ok(proto::Ack {})
10460    }
10461
10462    pub async fn handle_stop_language_servers(
10463        lsp_store: Entity<Self>,
10464        envelope: TypedEnvelope<proto::StopLanguageServers>,
10465        mut cx: AsyncApp,
10466    ) -> Result<proto::Ack> {
10467        lsp_store.update(&mut cx, |lsp_store, cx| {
10468            if envelope.payload.all
10469                && envelope.payload.also_servers.is_empty()
10470                && envelope.payload.buffer_ids.is_empty()
10471            {
10472                lsp_store.stop_all_language_servers(cx);
10473            } else {
10474                let buffers =
10475                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10476                lsp_store
10477                    .stop_language_servers_for_buffers(
10478                        buffers,
10479                        envelope
10480                            .payload
10481                            .also_servers
10482                            .into_iter()
10483                            .filter_map(|selector| {
10484                                Some(match selector.selector? {
10485                                    proto::language_server_selector::Selector::ServerId(
10486                                        server_id,
10487                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10488                                        server_id,
10489                                    )),
10490                                    proto::language_server_selector::Selector::Name(name) => {
10491                                        LanguageServerSelector::Name(LanguageServerName(
10492                                            SharedString::from(name),
10493                                        ))
10494                                    }
10495                                })
10496                            })
10497                            .collect(),
10498                        cx,
10499                    )
10500                    .detach_and_log_err(cx);
10501            }
10502        });
10503
10504        Ok(proto::Ack {})
10505    }
10506
10507    pub async fn handle_cancel_language_server_work(
10508        lsp_store: Entity<Self>,
10509        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10510        mut cx: AsyncApp,
10511    ) -> Result<proto::Ack> {
10512        lsp_store.update(&mut cx, |lsp_store, cx| {
10513            if let Some(work) = envelope.payload.work {
10514                match work {
10515                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10516                        let buffers =
10517                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10518                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10519                    }
10520                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10521                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10522                        let token = work
10523                            .token
10524                            .map(|token| {
10525                                ProgressToken::from_proto(token)
10526                                    .context("invalid work progress token")
10527                            })
10528                            .transpose()?;
10529                        lsp_store.cancel_language_server_work(server_id, token, cx);
10530                    }
10531                }
10532            }
10533            anyhow::Ok(())
10534        })?;
10535
10536        Ok(proto::Ack {})
10537    }
10538
10539    fn buffer_ids_to_buffers(
10540        &mut self,
10541        buffer_ids: impl Iterator<Item = u64>,
10542        cx: &mut Context<Self>,
10543    ) -> Vec<Entity<Buffer>> {
10544        buffer_ids
10545            .into_iter()
10546            .flat_map(|buffer_id| {
10547                self.buffer_store
10548                    .read(cx)
10549                    .get(BufferId::new(buffer_id).log_err()?)
10550            })
10551            .collect::<Vec<_>>()
10552    }
10553
10554    async fn handle_apply_additional_edits_for_completion(
10555        this: Entity<Self>,
10556        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10557        mut cx: AsyncApp,
10558    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10559        let (buffer, completion, all_commit_ranges) = this.update(&mut cx, |this, cx| {
10560            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10561            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10562            let completion = Self::deserialize_completion(
10563                envelope.payload.completion.context("invalid completion")?,
10564            )?;
10565            let all_commit_ranges = envelope
10566                .payload
10567                .all_commit_ranges
10568                .into_iter()
10569                .map(language::proto::deserialize_anchor_range)
10570                .collect::<Result<Vec<_>, _>>()?;
10571            anyhow::Ok((buffer, completion, all_commit_ranges))
10572        })?;
10573
10574        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10575            this.apply_additional_edits_for_completion(
10576                buffer,
10577                Rc::new(RefCell::new(Box::new([Completion {
10578                    replace_range: completion.replace_range,
10579                    new_text: completion.new_text,
10580                    source: completion.source,
10581                    documentation: None,
10582                    label: CodeLabel::default(),
10583                    match_start: None,
10584                    snippet_deduplication_key: None,
10585                    insert_text_mode: None,
10586                    icon_path: None,
10587                    confirm: None,
10588                }]))),
10589                0,
10590                false,
10591                all_commit_ranges,
10592                cx,
10593            )
10594        });
10595
10596        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10597            transaction: apply_additional_edits
10598                .await?
10599                .as_ref()
10600                .map(language::proto::serialize_transaction),
10601        })
10602    }
10603
10604    pub fn last_formatting_failure(&self) -> Option<&str> {
10605        self.last_formatting_failure.as_deref()
10606    }
10607
10608    pub fn reset_last_formatting_failure(&mut self) {
10609        self.last_formatting_failure = None;
10610    }
10611
10612    pub fn environment_for_buffer(
10613        &self,
10614        buffer: &Entity<Buffer>,
10615        cx: &mut Context<Self>,
10616    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10617        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10618            environment.update(cx, |env, cx| {
10619                env.buffer_environment(buffer, &self.worktree_store, cx)
10620            })
10621        } else {
10622            Task::ready(None).shared()
10623        }
10624    }
10625
10626    pub fn format(
10627        &mut self,
10628        buffers: HashSet<Entity<Buffer>>,
10629        target: LspFormatTarget,
10630        push_to_history: bool,
10631        trigger: FormatTrigger,
10632        cx: &mut Context<Self>,
10633    ) -> Task<anyhow::Result<ProjectTransaction>> {
10634        let logger = zlog::scoped!("format");
10635        if self.as_local().is_some() {
10636            zlog::trace!(logger => "Formatting locally");
10637            let logger = zlog::scoped!(logger => "local");
10638            let buffers = buffers
10639                .into_iter()
10640                .map(|buffer_handle| {
10641                    let buffer = buffer_handle.read(cx);
10642                    let buffer_abs_path = File::from_dyn(buffer.file())
10643                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10644
10645                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10646                })
10647                .collect::<Vec<_>>();
10648
10649            cx.spawn(async move |lsp_store, cx| {
10650                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10651
10652                for (handle, abs_path, id) in buffers {
10653                    let env = lsp_store
10654                        .update(cx, |lsp_store, cx| {
10655                            lsp_store.environment_for_buffer(&handle, cx)
10656                        })?
10657                        .await;
10658
10659                    let ranges = match &target {
10660                        LspFormatTarget::Buffers => None,
10661                        LspFormatTarget::Ranges(ranges) => {
10662                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10663                        }
10664                    };
10665
10666                    formattable_buffers.push(FormattableBuffer {
10667                        handle,
10668                        abs_path,
10669                        env,
10670                        ranges,
10671                    });
10672                }
10673                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10674
10675                let format_timer = zlog::time!(logger => "Formatting buffers");
10676                let result = LocalLspStore::format_locally(
10677                    lsp_store.clone(),
10678                    formattable_buffers,
10679                    push_to_history,
10680                    trigger,
10681                    logger,
10682                    cx,
10683                )
10684                .await;
10685                format_timer.end();
10686
10687                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10688
10689                lsp_store.update(cx, |lsp_store, _| {
10690                    lsp_store.update_last_formatting_failure(&result);
10691                })?;
10692
10693                result
10694            })
10695        } else if let Some((client, project_id)) = self.upstream_client() {
10696            zlog::trace!(logger => "Formatting remotely");
10697            let logger = zlog::scoped!(logger => "remote");
10698
10699            let buffer_ranges = match &target {
10700                LspFormatTarget::Buffers => Vec::new(),
10701                LspFormatTarget::Ranges(ranges) => ranges
10702                    .iter()
10703                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10704                        buffer_id: buffer_id.to_proto(),
10705                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10706                    })
10707                    .collect(),
10708            };
10709
10710            let buffer_store = self.buffer_store();
10711            cx.spawn(async move |lsp_store, cx| {
10712                zlog::trace!(logger => "Sending remote format request");
10713                let request_timer = zlog::time!(logger => "remote format request");
10714                let result = client
10715                    .request(proto::FormatBuffers {
10716                        project_id,
10717                        trigger: trigger as i32,
10718                        buffer_ids: buffers
10719                            .iter()
10720                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10721                            .collect(),
10722                        buffer_ranges,
10723                    })
10724                    .await
10725                    .and_then(|result| result.transaction.context("missing transaction"));
10726                request_timer.end();
10727
10728                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10729
10730                lsp_store.update(cx, |lsp_store, _| {
10731                    lsp_store.update_last_formatting_failure(&result);
10732                })?;
10733
10734                let transaction_response = result?;
10735                let _timer = zlog::time!(logger => "deserializing project transaction");
10736                buffer_store
10737                    .update(cx, |buffer_store, cx| {
10738                        buffer_store.deserialize_project_transaction(
10739                            transaction_response,
10740                            push_to_history,
10741                            cx,
10742                        )
10743                    })
10744                    .await
10745            })
10746        } else {
10747            zlog::trace!(logger => "Not formatting");
10748            Task::ready(Ok(ProjectTransaction::default()))
10749        }
10750    }
10751
10752    async fn handle_format_buffers(
10753        this: Entity<Self>,
10754        envelope: TypedEnvelope<proto::FormatBuffers>,
10755        mut cx: AsyncApp,
10756    ) -> Result<proto::FormatBuffersResponse> {
10757        let sender_id = envelope.original_sender_id().unwrap_or_default();
10758        let format = this.update(&mut cx, |this, cx| {
10759            let mut buffers = HashSet::default();
10760            for buffer_id in &envelope.payload.buffer_ids {
10761                let buffer_id = BufferId::new(*buffer_id)?;
10762                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10763            }
10764
10765            let target = if envelope.payload.buffer_ranges.is_empty() {
10766                LspFormatTarget::Buffers
10767            } else {
10768                let mut ranges_map = BTreeMap::new();
10769                for buffer_range in &envelope.payload.buffer_ranges {
10770                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10771                    let ranges: Result<Vec<_>> = buffer_range
10772                        .ranges
10773                        .iter()
10774                        .map(|range| {
10775                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10776                        })
10777                        .collect();
10778                    ranges_map.insert(buffer_id, ranges?);
10779                }
10780                LspFormatTarget::Ranges(ranges_map)
10781            };
10782
10783            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10784            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10785        })?;
10786
10787        let project_transaction = format.await?;
10788        let project_transaction = this.update(&mut cx, |this, cx| {
10789            this.buffer_store.update(cx, |buffer_store, cx| {
10790                buffer_store.serialize_project_transaction_for_peer(
10791                    project_transaction,
10792                    sender_id,
10793                    cx,
10794                )
10795            })
10796        });
10797        Ok(proto::FormatBuffersResponse {
10798            transaction: Some(project_transaction),
10799        })
10800    }
10801
10802    async fn handle_apply_code_action_kind(
10803        this: Entity<Self>,
10804        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10805        mut cx: AsyncApp,
10806    ) -> Result<proto::ApplyCodeActionKindResponse> {
10807        let sender_id = envelope.original_sender_id().unwrap_or_default();
10808        let format = this.update(&mut cx, |this, cx| {
10809            let mut buffers = HashSet::default();
10810            for buffer_id in &envelope.payload.buffer_ids {
10811                let buffer_id = BufferId::new(*buffer_id)?;
10812                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10813            }
10814            let kind = match envelope.payload.kind.as_str() {
10815                "" => CodeActionKind::EMPTY,
10816                "quickfix" => CodeActionKind::QUICKFIX,
10817                "refactor" => CodeActionKind::REFACTOR,
10818                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10819                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10820                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10821                "source" => CodeActionKind::SOURCE,
10822                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10823                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10824                _ => anyhow::bail!(
10825                    "Invalid code action kind {}",
10826                    envelope.payload.kind.as_str()
10827                ),
10828            };
10829            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10830        })?;
10831
10832        let project_transaction = format.await?;
10833        let project_transaction = this.update(&mut cx, |this, cx| {
10834            this.buffer_store.update(cx, |buffer_store, cx| {
10835                buffer_store.serialize_project_transaction_for_peer(
10836                    project_transaction,
10837                    sender_id,
10838                    cx,
10839                )
10840            })
10841        });
10842        Ok(proto::ApplyCodeActionKindResponse {
10843            transaction: Some(project_transaction),
10844        })
10845    }
10846
10847    async fn shutdown_language_server(
10848        server_state: Option<LanguageServerState>,
10849        name: LanguageServerName,
10850        cx: &mut AsyncApp,
10851    ) {
10852        let server = match server_state {
10853            Some(LanguageServerState::Starting { startup, .. }) => {
10854                let mut timer = cx
10855                    .background_executor()
10856                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10857                    .fuse();
10858
10859                select! {
10860                    server = startup.fuse() => server,
10861                    () = timer => {
10862                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10863                        None
10864                    },
10865                }
10866            }
10867
10868            Some(LanguageServerState::Running { server, .. }) => Some(server),
10869
10870            None => None,
10871        };
10872
10873        let Some(server) = server else { return };
10874        if let Some(shutdown) = server.shutdown() {
10875            shutdown.await;
10876        }
10877    }
10878
10879    // Returns a list of all of the worktrees which no longer have a language server and the root path
10880    // for the stopped server
10881    fn stop_local_language_server(
10882        &mut self,
10883        server_id: LanguageServerId,
10884        cx: &mut Context<Self>,
10885    ) -> Task<()> {
10886        let local = match &mut self.mode {
10887            LspStoreMode::Local(local) => local,
10888            _ => {
10889                return Task::ready(());
10890            }
10891        };
10892
10893        // Remove this server ID from all entries in the given worktree.
10894        local
10895            .language_server_ids
10896            .retain(|_, state| state.id != server_id);
10897        self.buffer_store.update(cx, |buffer_store, cx| {
10898            for buffer in buffer_store.buffers() {
10899                buffer.update(cx, |buffer, cx| {
10900                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10901                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10902                });
10903            }
10904        });
10905
10906        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
10907        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10908            summaries.retain(|path, summaries_by_server_id| {
10909                if summaries_by_server_id.remove(&server_id).is_some() {
10910                    if let Some((client, project_id)) = self.downstream_client.clone() {
10911                        client
10912                            .send(proto::UpdateDiagnosticSummary {
10913                                project_id,
10914                                worktree_id: worktree_id.to_proto(),
10915                                summary: Some(proto::DiagnosticSummary {
10916                                    path: path.as_ref().to_proto(),
10917                                    language_server_id: server_id.0 as u64,
10918                                    error_count: 0,
10919                                    warning_count: 0,
10920                                }),
10921                                more_summaries: Vec::new(),
10922                            })
10923                            .log_err();
10924                    }
10925                    cleared_paths.push(ProjectPath {
10926                        worktree_id: *worktree_id,
10927                        path: path.clone(),
10928                    });
10929                    !summaries_by_server_id.is_empty()
10930                } else {
10931                    true
10932                }
10933            });
10934        }
10935        if !cleared_paths.is_empty() {
10936            cx.emit(LspStoreEvent::DiagnosticsUpdated {
10937                server_id,
10938                paths: cleared_paths,
10939            });
10940        }
10941
10942        let local = self.as_local_mut().unwrap();
10943        for diagnostics in local.diagnostics.values_mut() {
10944            diagnostics.retain(|_, diagnostics_by_server_id| {
10945                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10946                    diagnostics_by_server_id.remove(ix);
10947                    !diagnostics_by_server_id.is_empty()
10948                } else {
10949                    true
10950                }
10951            });
10952        }
10953        local.language_server_watched_paths.remove(&server_id);
10954
10955        let server_state = local.language_servers.remove(&server_id);
10956        self.cleanup_lsp_data(server_id);
10957        let name = self
10958            .language_server_statuses
10959            .remove(&server_id)
10960            .map(|status| status.name)
10961            .or_else(|| {
10962                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10963                    Some(adapter.name())
10964                } else {
10965                    None
10966                }
10967            });
10968
10969        if let Some(name) = name {
10970            log::info!("stopping language server {name}");
10971            self.languages
10972                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10973            cx.notify();
10974
10975            return cx.spawn(async move |lsp_store, cx| {
10976                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10977                lsp_store
10978                    .update(cx, |lsp_store, cx| {
10979                        lsp_store
10980                            .languages
10981                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10982                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10983                        cx.notify();
10984                    })
10985                    .ok();
10986            });
10987        }
10988
10989        if server_state.is_some() {
10990            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10991        }
10992        Task::ready(())
10993    }
10994
10995    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10996        self.shutdown_all_language_servers(cx).detach();
10997    }
10998
10999    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
11000        if let Some((client, project_id)) = self.upstream_client() {
11001            let request = client.request(proto::StopLanguageServers {
11002                project_id,
11003                buffer_ids: Vec::new(),
11004                also_servers: Vec::new(),
11005                all: true,
11006            });
11007            cx.background_spawn(async move {
11008                request.await.ok();
11009            })
11010        } else {
11011            let Some(local) = self.as_local_mut() else {
11012                return Task::ready(());
11013            };
11014            let language_servers_to_stop = local
11015                .language_server_ids
11016                .values()
11017                .map(|state| state.id)
11018                .collect();
11019            local.lsp_tree.remove_nodes(&language_servers_to_stop);
11020            let tasks = language_servers_to_stop
11021                .into_iter()
11022                .map(|server| self.stop_local_language_server(server, cx))
11023                .collect::<Vec<_>>();
11024            cx.background_spawn(async move {
11025                futures::future::join_all(tasks).await;
11026            })
11027        }
11028    }
11029
11030    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
11031        let buffers = self.buffer_store.read(cx).buffers().collect();
11032        self.restart_language_servers_for_buffers(buffers, HashSet::default(), cx);
11033    }
11034
11035    pub fn restart_language_servers_for_buffers(
11036        &mut self,
11037        buffers: Vec<Entity<Buffer>>,
11038        only_restart_servers: HashSet<LanguageServerSelector>,
11039        cx: &mut Context<Self>,
11040    ) {
11041        if let Some((client, project_id)) = self.upstream_client() {
11042            let request = client.request(proto::RestartLanguageServers {
11043                project_id,
11044                buffer_ids: buffers
11045                    .into_iter()
11046                    .map(|b| b.read(cx).remote_id().to_proto())
11047                    .collect(),
11048                only_servers: only_restart_servers
11049                    .into_iter()
11050                    .map(|selector| {
11051                        let selector = match selector {
11052                            LanguageServerSelector::Id(language_server_id) => {
11053                                proto::language_server_selector::Selector::ServerId(
11054                                    language_server_id.to_proto(),
11055                                )
11056                            }
11057                            LanguageServerSelector::Name(language_server_name) => {
11058                                proto::language_server_selector::Selector::Name(
11059                                    language_server_name.to_string(),
11060                                )
11061                            }
11062                        };
11063                        proto::LanguageServerSelector {
11064                            selector: Some(selector),
11065                        }
11066                    })
11067                    .collect(),
11068                all: false,
11069            });
11070            cx.background_spawn(request).detach_and_log_err(cx);
11071        } else {
11072            let stop_task = if only_restart_servers.is_empty() {
11073                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11074            } else {
11075                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11076            };
11077            cx.spawn(async move |lsp_store, cx| {
11078                stop_task.await;
11079                lsp_store.update(cx, |lsp_store, cx| {
11080                    for buffer in buffers {
11081                        lsp_store.register_buffer_with_language_servers(
11082                            &buffer,
11083                            only_restart_servers.clone(),
11084                            true,
11085                            cx,
11086                        );
11087                    }
11088                })
11089            })
11090            .detach();
11091        }
11092    }
11093
11094    pub fn stop_language_servers_for_buffers(
11095        &mut self,
11096        buffers: Vec<Entity<Buffer>>,
11097        also_stop_servers: HashSet<LanguageServerSelector>,
11098        cx: &mut Context<Self>,
11099    ) -> Task<Result<()>> {
11100        if let Some((client, project_id)) = self.upstream_client() {
11101            let request = client.request(proto::StopLanguageServers {
11102                project_id,
11103                buffer_ids: buffers
11104                    .into_iter()
11105                    .map(|b| b.read(cx).remote_id().to_proto())
11106                    .collect(),
11107                also_servers: also_stop_servers
11108                    .into_iter()
11109                    .map(|selector| {
11110                        let selector = match selector {
11111                            LanguageServerSelector::Id(language_server_id) => {
11112                                proto::language_server_selector::Selector::ServerId(
11113                                    language_server_id.to_proto(),
11114                                )
11115                            }
11116                            LanguageServerSelector::Name(language_server_name) => {
11117                                proto::language_server_selector::Selector::Name(
11118                                    language_server_name.to_string(),
11119                                )
11120                            }
11121                        };
11122                        proto::LanguageServerSelector {
11123                            selector: Some(selector),
11124                        }
11125                    })
11126                    .collect(),
11127                all: false,
11128            });
11129            cx.background_spawn(async move {
11130                let _ = request.await?;
11131                Ok(())
11132            })
11133        } else {
11134            let task =
11135                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11136            cx.background_spawn(async move {
11137                task.await;
11138                Ok(())
11139            })
11140        }
11141    }
11142
11143    fn stop_local_language_servers_for_buffers(
11144        &mut self,
11145        buffers: &[Entity<Buffer>],
11146        also_stop_servers: HashSet<LanguageServerSelector>,
11147        cx: &mut Context<Self>,
11148    ) -> Task<()> {
11149        let Some(local) = self.as_local_mut() else {
11150            return Task::ready(());
11151        };
11152        let mut language_server_names_to_stop = BTreeSet::default();
11153        let mut language_servers_to_stop = also_stop_servers
11154            .into_iter()
11155            .flat_map(|selector| match selector {
11156                LanguageServerSelector::Id(id) => Some(id),
11157                LanguageServerSelector::Name(name) => {
11158                    language_server_names_to_stop.insert(name);
11159                    None
11160                }
11161            })
11162            .collect::<BTreeSet<_>>();
11163
11164        let mut covered_worktrees = HashSet::default();
11165        for buffer in buffers {
11166            buffer.update(cx, |buffer, cx| {
11167                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11168                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11169                    && covered_worktrees.insert(worktree_id)
11170                {
11171                    language_server_names_to_stop.retain(|name| {
11172                        let old_ids_count = language_servers_to_stop.len();
11173                        let all_language_servers_with_this_name = local
11174                            .language_server_ids
11175                            .iter()
11176                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11177                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11178                        old_ids_count == language_servers_to_stop.len()
11179                    });
11180                }
11181            });
11182        }
11183        for name in language_server_names_to_stop {
11184            language_servers_to_stop.extend(
11185                local
11186                    .language_server_ids
11187                    .iter()
11188                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11189            );
11190        }
11191
11192        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11193        let tasks = language_servers_to_stop
11194            .into_iter()
11195            .map(|server| self.stop_local_language_server(server, cx))
11196            .collect::<Vec<_>>();
11197
11198        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11199    }
11200
11201    #[cfg(any(test, feature = "test-support"))]
11202    pub fn update_diagnostics(
11203        &mut self,
11204        server_id: LanguageServerId,
11205        diagnostics: lsp::PublishDiagnosticsParams,
11206        result_id: Option<SharedString>,
11207        source_kind: DiagnosticSourceKind,
11208        disk_based_sources: &[String],
11209        cx: &mut Context<Self>,
11210    ) -> Result<()> {
11211        self.merge_lsp_diagnostics(
11212            source_kind,
11213            vec![DocumentDiagnosticsUpdate {
11214                diagnostics,
11215                result_id,
11216                server_id,
11217                disk_based_sources: Cow::Borrowed(disk_based_sources),
11218                registration_id: None,
11219            }],
11220            |_, _, _| false,
11221            cx,
11222        )
11223    }
11224
11225    pub fn merge_lsp_diagnostics(
11226        &mut self,
11227        source_kind: DiagnosticSourceKind,
11228        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11229        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11230        cx: &mut Context<Self>,
11231    ) -> Result<()> {
11232        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11233        let updates = lsp_diagnostics
11234            .into_iter()
11235            .filter_map(|update| {
11236                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11237                Some(DocumentDiagnosticsUpdate {
11238                    diagnostics: self.lsp_to_document_diagnostics(
11239                        abs_path,
11240                        source_kind,
11241                        update.server_id,
11242                        update.diagnostics,
11243                        &update.disk_based_sources,
11244                        update.registration_id.clone(),
11245                    ),
11246                    result_id: update.result_id,
11247                    server_id: update.server_id,
11248                    disk_based_sources: update.disk_based_sources,
11249                    registration_id: update.registration_id,
11250                })
11251            })
11252            .collect();
11253        self.merge_diagnostic_entries(updates, merge, cx)?;
11254        Ok(())
11255    }
11256
11257    fn lsp_to_document_diagnostics(
11258        &mut self,
11259        document_abs_path: PathBuf,
11260        source_kind: DiagnosticSourceKind,
11261        server_id: LanguageServerId,
11262        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11263        disk_based_sources: &[String],
11264        registration_id: Option<SharedString>,
11265    ) -> DocumentDiagnostics {
11266        let mut diagnostics = Vec::default();
11267        let mut primary_diagnostic_group_ids = HashMap::default();
11268        let mut sources_by_group_id = HashMap::default();
11269        let mut supporting_diagnostics = HashMap::default();
11270
11271        let adapter = self.language_server_adapter_for_id(server_id);
11272
11273        // Ensure that primary diagnostics are always the most severe
11274        lsp_diagnostics
11275            .diagnostics
11276            .sort_by_key(|item| item.severity);
11277
11278        for diagnostic in &lsp_diagnostics.diagnostics {
11279            let source = diagnostic.source.as_ref();
11280            let range = range_from_lsp(diagnostic.range);
11281            let is_supporting = diagnostic
11282                .related_information
11283                .as_ref()
11284                .is_some_and(|infos| {
11285                    infos.iter().any(|info| {
11286                        primary_diagnostic_group_ids.contains_key(&(
11287                            source,
11288                            diagnostic.code.clone(),
11289                            range_from_lsp(info.location.range),
11290                        ))
11291                    })
11292                });
11293
11294            let is_unnecessary = diagnostic
11295                .tags
11296                .as_ref()
11297                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11298
11299            let underline = self
11300                .language_server_adapter_for_id(server_id)
11301                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11302
11303            if is_supporting {
11304                supporting_diagnostics.insert(
11305                    (source, diagnostic.code.clone(), range),
11306                    (diagnostic.severity, is_unnecessary),
11307                );
11308            } else {
11309                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11310                let is_disk_based =
11311                    source.is_some_and(|source| disk_based_sources.contains(source));
11312
11313                sources_by_group_id.insert(group_id, source);
11314                primary_diagnostic_group_ids
11315                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11316
11317                diagnostics.push(DiagnosticEntry {
11318                    range,
11319                    diagnostic: Diagnostic {
11320                        source: diagnostic.source.clone(),
11321                        source_kind,
11322                        code: diagnostic.code.clone(),
11323                        code_description: diagnostic
11324                            .code_description
11325                            .as_ref()
11326                            .and_then(|d| d.href.clone()),
11327                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11328                        markdown: adapter.as_ref().and_then(|adapter| {
11329                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11330                        }),
11331                        message: diagnostic.message.trim().to_string(),
11332                        group_id,
11333                        is_primary: true,
11334                        is_disk_based,
11335                        is_unnecessary,
11336                        underline,
11337                        data: diagnostic.data.clone(),
11338                        registration_id: registration_id.clone(),
11339                    },
11340                });
11341                if let Some(infos) = &diagnostic.related_information {
11342                    for info in infos {
11343                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11344                            let range = range_from_lsp(info.location.range);
11345                            diagnostics.push(DiagnosticEntry {
11346                                range,
11347                                diagnostic: Diagnostic {
11348                                    source: diagnostic.source.clone(),
11349                                    source_kind,
11350                                    code: diagnostic.code.clone(),
11351                                    code_description: diagnostic
11352                                        .code_description
11353                                        .as_ref()
11354                                        .and_then(|d| d.href.clone()),
11355                                    severity: DiagnosticSeverity::INFORMATION,
11356                                    markdown: adapter.as_ref().and_then(|adapter| {
11357                                        adapter.diagnostic_message_to_markdown(&info.message)
11358                                    }),
11359                                    message: info.message.trim().to_string(),
11360                                    group_id,
11361                                    is_primary: false,
11362                                    is_disk_based,
11363                                    is_unnecessary: false,
11364                                    underline,
11365                                    data: diagnostic.data.clone(),
11366                                    registration_id: registration_id.clone(),
11367                                },
11368                            });
11369                        }
11370                    }
11371                }
11372            }
11373        }
11374
11375        for entry in &mut diagnostics {
11376            let diagnostic = &mut entry.diagnostic;
11377            if !diagnostic.is_primary {
11378                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11379                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11380                    source,
11381                    diagnostic.code.clone(),
11382                    entry.range.clone(),
11383                )) {
11384                    if let Some(severity) = severity {
11385                        diagnostic.severity = severity;
11386                    }
11387                    diagnostic.is_unnecessary = is_unnecessary;
11388                }
11389            }
11390        }
11391
11392        DocumentDiagnostics {
11393            diagnostics,
11394            document_abs_path,
11395            version: lsp_diagnostics.version,
11396        }
11397    }
11398
11399    fn insert_newly_running_language_server(
11400        &mut self,
11401        adapter: Arc<CachedLspAdapter>,
11402        language_server: Arc<LanguageServer>,
11403        server_id: LanguageServerId,
11404        key: LanguageServerSeed,
11405        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11406        cx: &mut Context<Self>,
11407    ) {
11408        let Some(local) = self.as_local_mut() else {
11409            return;
11410        };
11411        // If the language server for this key doesn't match the server id, don't store the
11412        // server. Which will cause it to be dropped, killing the process
11413        if local
11414            .language_server_ids
11415            .get(&key)
11416            .map(|state| state.id != server_id)
11417            .unwrap_or(false)
11418        {
11419            return;
11420        }
11421
11422        // Update language_servers collection with Running variant of LanguageServerState
11423        // indicating that the server is up and running and ready
11424        let workspace_folders = workspace_folders.lock().clone();
11425        language_server.set_workspace_folders(workspace_folders);
11426
11427        let workspace_diagnostics_refresh_tasks = language_server
11428            .capabilities()
11429            .diagnostic_provider
11430            .and_then(|provider| {
11431                local
11432                    .language_server_dynamic_registrations
11433                    .entry(server_id)
11434                    .or_default()
11435                    .diagnostics
11436                    .entry(None)
11437                    .or_insert(provider.clone());
11438                let workspace_refresher =
11439                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11440
11441                Some((None, workspace_refresher))
11442            })
11443            .into_iter()
11444            .collect();
11445        local.language_servers.insert(
11446            server_id,
11447            LanguageServerState::Running {
11448                workspace_diagnostics_refresh_tasks,
11449                adapter: adapter.clone(),
11450                server: language_server.clone(),
11451                simulate_disk_based_diagnostics_completion: None,
11452            },
11453        );
11454        local
11455            .languages
11456            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11457        if let Some(file_ops_caps) = language_server
11458            .capabilities()
11459            .workspace
11460            .as_ref()
11461            .and_then(|ws| ws.file_operations.as_ref())
11462        {
11463            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11464            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11465            if did_rename_caps.or(will_rename_caps).is_some() {
11466                let watcher = RenamePathsWatchedForServer::default()
11467                    .with_did_rename_patterns(did_rename_caps)
11468                    .with_will_rename_patterns(will_rename_caps);
11469                local
11470                    .language_server_paths_watched_for_rename
11471                    .insert(server_id, watcher);
11472            }
11473        }
11474
11475        self.language_server_statuses.insert(
11476            server_id,
11477            LanguageServerStatus {
11478                name: language_server.name(),
11479                server_version: language_server.version(),
11480                server_readable_version: language_server.readable_version(),
11481                pending_work: Default::default(),
11482                has_pending_diagnostic_updates: false,
11483                progress_tokens: Default::default(),
11484                worktree: Some(key.worktree_id),
11485                binary: Some(language_server.binary().clone()),
11486                configuration: Some(language_server.configuration().clone()),
11487                workspace_folders: language_server.workspace_folders(),
11488                process_id: language_server.process_id(),
11489            },
11490        );
11491
11492        cx.emit(LspStoreEvent::LanguageServerAdded(
11493            server_id,
11494            language_server.name(),
11495            Some(key.worktree_id),
11496        ));
11497
11498        let server_capabilities = language_server.capabilities();
11499        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11500            downstream_client
11501                .send(proto::StartLanguageServer {
11502                    project_id: *project_id,
11503                    server: Some(proto::LanguageServer {
11504                        id: server_id.to_proto(),
11505                        name: language_server.name().to_string(),
11506                        worktree_id: Some(key.worktree_id.to_proto()),
11507                    }),
11508                    capabilities: serde_json::to_string(&server_capabilities)
11509                        .expect("serializing server LSP capabilities"),
11510                })
11511                .log_err();
11512        }
11513        self.lsp_server_capabilities
11514            .insert(server_id, server_capabilities);
11515
11516        // Tell the language server about every open buffer in the worktree that matches the language.
11517        // Also check for buffers in worktrees that reused this server
11518        let mut worktrees_using_server = vec![key.worktree_id];
11519        if let Some(local) = self.as_local() {
11520            // Find all worktrees that have this server in their language server tree
11521            for (worktree_id, servers) in &local.lsp_tree.instances {
11522                if *worktree_id != key.worktree_id {
11523                    for server_map in servers.roots.values() {
11524                        if server_map
11525                            .values()
11526                            .any(|(node, _)| node.id() == Some(server_id))
11527                        {
11528                            worktrees_using_server.push(*worktree_id);
11529                        }
11530                    }
11531                }
11532            }
11533        }
11534
11535        let mut buffer_paths_registered = Vec::new();
11536        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11537            let mut lsp_adapters = HashMap::default();
11538            for buffer_handle in buffer_store.buffers() {
11539                let buffer = buffer_handle.read(cx);
11540                let file = match File::from_dyn(buffer.file()) {
11541                    Some(file) => file,
11542                    None => continue,
11543                };
11544                let language = match buffer.language() {
11545                    Some(language) => language,
11546                    None => continue,
11547                };
11548
11549                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11550                    || !lsp_adapters
11551                        .entry(language.name())
11552                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11553                        .iter()
11554                        .any(|a| a.name == key.name)
11555                {
11556                    continue;
11557                }
11558                // didOpen
11559                let file = match file.as_local() {
11560                    Some(file) => file,
11561                    None => continue,
11562                };
11563
11564                let local = self.as_local_mut().unwrap();
11565
11566                let buffer_id = buffer.remote_id();
11567                if local.registered_buffers.contains_key(&buffer_id) {
11568                    let abs_path = file.abs_path(cx);
11569                    let uri = match lsp::Uri::from_file_path(&abs_path) {
11570                        Ok(uri) => uri,
11571                        Err(()) => {
11572                            log::error!("failed to convert path to URI: {:?}", abs_path);
11573                            continue;
11574                        }
11575                    };
11576
11577                    let versions = local
11578                        .buffer_snapshots
11579                        .entry(buffer_id)
11580                        .or_default()
11581                        .entry(server_id)
11582                        .and_modify(|_| {
11583                            assert!(
11584                            false,
11585                            "There should not be an existing snapshot for a newly inserted buffer"
11586                        )
11587                        })
11588                        .or_insert_with(|| {
11589                            vec![LspBufferSnapshot {
11590                                version: 0,
11591                                snapshot: buffer.text_snapshot(),
11592                            }]
11593                        });
11594
11595                    let snapshot = versions.last().unwrap();
11596                    let version = snapshot.version;
11597                    let initial_snapshot = &snapshot.snapshot;
11598                    language_server.register_buffer(
11599                        uri,
11600                        adapter.language_id(&language.name()),
11601                        version,
11602                        initial_snapshot.text(),
11603                    );
11604                    buffer_paths_registered.push((buffer_id, abs_path));
11605                    local
11606                        .buffers_opened_in_servers
11607                        .entry(buffer_id)
11608                        .or_default()
11609                        .insert(server_id);
11610                }
11611                buffer_handle.update(cx, |buffer, cx| {
11612                    buffer.set_completion_triggers(
11613                        server_id,
11614                        language_server
11615                            .capabilities()
11616                            .completion_provider
11617                            .as_ref()
11618                            .and_then(|provider| {
11619                                provider
11620                                    .trigger_characters
11621                                    .as_ref()
11622                                    .map(|characters| characters.iter().cloned().collect())
11623                            })
11624                            .unwrap_or_default(),
11625                        cx,
11626                    )
11627                });
11628            }
11629        });
11630
11631        for (buffer_id, abs_path) in buffer_paths_registered {
11632            cx.emit(LspStoreEvent::LanguageServerUpdate {
11633                language_server_id: server_id,
11634                name: Some(adapter.name()),
11635                message: proto::update_language_server::Variant::RegisteredForBuffer(
11636                    proto::RegisteredForBuffer {
11637                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11638                        buffer_id: buffer_id.to_proto(),
11639                    },
11640                ),
11641            });
11642        }
11643
11644        cx.notify();
11645    }
11646
11647    pub fn language_servers_running_disk_based_diagnostics(
11648        &self,
11649    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11650        self.language_server_statuses
11651            .iter()
11652            .filter_map(|(id, status)| {
11653                if status.has_pending_diagnostic_updates {
11654                    Some(*id)
11655                } else {
11656                    None
11657                }
11658            })
11659    }
11660
11661    pub(crate) fn cancel_language_server_work_for_buffers(
11662        &mut self,
11663        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11664        cx: &mut Context<Self>,
11665    ) {
11666        if let Some((client, project_id)) = self.upstream_client() {
11667            let request = client.request(proto::CancelLanguageServerWork {
11668                project_id,
11669                work: Some(proto::cancel_language_server_work::Work::Buffers(
11670                    proto::cancel_language_server_work::Buffers {
11671                        buffer_ids: buffers
11672                            .into_iter()
11673                            .map(|b| b.read(cx).remote_id().to_proto())
11674                            .collect(),
11675                    },
11676                )),
11677            });
11678            cx.background_spawn(request).detach_and_log_err(cx);
11679        } else if let Some(local) = self.as_local() {
11680            let servers = buffers
11681                .into_iter()
11682                .flat_map(|buffer| {
11683                    buffer.update(cx, |buffer, cx| {
11684                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11685                    })
11686                })
11687                .collect::<HashSet<_>>();
11688            for server_id in servers {
11689                self.cancel_language_server_work(server_id, None, cx);
11690            }
11691        }
11692    }
11693
11694    pub(crate) fn cancel_language_server_work(
11695        &mut self,
11696        server_id: LanguageServerId,
11697        token_to_cancel: Option<ProgressToken>,
11698        cx: &mut Context<Self>,
11699    ) {
11700        if let Some(local) = self.as_local() {
11701            let status = self.language_server_statuses.get(&server_id);
11702            let server = local.language_servers.get(&server_id);
11703            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11704            {
11705                for (token, progress) in &status.pending_work {
11706                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11707                        && token != token_to_cancel
11708                    {
11709                        continue;
11710                    }
11711                    if progress.is_cancellable {
11712                        server
11713                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11714                                WorkDoneProgressCancelParams {
11715                                    token: token.to_lsp(),
11716                                },
11717                            )
11718                            .ok();
11719                    }
11720                }
11721            }
11722        } else if let Some((client, project_id)) = self.upstream_client() {
11723            let request = client.request(proto::CancelLanguageServerWork {
11724                project_id,
11725                work: Some(
11726                    proto::cancel_language_server_work::Work::LanguageServerWork(
11727                        proto::cancel_language_server_work::LanguageServerWork {
11728                            language_server_id: server_id.to_proto(),
11729                            token: token_to_cancel.map(|token| token.to_proto()),
11730                        },
11731                    ),
11732                ),
11733            });
11734            cx.background_spawn(request).detach_and_log_err(cx);
11735        }
11736    }
11737
11738    fn register_supplementary_language_server(
11739        &mut self,
11740        id: LanguageServerId,
11741        name: LanguageServerName,
11742        server: Arc<LanguageServer>,
11743        cx: &mut Context<Self>,
11744    ) {
11745        if let Some(local) = self.as_local_mut() {
11746            local
11747                .supplementary_language_servers
11748                .insert(id, (name.clone(), server));
11749            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11750        }
11751    }
11752
11753    fn unregister_supplementary_language_server(
11754        &mut self,
11755        id: LanguageServerId,
11756        cx: &mut Context<Self>,
11757    ) {
11758        if let Some(local) = self.as_local_mut() {
11759            local.supplementary_language_servers.remove(&id);
11760            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11761        }
11762    }
11763
11764    pub(crate) fn supplementary_language_servers(
11765        &self,
11766    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11767        self.as_local().into_iter().flat_map(|local| {
11768            local
11769                .supplementary_language_servers
11770                .iter()
11771                .map(|(id, (name, _))| (*id, name.clone()))
11772        })
11773    }
11774
11775    pub fn language_server_adapter_for_id(
11776        &self,
11777        id: LanguageServerId,
11778    ) -> Option<Arc<CachedLspAdapter>> {
11779        self.as_local()
11780            .and_then(|local| local.language_servers.get(&id))
11781            .and_then(|language_server_state| match language_server_state {
11782                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11783                _ => None,
11784            })
11785    }
11786
11787    pub(super) fn update_local_worktree_language_servers(
11788        &mut self,
11789        worktree_handle: &Entity<Worktree>,
11790        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11791        cx: &mut Context<Self>,
11792    ) {
11793        if changes.is_empty() {
11794            return;
11795        }
11796
11797        let Some(local) = self.as_local() else { return };
11798
11799        local.prettier_store.update(cx, |prettier_store, cx| {
11800            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11801        });
11802
11803        let worktree_id = worktree_handle.read(cx).id();
11804        let mut language_server_ids = local
11805            .language_server_ids
11806            .iter()
11807            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11808            .collect::<Vec<_>>();
11809        language_server_ids.sort();
11810        language_server_ids.dedup();
11811
11812        // let abs_path = worktree_handle.read(cx).abs_path();
11813        for server_id in &language_server_ids {
11814            if let Some(LanguageServerState::Running { server, .. }) =
11815                local.language_servers.get(server_id)
11816                && let Some(watched_paths) = local
11817                    .language_server_watched_paths
11818                    .get(server_id)
11819                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11820            {
11821                let params = lsp::DidChangeWatchedFilesParams {
11822                    changes: changes
11823                        .iter()
11824                        .filter_map(|(path, _, change)| {
11825                            if !watched_paths.is_match(path.as_std_path()) {
11826                                return None;
11827                            }
11828                            let typ = match change {
11829                                PathChange::Loaded => return None,
11830                                PathChange::Added => lsp::FileChangeType::CREATED,
11831                                PathChange::Removed => lsp::FileChangeType::DELETED,
11832                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11833                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11834                            };
11835                            let uri = lsp::Uri::from_file_path(
11836                                worktree_handle.read(cx).absolutize(&path),
11837                            )
11838                            .ok()?;
11839                            Some(lsp::FileEvent { uri, typ })
11840                        })
11841                        .collect(),
11842                };
11843                if !params.changes.is_empty() {
11844                    server
11845                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11846                        .ok();
11847                }
11848            }
11849        }
11850        for (path, _, _) in changes {
11851            if let Some(file_name) = path.file_name()
11852                && local.watched_manifest_filenames.contains(file_name)
11853            {
11854                self.request_workspace_config_refresh();
11855                break;
11856            }
11857        }
11858    }
11859
11860    pub fn wait_for_remote_buffer(
11861        &mut self,
11862        id: BufferId,
11863        cx: &mut Context<Self>,
11864    ) -> Task<Result<Entity<Buffer>>> {
11865        self.buffer_store.update(cx, |buffer_store, cx| {
11866            buffer_store.wait_for_remote_buffer(id, cx)
11867        })
11868    }
11869
11870    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11871        let mut result = proto::Symbol {
11872            language_server_name: symbol.language_server_name.0.to_string(),
11873            source_worktree_id: symbol.source_worktree_id.to_proto(),
11874            language_server_id: symbol.source_language_server_id.to_proto(),
11875            name: symbol.name.clone(),
11876            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11877            start: Some(proto::PointUtf16 {
11878                row: symbol.range.start.0.row,
11879                column: symbol.range.start.0.column,
11880            }),
11881            end: Some(proto::PointUtf16 {
11882                row: symbol.range.end.0.row,
11883                column: symbol.range.end.0.column,
11884            }),
11885            worktree_id: Default::default(),
11886            path: Default::default(),
11887            signature: Default::default(),
11888            container_name: symbol.container_name.clone(),
11889        };
11890        match &symbol.path {
11891            SymbolLocation::InProject(path) => {
11892                result.worktree_id = path.worktree_id.to_proto();
11893                result.path = path.path.to_proto();
11894            }
11895            SymbolLocation::OutsideProject {
11896                abs_path,
11897                signature,
11898            } => {
11899                result.path = abs_path.to_string_lossy().into_owned();
11900                result.signature = signature.to_vec();
11901            }
11902        }
11903        result
11904    }
11905
11906    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11907        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11908        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11909        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11910
11911        let path = if serialized_symbol.signature.is_empty() {
11912            SymbolLocation::InProject(ProjectPath {
11913                worktree_id,
11914                path: RelPath::from_proto(&serialized_symbol.path)
11915                    .context("invalid symbol path")?,
11916            })
11917        } else {
11918            SymbolLocation::OutsideProject {
11919                abs_path: Path::new(&serialized_symbol.path).into(),
11920                signature: serialized_symbol
11921                    .signature
11922                    .try_into()
11923                    .map_err(|_| anyhow!("invalid signature"))?,
11924            }
11925        };
11926
11927        let start = serialized_symbol.start.context("invalid start")?;
11928        let end = serialized_symbol.end.context("invalid end")?;
11929        Ok(CoreSymbol {
11930            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11931            source_worktree_id,
11932            source_language_server_id: LanguageServerId::from_proto(
11933                serialized_symbol.language_server_id,
11934            ),
11935            path,
11936            name: serialized_symbol.name,
11937            range: Unclipped(PointUtf16::new(start.row, start.column))
11938                ..Unclipped(PointUtf16::new(end.row, end.column)),
11939            kind,
11940            container_name: serialized_symbol.container_name,
11941        })
11942    }
11943
11944    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11945        let mut serialized_completion = proto::Completion {
11946            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11947            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11948            new_text: completion.new_text.clone(),
11949            ..proto::Completion::default()
11950        };
11951        match &completion.source {
11952            CompletionSource::Lsp {
11953                insert_range,
11954                server_id,
11955                lsp_completion,
11956                lsp_defaults,
11957                resolved,
11958            } => {
11959                let (old_insert_start, old_insert_end) = insert_range
11960                    .as_ref()
11961                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11962                    .unzip();
11963
11964                serialized_completion.old_insert_start = old_insert_start;
11965                serialized_completion.old_insert_end = old_insert_end;
11966                serialized_completion.source = proto::completion::Source::Lsp as i32;
11967                serialized_completion.server_id = server_id.0 as u64;
11968                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11969                serialized_completion.lsp_defaults = lsp_defaults
11970                    .as_deref()
11971                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11972                serialized_completion.resolved = *resolved;
11973            }
11974            CompletionSource::BufferWord {
11975                word_range,
11976                resolved,
11977            } => {
11978                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11979                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11980                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11981                serialized_completion.resolved = *resolved;
11982            }
11983            CompletionSource::Custom => {
11984                serialized_completion.source = proto::completion::Source::Custom as i32;
11985                serialized_completion.resolved = true;
11986            }
11987            CompletionSource::Dap { sort_text } => {
11988                serialized_completion.source = proto::completion::Source::Dap as i32;
11989                serialized_completion.sort_text = Some(sort_text.clone());
11990            }
11991        }
11992
11993        serialized_completion
11994    }
11995
11996    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11997        let old_replace_start = completion
11998            .old_replace_start
11999            .and_then(deserialize_anchor)
12000            .context("invalid old start")?;
12001        let old_replace_end = completion
12002            .old_replace_end
12003            .and_then(deserialize_anchor)
12004            .context("invalid old end")?;
12005        let insert_range = {
12006            match completion.old_insert_start.zip(completion.old_insert_end) {
12007                Some((start, end)) => {
12008                    let start = deserialize_anchor(start).context("invalid insert old start")?;
12009                    let end = deserialize_anchor(end).context("invalid insert old end")?;
12010                    Some(start..end)
12011                }
12012                None => None,
12013            }
12014        };
12015        Ok(CoreCompletion {
12016            replace_range: old_replace_start..old_replace_end,
12017            new_text: completion.new_text,
12018            source: match proto::completion::Source::from_i32(completion.source) {
12019                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
12020                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
12021                    insert_range,
12022                    server_id: LanguageServerId::from_proto(completion.server_id),
12023                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
12024                    lsp_defaults: completion
12025                        .lsp_defaults
12026                        .as_deref()
12027                        .map(serde_json::from_slice)
12028                        .transpose()?,
12029                    resolved: completion.resolved,
12030                },
12031                Some(proto::completion::Source::BufferWord) => {
12032                    let word_range = completion
12033                        .buffer_word_start
12034                        .and_then(deserialize_anchor)
12035                        .context("invalid buffer word start")?
12036                        ..completion
12037                            .buffer_word_end
12038                            .and_then(deserialize_anchor)
12039                            .context("invalid buffer word end")?;
12040                    CompletionSource::BufferWord {
12041                        word_range,
12042                        resolved: completion.resolved,
12043                    }
12044                }
12045                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12046                    sort_text: completion
12047                        .sort_text
12048                        .context("expected sort text to exist")?,
12049                },
12050                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12051            },
12052        })
12053    }
12054
12055    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12056        let (kind, lsp_action) = match &action.lsp_action {
12057            LspAction::Action(code_action) => (
12058                proto::code_action::Kind::Action as i32,
12059                serde_json::to_vec(code_action).unwrap(),
12060            ),
12061            LspAction::Command(command) => (
12062                proto::code_action::Kind::Command as i32,
12063                serde_json::to_vec(command).unwrap(),
12064            ),
12065            LspAction::CodeLens(code_lens) => (
12066                proto::code_action::Kind::CodeLens as i32,
12067                serde_json::to_vec(code_lens).unwrap(),
12068            ),
12069        };
12070
12071        proto::CodeAction {
12072            server_id: action.server_id.0 as u64,
12073            start: Some(serialize_anchor(&action.range.start)),
12074            end: Some(serialize_anchor(&action.range.end)),
12075            lsp_action,
12076            kind,
12077            resolved: action.resolved,
12078        }
12079    }
12080
12081    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12082        let start = action
12083            .start
12084            .and_then(deserialize_anchor)
12085            .context("invalid start")?;
12086        let end = action
12087            .end
12088            .and_then(deserialize_anchor)
12089            .context("invalid end")?;
12090        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12091            Some(proto::code_action::Kind::Action) => {
12092                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12093            }
12094            Some(proto::code_action::Kind::Command) => {
12095                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12096            }
12097            Some(proto::code_action::Kind::CodeLens) => {
12098                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12099            }
12100            None => anyhow::bail!("Unknown action kind {}", action.kind),
12101        };
12102        Ok(CodeAction {
12103            server_id: LanguageServerId(action.server_id as usize),
12104            range: start..end,
12105            resolved: action.resolved,
12106            lsp_action,
12107        })
12108    }
12109
12110    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12111        match &formatting_result {
12112            Ok(_) => self.last_formatting_failure = None,
12113            Err(error) => {
12114                let error_string = format!("{error:#}");
12115                log::error!("Formatting failed: {error_string}");
12116                self.last_formatting_failure
12117                    .replace(error_string.lines().join(" "));
12118            }
12119        }
12120    }
12121
12122    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12123        self.lsp_server_capabilities.remove(&for_server);
12124        self.semantic_token_config.remove_server_data(for_server);
12125        for lsp_data in self.lsp_data.values_mut() {
12126            lsp_data.remove_server_data(for_server);
12127        }
12128        if let Some(local) = self.as_local_mut() {
12129            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12130            local
12131                .workspace_pull_diagnostics_result_ids
12132                .remove(&for_server);
12133            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12134                buffer_servers.remove(&for_server);
12135            }
12136        }
12137    }
12138
12139    pub fn result_id_for_buffer_pull(
12140        &self,
12141        server_id: LanguageServerId,
12142        buffer_id: BufferId,
12143        registration_id: &Option<SharedString>,
12144        cx: &App,
12145    ) -> Option<SharedString> {
12146        let abs_path = self
12147            .buffer_store
12148            .read(cx)
12149            .get(buffer_id)
12150            .and_then(|b| File::from_dyn(b.read(cx).file()))
12151            .map(|f| f.abs_path(cx))?;
12152        self.as_local()?
12153            .buffer_pull_diagnostics_result_ids
12154            .get(&server_id)?
12155            .get(registration_id)?
12156            .get(&abs_path)?
12157            .clone()
12158    }
12159
12160    /// Gets all result_ids for a workspace diagnostics pull request.
12161    /// 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.
12162    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12163    pub fn result_ids_for_workspace_refresh(
12164        &self,
12165        server_id: LanguageServerId,
12166        registration_id: &Option<SharedString>,
12167    ) -> HashMap<PathBuf, SharedString> {
12168        let Some(local) = self.as_local() else {
12169            return HashMap::default();
12170        };
12171        local
12172            .workspace_pull_diagnostics_result_ids
12173            .get(&server_id)
12174            .into_iter()
12175            .filter_map(|diagnostics| diagnostics.get(registration_id))
12176            .flatten()
12177            .filter_map(|(abs_path, result_id)| {
12178                let result_id = local
12179                    .buffer_pull_diagnostics_result_ids
12180                    .get(&server_id)
12181                    .and_then(|buffer_ids_result_ids| {
12182                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12183                    })
12184                    .cloned()
12185                    .flatten()
12186                    .or_else(|| result_id.clone())?;
12187                Some((abs_path.clone(), result_id))
12188            })
12189            .collect()
12190    }
12191
12192    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12193        if let Some(LanguageServerState::Running {
12194            workspace_diagnostics_refresh_tasks,
12195            ..
12196        }) = self
12197            .as_local_mut()
12198            .and_then(|local| local.language_servers.get_mut(&server_id))
12199        {
12200            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12201                diagnostics.refresh_tx.try_send(()).ok();
12202            }
12203        }
12204    }
12205
12206    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12207    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12208    /// which requires refreshing both workspace and document diagnostics.
12209    pub fn pull_document_diagnostics_for_server(
12210        &mut self,
12211        server_id: LanguageServerId,
12212        source_buffer_id: Option<BufferId>,
12213        cx: &mut Context<Self>,
12214    ) -> Shared<Task<()>> {
12215        let Some(local) = self.as_local_mut() else {
12216            return Task::ready(()).shared();
12217        };
12218        let mut buffers_to_refresh = HashSet::default();
12219        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12220            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12221                buffers_to_refresh.insert(*buffer_id);
12222            }
12223        }
12224
12225        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12226    }
12227
12228    pub fn pull_document_diagnostics_for_buffer_edit(
12229        &mut self,
12230        buffer_id: BufferId,
12231        cx: &mut Context<Self>,
12232    ) {
12233        let Some(local) = self.as_local_mut() else {
12234            return;
12235        };
12236        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12237        else {
12238            return;
12239        };
12240        for server_id in languages_servers {
12241            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12242        }
12243    }
12244
12245    fn apply_workspace_diagnostic_report(
12246        &mut self,
12247        server_id: LanguageServerId,
12248        report: lsp::WorkspaceDiagnosticReportResult,
12249        registration_id: Option<SharedString>,
12250        cx: &mut Context<Self>,
12251    ) {
12252        let mut workspace_diagnostics =
12253            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12254                report,
12255                server_id,
12256                registration_id,
12257            );
12258        workspace_diagnostics.retain(|d| match &d.diagnostics {
12259            LspPullDiagnostics::Response {
12260                server_id,
12261                registration_id,
12262                ..
12263            } => self.diagnostic_registration_exists(*server_id, registration_id),
12264            LspPullDiagnostics::Default => false,
12265        });
12266        let mut unchanged_buffers = HashMap::default();
12267        let workspace_diagnostics_updates = workspace_diagnostics
12268            .into_iter()
12269            .filter_map(
12270                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12271                    LspPullDiagnostics::Response {
12272                        server_id,
12273                        uri,
12274                        diagnostics,
12275                        registration_id,
12276                    } => Some((
12277                        server_id,
12278                        uri,
12279                        diagnostics,
12280                        workspace_diagnostics.version,
12281                        registration_id,
12282                    )),
12283                    LspPullDiagnostics::Default => None,
12284                },
12285            )
12286            .fold(
12287                HashMap::default(),
12288                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12289                    let (result_id, diagnostics) = match diagnostics {
12290                        PulledDiagnostics::Unchanged { result_id } => {
12291                            unchanged_buffers
12292                                .entry(new_registration_id.clone())
12293                                .or_insert_with(HashSet::default)
12294                                .insert(uri.clone());
12295                            (Some(result_id), Vec::new())
12296                        }
12297                        PulledDiagnostics::Changed {
12298                            result_id,
12299                            diagnostics,
12300                        } => (result_id, diagnostics),
12301                    };
12302                    let disk_based_sources = Cow::Owned(
12303                        self.language_server_adapter_for_id(server_id)
12304                            .as_ref()
12305                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12306                            .unwrap_or(&[])
12307                            .to_vec(),
12308                    );
12309
12310                    let Some(abs_path) = uri.to_file_path().ok() else {
12311                        return acc;
12312                    };
12313                    let Some((worktree, relative_path)) =
12314                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12315                    else {
12316                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12317                        return acc;
12318                    };
12319                    let worktree_id = worktree.read(cx).id();
12320                    let project_path = ProjectPath {
12321                        worktree_id,
12322                        path: relative_path,
12323                    };
12324                    if let Some(local_lsp_store) = self.as_local_mut() {
12325                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12326                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12327                    }
12328                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12329                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12330                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12331                        acc.entry(server_id)
12332                            .or_insert_with(HashMap::default)
12333                            .entry(new_registration_id.clone())
12334                            .or_insert_with(Vec::new)
12335                            .push(DocumentDiagnosticsUpdate {
12336                                server_id,
12337                                diagnostics: lsp::PublishDiagnosticsParams {
12338                                    uri,
12339                                    diagnostics,
12340                                    version,
12341                                },
12342                                result_id: result_id.map(SharedString::new),
12343                                disk_based_sources,
12344                                registration_id: new_registration_id,
12345                            });
12346                    }
12347                    acc
12348                },
12349            );
12350
12351        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12352            for (registration_id, diagnostic_updates) in diagnostic_updates {
12353                self.merge_lsp_diagnostics(
12354                    DiagnosticSourceKind::Pulled,
12355                    diagnostic_updates,
12356                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12357                        DiagnosticSourceKind::Pulled => {
12358                            old_diagnostic.registration_id != registration_id
12359                                || unchanged_buffers
12360                                    .get(&old_diagnostic.registration_id)
12361                                    .is_some_and(|unchanged_buffers| {
12362                                        unchanged_buffers.contains(&document_uri)
12363                                    })
12364                        }
12365                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12366                    },
12367                    cx,
12368                )
12369                .log_err();
12370            }
12371        }
12372    }
12373
12374    fn register_server_capabilities(
12375        &mut self,
12376        server_id: LanguageServerId,
12377        params: lsp::RegistrationParams,
12378        cx: &mut Context<Self>,
12379    ) -> anyhow::Result<()> {
12380        let server = self
12381            .language_server_for_id(server_id)
12382            .with_context(|| format!("no server {server_id} found"))?;
12383        for reg in params.registrations {
12384            match reg.method.as_str() {
12385                "workspace/didChangeWatchedFiles" => {
12386                    if let Some(options) = reg.register_options {
12387                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12388                            let caps = serde_json::from_value(options)?;
12389                            local_lsp_store
12390                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12391                            true
12392                        } else {
12393                            false
12394                        };
12395                        if notify {
12396                            notify_server_capabilities_updated(&server, cx);
12397                        }
12398                    }
12399                }
12400                "workspace/didChangeConfiguration" => {
12401                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12402                }
12403                "workspace/didChangeWorkspaceFolders" => {
12404                    // In this case register options is an empty object, we can ignore it
12405                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12406                        supported: Some(true),
12407                        change_notifications: Some(OneOf::Right(reg.id)),
12408                    };
12409                    server.update_capabilities(|capabilities| {
12410                        capabilities
12411                            .workspace
12412                            .get_or_insert_default()
12413                            .workspace_folders = Some(caps);
12414                    });
12415                    notify_server_capabilities_updated(&server, cx);
12416                }
12417                "workspace/symbol" => {
12418                    let options = parse_register_capabilities(reg)?;
12419                    server.update_capabilities(|capabilities| {
12420                        capabilities.workspace_symbol_provider = Some(options);
12421                    });
12422                    notify_server_capabilities_updated(&server, cx);
12423                }
12424                "workspace/fileOperations" => {
12425                    if let Some(options) = reg.register_options {
12426                        let caps = serde_json::from_value(options)?;
12427                        server.update_capabilities(|capabilities| {
12428                            capabilities
12429                                .workspace
12430                                .get_or_insert_default()
12431                                .file_operations = Some(caps);
12432                        });
12433                        notify_server_capabilities_updated(&server, cx);
12434                    }
12435                }
12436                "workspace/executeCommand" => {
12437                    if let Some(options) = reg.register_options {
12438                        let options = serde_json::from_value(options)?;
12439                        server.update_capabilities(|capabilities| {
12440                            capabilities.execute_command_provider = Some(options);
12441                        });
12442                        notify_server_capabilities_updated(&server, cx);
12443                    }
12444                }
12445                "textDocument/rangeFormatting" => {
12446                    let options = parse_register_capabilities(reg)?;
12447                    server.update_capabilities(|capabilities| {
12448                        capabilities.document_range_formatting_provider = Some(options);
12449                    });
12450                    notify_server_capabilities_updated(&server, cx);
12451                }
12452                "textDocument/onTypeFormatting" => {
12453                    if let Some(options) = reg
12454                        .register_options
12455                        .map(serde_json::from_value)
12456                        .transpose()?
12457                    {
12458                        server.update_capabilities(|capabilities| {
12459                            capabilities.document_on_type_formatting_provider = Some(options);
12460                        });
12461                        notify_server_capabilities_updated(&server, cx);
12462                    }
12463                }
12464                "textDocument/formatting" => {
12465                    let options = parse_register_capabilities(reg)?;
12466                    server.update_capabilities(|capabilities| {
12467                        capabilities.document_formatting_provider = Some(options);
12468                    });
12469                    notify_server_capabilities_updated(&server, cx);
12470                }
12471                "textDocument/rename" => {
12472                    let options = parse_register_capabilities(reg)?;
12473                    server.update_capabilities(|capabilities| {
12474                        capabilities.rename_provider = Some(options);
12475                    });
12476                    notify_server_capabilities_updated(&server, cx);
12477                }
12478                "textDocument/inlayHint" => {
12479                    let options = parse_register_capabilities(reg)?;
12480                    server.update_capabilities(|capabilities| {
12481                        capabilities.inlay_hint_provider = Some(options);
12482                    });
12483                    notify_server_capabilities_updated(&server, cx);
12484                }
12485                "textDocument/documentSymbol" => {
12486                    let options = parse_register_capabilities(reg)?;
12487                    server.update_capabilities(|capabilities| {
12488                        capabilities.document_symbol_provider = Some(options);
12489                    });
12490                    notify_server_capabilities_updated(&server, cx);
12491                }
12492                "textDocument/codeAction" => {
12493                    let options = parse_register_capabilities(reg)?;
12494                    let provider = match options {
12495                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12496                        OneOf::Right(caps) => caps,
12497                    };
12498                    server.update_capabilities(|capabilities| {
12499                        capabilities.code_action_provider = Some(provider);
12500                    });
12501                    notify_server_capabilities_updated(&server, cx);
12502                }
12503                "textDocument/definition" => {
12504                    let options = parse_register_capabilities(reg)?;
12505                    server.update_capabilities(|capabilities| {
12506                        capabilities.definition_provider = Some(options);
12507                    });
12508                    notify_server_capabilities_updated(&server, cx);
12509                }
12510                "textDocument/completion" => {
12511                    if let Some(caps) = reg
12512                        .register_options
12513                        .map(serde_json::from_value::<CompletionOptions>)
12514                        .transpose()?
12515                    {
12516                        server.update_capabilities(|capabilities| {
12517                            capabilities.completion_provider = Some(caps.clone());
12518                        });
12519
12520                        if let Some(local) = self.as_local() {
12521                            let mut buffers_with_language_server = Vec::new();
12522                            for handle in self.buffer_store.read(cx).buffers() {
12523                                let buffer_id = handle.read(cx).remote_id();
12524                                if local
12525                                    .buffers_opened_in_servers
12526                                    .get(&buffer_id)
12527                                    .filter(|s| s.contains(&server_id))
12528                                    .is_some()
12529                                {
12530                                    buffers_with_language_server.push(handle);
12531                                }
12532                            }
12533                            let triggers = caps
12534                                .trigger_characters
12535                                .unwrap_or_default()
12536                                .into_iter()
12537                                .collect::<BTreeSet<_>>();
12538                            for handle in buffers_with_language_server {
12539                                let triggers = triggers.clone();
12540                                let _ = handle.update(cx, move |buffer, cx| {
12541                                    buffer.set_completion_triggers(server_id, triggers, cx);
12542                                });
12543                            }
12544                        }
12545                        notify_server_capabilities_updated(&server, cx);
12546                    }
12547                }
12548                "textDocument/hover" => {
12549                    let options = parse_register_capabilities(reg)?;
12550                    let provider = match options {
12551                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12552                        OneOf::Right(caps) => caps,
12553                    };
12554                    server.update_capabilities(|capabilities| {
12555                        capabilities.hover_provider = Some(provider);
12556                    });
12557                    notify_server_capabilities_updated(&server, cx);
12558                }
12559                "textDocument/signatureHelp" => {
12560                    if let Some(caps) = reg
12561                        .register_options
12562                        .map(serde_json::from_value)
12563                        .transpose()?
12564                    {
12565                        server.update_capabilities(|capabilities| {
12566                            capabilities.signature_help_provider = Some(caps);
12567                        });
12568                        notify_server_capabilities_updated(&server, cx);
12569                    }
12570                }
12571                "textDocument/didChange" => {
12572                    if let Some(sync_kind) = reg
12573                        .register_options
12574                        .and_then(|opts| opts.get("syncKind").cloned())
12575                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12576                        .transpose()?
12577                    {
12578                        server.update_capabilities(|capabilities| {
12579                            let mut sync_options =
12580                                Self::take_text_document_sync_options(capabilities);
12581                            sync_options.change = Some(sync_kind);
12582                            capabilities.text_document_sync =
12583                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12584                        });
12585                        notify_server_capabilities_updated(&server, cx);
12586                    }
12587                }
12588                "textDocument/didSave" => {
12589                    if let Some(include_text) = reg
12590                        .register_options
12591                        .map(|opts| {
12592                            let transpose = opts
12593                                .get("includeText")
12594                                .cloned()
12595                                .map(serde_json::from_value::<Option<bool>>)
12596                                .transpose();
12597                            match transpose {
12598                                Ok(value) => Ok(value.flatten()),
12599                                Err(e) => Err(e),
12600                            }
12601                        })
12602                        .transpose()?
12603                    {
12604                        server.update_capabilities(|capabilities| {
12605                            let mut sync_options =
12606                                Self::take_text_document_sync_options(capabilities);
12607                            sync_options.save =
12608                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12609                                    include_text,
12610                                }));
12611                            capabilities.text_document_sync =
12612                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12613                        });
12614                        notify_server_capabilities_updated(&server, cx);
12615                    }
12616                }
12617                "textDocument/codeLens" => {
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.code_lens_provider = Some(caps);
12625                        });
12626                        notify_server_capabilities_updated(&server, cx);
12627                    }
12628                }
12629                "textDocument/diagnostic" => {
12630                    if let Some(caps) = reg
12631                        .register_options
12632                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12633                        .transpose()?
12634                    {
12635                        let local = self
12636                            .as_local_mut()
12637                            .context("Expected LSP Store to be local")?;
12638                        let state = local
12639                            .language_servers
12640                            .get_mut(&server_id)
12641                            .context("Could not obtain Language Servers state")?;
12642                        local
12643                            .language_server_dynamic_registrations
12644                            .entry(server_id)
12645                            .or_default()
12646                            .diagnostics
12647                            .insert(Some(reg.id.clone()), caps.clone());
12648
12649                        let supports_workspace_diagnostics =
12650                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12651                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12652                                    diagnostic_options.workspace_diagnostics
12653                                }
12654                                DiagnosticServerCapabilities::RegistrationOptions(
12655                                    diagnostic_registration_options,
12656                                ) => {
12657                                    diagnostic_registration_options
12658                                        .diagnostic_options
12659                                        .workspace_diagnostics
12660                                }
12661                            };
12662
12663                        if supports_workspace_diagnostics(&caps) {
12664                            if let LanguageServerState::Running {
12665                                workspace_diagnostics_refresh_tasks,
12666                                ..
12667                            } = state
12668                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12669                                    Some(reg.id.clone()),
12670                                    caps.clone(),
12671                                    server.clone(),
12672                                    cx,
12673                                )
12674                            {
12675                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12676                            }
12677                        }
12678
12679                        server.update_capabilities(|capabilities| {
12680                            capabilities.diagnostic_provider = Some(caps);
12681                        });
12682
12683                        notify_server_capabilities_updated(&server, cx);
12684
12685                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12686                    }
12687                }
12688                "textDocument/documentColor" => {
12689                    let options = parse_register_capabilities(reg)?;
12690                    let provider = match options {
12691                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12692                        OneOf::Right(caps) => caps,
12693                    };
12694                    server.update_capabilities(|capabilities| {
12695                        capabilities.color_provider = Some(provider);
12696                    });
12697                    notify_server_capabilities_updated(&server, cx);
12698                }
12699                "textDocument/foldingRange" => {
12700                    let options = parse_register_capabilities(reg)?;
12701                    let provider = match options {
12702                        OneOf::Left(value) => lsp::FoldingRangeProviderCapability::Simple(value),
12703                        OneOf::Right(caps) => caps,
12704                    };
12705                    server.update_capabilities(|capabilities| {
12706                        capabilities.folding_range_provider = Some(provider);
12707                    });
12708                    notify_server_capabilities_updated(&server, cx);
12709                }
12710                _ => log::warn!("unhandled capability registration: {reg:?}"),
12711            }
12712        }
12713
12714        Ok(())
12715    }
12716
12717    fn unregister_server_capabilities(
12718        &mut self,
12719        server_id: LanguageServerId,
12720        params: lsp::UnregistrationParams,
12721        cx: &mut Context<Self>,
12722    ) -> anyhow::Result<()> {
12723        let server = self
12724            .language_server_for_id(server_id)
12725            .with_context(|| format!("no server {server_id} found"))?;
12726        for unreg in params.unregisterations.iter() {
12727            match unreg.method.as_str() {
12728                "workspace/didChangeWatchedFiles" => {
12729                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12730                        local_lsp_store
12731                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12732                        true
12733                    } else {
12734                        false
12735                    };
12736                    if notify {
12737                        notify_server_capabilities_updated(&server, cx);
12738                    }
12739                }
12740                "workspace/didChangeConfiguration" => {
12741                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12742                }
12743                "workspace/didChangeWorkspaceFolders" => {
12744                    server.update_capabilities(|capabilities| {
12745                        capabilities
12746                            .workspace
12747                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12748                                workspace_folders: None,
12749                                file_operations: None,
12750                            })
12751                            .workspace_folders = None;
12752                    });
12753                    notify_server_capabilities_updated(&server, cx);
12754                }
12755                "workspace/symbol" => {
12756                    server.update_capabilities(|capabilities| {
12757                        capabilities.workspace_symbol_provider = None
12758                    });
12759                    notify_server_capabilities_updated(&server, cx);
12760                }
12761                "workspace/fileOperations" => {
12762                    server.update_capabilities(|capabilities| {
12763                        capabilities
12764                            .workspace
12765                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12766                                workspace_folders: None,
12767                                file_operations: None,
12768                            })
12769                            .file_operations = None;
12770                    });
12771                    notify_server_capabilities_updated(&server, cx);
12772                }
12773                "workspace/executeCommand" => {
12774                    server.update_capabilities(|capabilities| {
12775                        capabilities.execute_command_provider = None;
12776                    });
12777                    notify_server_capabilities_updated(&server, cx);
12778                }
12779                "textDocument/rangeFormatting" => {
12780                    server.update_capabilities(|capabilities| {
12781                        capabilities.document_range_formatting_provider = None
12782                    });
12783                    notify_server_capabilities_updated(&server, cx);
12784                }
12785                "textDocument/onTypeFormatting" => {
12786                    server.update_capabilities(|capabilities| {
12787                        capabilities.document_on_type_formatting_provider = None;
12788                    });
12789                    notify_server_capabilities_updated(&server, cx);
12790                }
12791                "textDocument/formatting" => {
12792                    server.update_capabilities(|capabilities| {
12793                        capabilities.document_formatting_provider = None;
12794                    });
12795                    notify_server_capabilities_updated(&server, cx);
12796                }
12797                "textDocument/rename" => {
12798                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12799                    notify_server_capabilities_updated(&server, cx);
12800                }
12801                "textDocument/codeAction" => {
12802                    server.update_capabilities(|capabilities| {
12803                        capabilities.code_action_provider = None;
12804                    });
12805                    notify_server_capabilities_updated(&server, cx);
12806                }
12807                "textDocument/definition" => {
12808                    server.update_capabilities(|capabilities| {
12809                        capabilities.definition_provider = None;
12810                    });
12811                    notify_server_capabilities_updated(&server, cx);
12812                }
12813                "textDocument/completion" => {
12814                    server.update_capabilities(|capabilities| {
12815                        capabilities.completion_provider = None;
12816                    });
12817                    notify_server_capabilities_updated(&server, cx);
12818                }
12819                "textDocument/hover" => {
12820                    server.update_capabilities(|capabilities| {
12821                        capabilities.hover_provider = None;
12822                    });
12823                    notify_server_capabilities_updated(&server, cx);
12824                }
12825                "textDocument/signatureHelp" => {
12826                    server.update_capabilities(|capabilities| {
12827                        capabilities.signature_help_provider = None;
12828                    });
12829                    notify_server_capabilities_updated(&server, cx);
12830                }
12831                "textDocument/didChange" => {
12832                    server.update_capabilities(|capabilities| {
12833                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12834                        sync_options.change = None;
12835                        capabilities.text_document_sync =
12836                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12837                    });
12838                    notify_server_capabilities_updated(&server, cx);
12839                }
12840                "textDocument/didSave" => {
12841                    server.update_capabilities(|capabilities| {
12842                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12843                        sync_options.save = None;
12844                        capabilities.text_document_sync =
12845                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12846                    });
12847                    notify_server_capabilities_updated(&server, cx);
12848                }
12849                "textDocument/codeLens" => {
12850                    server.update_capabilities(|capabilities| {
12851                        capabilities.code_lens_provider = None;
12852                    });
12853                    notify_server_capabilities_updated(&server, cx);
12854                }
12855                "textDocument/diagnostic" => {
12856                    let local = self
12857                        .as_local_mut()
12858                        .context("Expected LSP Store to be local")?;
12859
12860                    let state = local
12861                        .language_servers
12862                        .get_mut(&server_id)
12863                        .context("Could not obtain Language Servers state")?;
12864                    let registrations = local
12865                        .language_server_dynamic_registrations
12866                        .get_mut(&server_id)
12867                        .with_context(|| {
12868                            format!("Expected dynamic registration to exist for server {server_id}")
12869                        })?;
12870                    registrations.diagnostics
12871                        .remove(&Some(unreg.id.clone()))
12872                        .with_context(|| format!(
12873                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12874                            unreg.id)
12875                        )?;
12876                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12877
12878                    if let LanguageServerState::Running {
12879                        workspace_diagnostics_refresh_tasks,
12880                        ..
12881                    } = state
12882                    {
12883                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12884                    }
12885
12886                    self.clear_unregistered_diagnostics(
12887                        server_id,
12888                        SharedString::from(unreg.id.clone()),
12889                        cx,
12890                    )?;
12891
12892                    if removed_last_diagnostic_provider {
12893                        server.update_capabilities(|capabilities| {
12894                            debug_assert!(capabilities.diagnostic_provider.is_some());
12895                            capabilities.diagnostic_provider = None;
12896                        });
12897                    }
12898
12899                    notify_server_capabilities_updated(&server, cx);
12900                }
12901                "textDocument/documentColor" => {
12902                    server.update_capabilities(|capabilities| {
12903                        capabilities.color_provider = None;
12904                    });
12905                    notify_server_capabilities_updated(&server, cx);
12906                }
12907                "textDocument/foldingRange" => {
12908                    server.update_capabilities(|capabilities| {
12909                        capabilities.folding_range_provider = None;
12910                    });
12911                    notify_server_capabilities_updated(&server, cx);
12912                }
12913                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12914            }
12915        }
12916
12917        Ok(())
12918    }
12919
12920    fn clear_unregistered_diagnostics(
12921        &mut self,
12922        server_id: LanguageServerId,
12923        cleared_registration_id: SharedString,
12924        cx: &mut Context<Self>,
12925    ) -> anyhow::Result<()> {
12926        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12927
12928        self.buffer_store.update(cx, |buffer_store, cx| {
12929            for buffer_handle in buffer_store.buffers() {
12930                let buffer = buffer_handle.read(cx);
12931                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12932                let Some(abs_path) = abs_path else {
12933                    continue;
12934                };
12935                affected_abs_paths.insert(abs_path);
12936            }
12937        });
12938
12939        let local = self.as_local().context("Expected LSP Store to be local")?;
12940        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12941            let Some(worktree) = self
12942                .worktree_store
12943                .read(cx)
12944                .worktree_for_id(*worktree_id, cx)
12945            else {
12946                continue;
12947            };
12948
12949            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
12950                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
12951                    let has_matching_registration =
12952                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
12953                            entry.diagnostic.registration_id.as_ref()
12954                                == Some(&cleared_registration_id)
12955                        });
12956                    if has_matching_registration {
12957                        let abs_path = worktree.read(cx).absolutize(rel_path);
12958                        affected_abs_paths.insert(abs_path);
12959                    }
12960                }
12961            }
12962        }
12963
12964        if affected_abs_paths.is_empty() {
12965            return Ok(());
12966        }
12967
12968        // Send a fake diagnostic update which clears the state for the registration ID
12969        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
12970            affected_abs_paths
12971                .into_iter()
12972                .map(|abs_path| DocumentDiagnosticsUpdate {
12973                    diagnostics: DocumentDiagnostics {
12974                        diagnostics: Vec::new(),
12975                        document_abs_path: abs_path,
12976                        version: None,
12977                    },
12978                    result_id: None,
12979                    registration_id: Some(cleared_registration_id.clone()),
12980                    server_id,
12981                    disk_based_sources: Cow::Borrowed(&[]),
12982                })
12983                .collect();
12984
12985        let merge_registration_id = cleared_registration_id.clone();
12986        self.merge_diagnostic_entries(
12987            clears,
12988            move |_, diagnostic, _| {
12989                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
12990                    diagnostic.registration_id != Some(merge_registration_id.clone())
12991                } else {
12992                    true
12993                }
12994            },
12995            cx,
12996        )?;
12997
12998        Ok(())
12999    }
13000
13001    async fn deduplicate_range_based_lsp_requests<T>(
13002        lsp_store: &Entity<Self>,
13003        server_id: Option<LanguageServerId>,
13004        lsp_request_id: LspRequestId,
13005        proto_request: &T::ProtoRequest,
13006        range: Range<Anchor>,
13007        cx: &mut AsyncApp,
13008    ) -> Result<()>
13009    where
13010        T: LspCommand,
13011        T::ProtoRequest: proto::LspRequestMessage,
13012    {
13013        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13014        let version = deserialize_version(proto_request.buffer_version());
13015        let buffer = lsp_store.update(cx, |this, cx| {
13016            this.buffer_store.read(cx).get_existing(buffer_id)
13017        })?;
13018        buffer
13019            .update(cx, |buffer, _| buffer.wait_for_version(version))
13020            .await?;
13021        lsp_store.update(cx, |lsp_store, cx| {
13022            let buffer_snapshot = buffer.read(cx).snapshot();
13023            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13024            let chunks_queried_for = lsp_data
13025                .inlay_hints
13026                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
13027                .collect::<Vec<_>>();
13028            match chunks_queried_for.as_slice() {
13029                &[chunk] => {
13030                    let key = LspKey {
13031                        request_type: TypeId::of::<T>(),
13032                        server_queried: server_id,
13033                    };
13034                    let previous_request = lsp_data
13035                        .chunk_lsp_requests
13036                        .entry(key)
13037                        .or_default()
13038                        .insert(chunk, lsp_request_id);
13039                    if let Some((previous_request, running_requests)) =
13040                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13041                    {
13042                        running_requests.remove(&previous_request);
13043                    }
13044                }
13045                _ambiguous_chunks => {
13046                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13047                    // there, a buffer version-based check will be performed and outdated requests discarded.
13048                }
13049            }
13050            anyhow::Ok(())
13051        })?;
13052
13053        Ok(())
13054    }
13055
13056    async fn query_lsp_locally<T>(
13057        lsp_store: Entity<Self>,
13058        for_server_id: Option<LanguageServerId>,
13059        sender_id: proto::PeerId,
13060        lsp_request_id: LspRequestId,
13061        proto_request: T::ProtoRequest,
13062        position: Option<Anchor>,
13063        cx: &mut AsyncApp,
13064    ) -> Result<()>
13065    where
13066        T: LspCommand + Clone,
13067        T::ProtoRequest: proto::LspRequestMessage,
13068        <T::ProtoRequest as proto::RequestMessage>::Response:
13069            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13070    {
13071        let (buffer_version, buffer) =
13072            Self::wait_for_buffer_version::<T>(&lsp_store, &proto_request, cx).await?;
13073        let request =
13074            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13075        let key = LspKey {
13076            request_type: TypeId::of::<T>(),
13077            server_queried: for_server_id,
13078        };
13079        lsp_store.update(cx, |lsp_store, cx| {
13080            let request_task = match for_server_id {
13081                Some(server_id) => {
13082                    let server_task = lsp_store.request_lsp(
13083                        buffer.clone(),
13084                        LanguageServerToQuery::Other(server_id),
13085                        request.clone(),
13086                        cx,
13087                    );
13088                    cx.background_spawn(async move {
13089                        let mut responses = Vec::new();
13090                        match server_task.await {
13091                            Ok(response) => responses.push((server_id, response)),
13092                            // rust-analyzer likes to error with this when its still loading up
13093                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13094                            Err(e) => log::error!(
13095                                "Error handling response for request {request:?}: {e:#}"
13096                            ),
13097                        }
13098                        responses
13099                    })
13100                }
13101                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13102            };
13103            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13104            if T::ProtoRequest::stop_previous_requests() {
13105                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13106                    lsp_requests.clear();
13107                }
13108            }
13109            lsp_data.lsp_requests.entry(key).or_default().insert(
13110                lsp_request_id,
13111                cx.spawn(async move |lsp_store, cx| {
13112                    let response = request_task.await;
13113                    lsp_store
13114                        .update(cx, |lsp_store, cx| {
13115                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13116                            {
13117                                let response = response
13118                                    .into_iter()
13119                                    .map(|(server_id, response)| {
13120                                        (
13121                                            server_id.to_proto(),
13122                                            T::response_to_proto(
13123                                                response,
13124                                                lsp_store,
13125                                                sender_id,
13126                                                &buffer_version,
13127                                                cx,
13128                                            )
13129                                            .into(),
13130                                        )
13131                                    })
13132                                    .collect::<HashMap<_, _>>();
13133                                match client.send_lsp_response::<T::ProtoRequest>(
13134                                    project_id,
13135                                    lsp_request_id,
13136                                    response,
13137                                ) {
13138                                    Ok(()) => {}
13139                                    Err(e) => {
13140                                        log::error!("Failed to send LSP response: {e:#}",)
13141                                    }
13142                                }
13143                            }
13144                        })
13145                        .ok();
13146                }),
13147            );
13148        });
13149        Ok(())
13150    }
13151
13152    async fn wait_for_buffer_version<T>(
13153        lsp_store: &Entity<Self>,
13154        proto_request: &T::ProtoRequest,
13155        cx: &mut AsyncApp,
13156    ) -> Result<(Global, Entity<Buffer>)>
13157    where
13158        T: LspCommand,
13159        T::ProtoRequest: proto::LspRequestMessage,
13160    {
13161        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13162        let version = deserialize_version(proto_request.buffer_version());
13163        let buffer = lsp_store.update(cx, |this, cx| {
13164            this.buffer_store.read(cx).get_existing(buffer_id)
13165        })?;
13166        buffer
13167            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13168            .await?;
13169        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13170        Ok((buffer_version, buffer))
13171    }
13172
13173    fn take_text_document_sync_options(
13174        capabilities: &mut lsp::ServerCapabilities,
13175    ) -> lsp::TextDocumentSyncOptions {
13176        match capabilities.text_document_sync.take() {
13177            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13178            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13179                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13180                sync_options.change = Some(sync_kind);
13181                sync_options
13182            }
13183            None => lsp::TextDocumentSyncOptions::default(),
13184        }
13185    }
13186
13187    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13188        self.downstream_client.clone()
13189    }
13190
13191    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13192        self.worktree_store.clone()
13193    }
13194
13195    /// Gets what's stored in the LSP data for the given buffer.
13196    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13197        self.lsp_data.get_mut(&buffer_id)
13198    }
13199
13200    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13201    /// new [`BufferLspData`] will be created to replace the previous state.
13202    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13203        let (buffer_id, buffer_version) =
13204            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13205        let lsp_data = self
13206            .lsp_data
13207            .entry(buffer_id)
13208            .or_insert_with(|| BufferLspData::new(buffer, cx));
13209        if buffer_version.changed_since(&lsp_data.buffer_version) {
13210            // To send delta requests for semantic tokens, the previous tokens
13211            // need to be kept between buffer changes.
13212            let semantic_tokens = lsp_data.semantic_tokens.take();
13213            *lsp_data = BufferLspData::new(buffer, cx);
13214            lsp_data.semantic_tokens = semantic_tokens;
13215        }
13216        lsp_data
13217    }
13218}
13219
13220// Registration with registerOptions as null, should fallback to true.
13221// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13222fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13223    reg: lsp::Registration,
13224) -> Result<OneOf<bool, T>> {
13225    Ok(match reg.register_options {
13226        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13227        None => OneOf::Left(true),
13228    })
13229}
13230
13231fn subscribe_to_binary_statuses(
13232    languages: &Arc<LanguageRegistry>,
13233    cx: &mut Context<'_, LspStore>,
13234) -> Task<()> {
13235    let mut server_statuses = languages.language_server_binary_statuses();
13236    cx.spawn(async move |lsp_store, cx| {
13237        while let Some((server_name, binary_status)) = server_statuses.next().await {
13238            if lsp_store
13239                .update(cx, |_, cx| {
13240                    let mut message = None;
13241                    let binary_status = match binary_status {
13242                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13243                        BinaryStatus::CheckingForUpdate => {
13244                            proto::ServerBinaryStatus::CheckingForUpdate
13245                        }
13246                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13247                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13248                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13249                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13250                        BinaryStatus::Failed { error } => {
13251                            message = Some(error);
13252                            proto::ServerBinaryStatus::Failed
13253                        }
13254                    };
13255                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13256                        // Binary updates are about the binary that might not have any language server id at that point.
13257                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13258                        language_server_id: LanguageServerId(0),
13259                        name: Some(server_name),
13260                        message: proto::update_language_server::Variant::StatusUpdate(
13261                            proto::StatusUpdate {
13262                                message,
13263                                status: Some(proto::status_update::Status::Binary(
13264                                    binary_status as i32,
13265                                )),
13266                            },
13267                        ),
13268                    });
13269                })
13270                .is_err()
13271            {
13272                break;
13273            }
13274        }
13275    })
13276}
13277
13278fn lsp_workspace_diagnostics_refresh(
13279    registration_id: Option<String>,
13280    options: DiagnosticServerCapabilities,
13281    server: Arc<LanguageServer>,
13282    cx: &mut Context<'_, LspStore>,
13283) -> Option<WorkspaceRefreshTask> {
13284    let identifier = workspace_diagnostic_identifier(&options)?;
13285    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13286
13287    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13288    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13289    refresh_tx.try_send(()).ok();
13290
13291    let request_timeout = ProjectSettings::get_global(cx)
13292        .global_lsp_settings
13293        .get_request_timeout();
13294
13295    // 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.
13296    // This allows users to increase the duration if need be
13297    let timeout = if request_timeout != Duration::ZERO {
13298        request_timeout.max(DEFAULT_LSP_REQUEST_TIMEOUT)
13299    } else {
13300        request_timeout
13301    };
13302
13303    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13304        let mut attempts = 0;
13305        let max_attempts = 50;
13306        let mut requests = 0;
13307
13308        loop {
13309            let Some(()) = refresh_rx.recv().await else {
13310                return;
13311            };
13312
13313            'request: loop {
13314                requests += 1;
13315                if attempts > max_attempts {
13316                    log::error!(
13317                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13318                    );
13319                    return;
13320                }
13321                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13322                cx.background_executor()
13323                    .timer(Duration::from_millis(backoff_millis))
13324                    .await;
13325                attempts += 1;
13326
13327                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13328                    lsp_store
13329                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13330                        .into_iter()
13331                        .filter_map(|(abs_path, result_id)| {
13332                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13333                            Some(lsp::PreviousResultId {
13334                                uri,
13335                                value: result_id.to_string(),
13336                            })
13337                        })
13338                        .collect()
13339                }) else {
13340                    return;
13341                };
13342
13343                let token = if let Some(registration_id) = &registration_id {
13344                    format!(
13345                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13346                        server.server_id(),
13347                    )
13348                } else {
13349                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13350                };
13351
13352                progress_rx.try_recv().ok();
13353                let timer = server.request_timer(timeout).fuse();
13354                let progress = pin!(progress_rx.recv().fuse());
13355                let response_result = server
13356                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13357                        lsp::WorkspaceDiagnosticParams {
13358                            previous_result_ids,
13359                            identifier: identifier.clone(),
13360                            work_done_progress_params: Default::default(),
13361                            partial_result_params: lsp::PartialResultParams {
13362                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13363                            },
13364                        },
13365                        select(timer, progress).then(|either| match either {
13366                            Either::Left((message, ..)) => ready(message).left_future(),
13367                            Either::Right(..) => pending::<String>().right_future(),
13368                        }),
13369                    )
13370                    .await;
13371
13372                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13373                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13374                match response_result {
13375                    ConnectionResult::Timeout => {
13376                        log::error!("Timeout during workspace diagnostics pull");
13377                        continue 'request;
13378                    }
13379                    ConnectionResult::ConnectionReset => {
13380                        log::error!("Server closed a workspace diagnostics pull request");
13381                        continue 'request;
13382                    }
13383                    ConnectionResult::Result(Err(e)) => {
13384                        log::error!("Error during workspace diagnostics pull: {e:#}");
13385                        break 'request;
13386                    }
13387                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13388                        attempts = 0;
13389                        if lsp_store
13390                            .update(cx, |lsp_store, cx| {
13391                                lsp_store.apply_workspace_diagnostic_report(
13392                                    server.server_id(),
13393                                    pulled_diagnostics,
13394                                    registration_id_shared.clone(),
13395                                    cx,
13396                                )
13397                            })
13398                            .is_err()
13399                        {
13400                            return;
13401                        }
13402                        break 'request;
13403                    }
13404                }
13405            }
13406        }
13407    });
13408
13409    Some(WorkspaceRefreshTask {
13410        refresh_tx,
13411        progress_tx,
13412        task: workspace_query_language_server,
13413    })
13414}
13415
13416fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<SharedString> {
13417    match &options {
13418        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => diagnostic_options
13419            .identifier
13420            .as_deref()
13421            .map(SharedString::new),
13422        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13423            let diagnostic_options = &registration_options.diagnostic_options;
13424            diagnostic_options
13425                .identifier
13426                .as_deref()
13427                .map(SharedString::new)
13428        }
13429    }
13430}
13431
13432fn workspace_diagnostic_identifier(
13433    options: &DiagnosticServerCapabilities,
13434) -> Option<Option<String>> {
13435    match &options {
13436        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13437            if !diagnostic_options.workspace_diagnostics {
13438                return None;
13439            }
13440            Some(diagnostic_options.identifier.clone())
13441        }
13442        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13443            let diagnostic_options = &registration_options.diagnostic_options;
13444            if !diagnostic_options.workspace_diagnostics {
13445                return None;
13446            }
13447            Some(diagnostic_options.identifier.clone())
13448        }
13449    }
13450}
13451
13452fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13453    let CompletionSource::BufferWord {
13454        word_range,
13455        resolved,
13456    } = &mut completion.source
13457    else {
13458        return;
13459    };
13460    if *resolved {
13461        return;
13462    }
13463
13464    if completion.new_text
13465        != snapshot
13466            .text_for_range(word_range.clone())
13467            .collect::<String>()
13468    {
13469        return;
13470    }
13471
13472    let mut offset = 0;
13473    for chunk in snapshot.chunks(word_range.clone(), true) {
13474        let end_offset = offset + chunk.text.len();
13475        if let Some(highlight_id) = chunk.syntax_highlight_id {
13476            completion
13477                .label
13478                .runs
13479                .push((offset..end_offset, highlight_id));
13480        }
13481        offset = end_offset;
13482    }
13483    *resolved = true;
13484}
13485
13486impl EventEmitter<LspStoreEvent> for LspStore {}
13487
13488fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13489    hover
13490        .contents
13491        .retain(|hover_block| !hover_block.text.trim().is_empty());
13492    if hover.contents.is_empty() {
13493        None
13494    } else {
13495        Some(hover)
13496    }
13497}
13498
13499async fn populate_labels_for_completions(
13500    new_completions: Vec<CoreCompletion>,
13501    language: Option<Arc<Language>>,
13502    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13503) -> Vec<Completion> {
13504    let lsp_completions = new_completions
13505        .iter()
13506        .filter_map(|new_completion| {
13507            new_completion
13508                .source
13509                .lsp_completion(true)
13510                .map(|lsp_completion| lsp_completion.into_owned())
13511        })
13512        .collect::<Vec<_>>();
13513
13514    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13515        lsp_adapter
13516            .labels_for_completions(&lsp_completions, language)
13517            .await
13518            .log_err()
13519            .unwrap_or_default()
13520    } else {
13521        Vec::new()
13522    }
13523    .into_iter()
13524    .fuse();
13525
13526    let mut completions = Vec::new();
13527    for completion in new_completions {
13528        match completion.source.lsp_completion(true) {
13529            Some(lsp_completion) => {
13530                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13531
13532                let mut label = labels.next().flatten().unwrap_or_else(|| {
13533                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13534                });
13535                ensure_uniform_list_compatible_label(&mut label);
13536                completions.push(Completion {
13537                    label,
13538                    documentation,
13539                    replace_range: completion.replace_range,
13540                    new_text: completion.new_text,
13541                    insert_text_mode: lsp_completion.insert_text_mode,
13542                    source: completion.source,
13543                    icon_path: None,
13544                    confirm: None,
13545                    match_start: None,
13546                    snippet_deduplication_key: None,
13547                });
13548            }
13549            None => {
13550                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13551                ensure_uniform_list_compatible_label(&mut label);
13552                completions.push(Completion {
13553                    label,
13554                    documentation: None,
13555                    replace_range: completion.replace_range,
13556                    new_text: completion.new_text,
13557                    source: completion.source,
13558                    insert_text_mode: None,
13559                    icon_path: None,
13560                    confirm: None,
13561                    match_start: None,
13562                    snippet_deduplication_key: None,
13563                });
13564            }
13565        }
13566    }
13567    completions
13568}
13569
13570#[derive(Debug)]
13571pub enum LanguageServerToQuery {
13572    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13573    FirstCapable,
13574    /// Query a specific language server.
13575    Other(LanguageServerId),
13576}
13577
13578#[derive(Default)]
13579struct RenamePathsWatchedForServer {
13580    did_rename: Vec<RenameActionPredicate>,
13581    will_rename: Vec<RenameActionPredicate>,
13582}
13583
13584impl RenamePathsWatchedForServer {
13585    fn with_did_rename_patterns(
13586        mut self,
13587        did_rename: Option<&FileOperationRegistrationOptions>,
13588    ) -> Self {
13589        if let Some(did_rename) = did_rename {
13590            self.did_rename = did_rename
13591                .filters
13592                .iter()
13593                .filter_map(|filter| filter.try_into().log_err())
13594                .collect();
13595        }
13596        self
13597    }
13598    fn with_will_rename_patterns(
13599        mut self,
13600        will_rename: Option<&FileOperationRegistrationOptions>,
13601    ) -> Self {
13602        if let Some(will_rename) = will_rename {
13603            self.will_rename = will_rename
13604                .filters
13605                .iter()
13606                .filter_map(|filter| filter.try_into().log_err())
13607                .collect();
13608        }
13609        self
13610    }
13611
13612    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13613        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13614    }
13615    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13616        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13617    }
13618}
13619
13620impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13621    type Error = globset::Error;
13622    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13623        Ok(Self {
13624            kind: ops.pattern.matches.clone(),
13625            glob: GlobBuilder::new(&ops.pattern.glob)
13626                .case_insensitive(
13627                    ops.pattern
13628                        .options
13629                        .as_ref()
13630                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13631                )
13632                .build()?
13633                .compile_matcher(),
13634        })
13635    }
13636}
13637struct RenameActionPredicate {
13638    glob: GlobMatcher,
13639    kind: Option<FileOperationPatternKind>,
13640}
13641
13642impl RenameActionPredicate {
13643    // Returns true if language server should be notified
13644    fn eval(&self, path: &str, is_dir: bool) -> bool {
13645        self.kind.as_ref().is_none_or(|kind| {
13646            let expected_kind = if is_dir {
13647                FileOperationPatternKind::Folder
13648            } else {
13649                FileOperationPatternKind::File
13650            };
13651            kind == &expected_kind
13652        }) && self.glob.is_match(path)
13653    }
13654}
13655
13656#[derive(Default)]
13657struct LanguageServerWatchedPaths {
13658    worktree_paths: HashMap<WorktreeId, GlobSet>,
13659    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13660}
13661
13662#[derive(Default)]
13663struct LanguageServerWatchedPathsBuilder {
13664    worktree_paths: HashMap<WorktreeId, GlobSet>,
13665    abs_paths: HashMap<Arc<Path>, GlobSet>,
13666}
13667
13668impl LanguageServerWatchedPathsBuilder {
13669    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13670        self.worktree_paths.insert(worktree_id, glob_set);
13671    }
13672    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13673        self.abs_paths.insert(path, glob_set);
13674    }
13675    fn build(
13676        self,
13677        fs: Arc<dyn Fs>,
13678        language_server_id: LanguageServerId,
13679        cx: &mut Context<LspStore>,
13680    ) -> LanguageServerWatchedPaths {
13681        let lsp_store = cx.weak_entity();
13682
13683        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13684        let abs_paths = self
13685            .abs_paths
13686            .into_iter()
13687            .map(|(abs_path, globset)| {
13688                let task = cx.spawn({
13689                    let abs_path = abs_path.clone();
13690                    let fs = fs.clone();
13691
13692                    let lsp_store = lsp_store.clone();
13693                    async move |_, cx| {
13694                        maybe!(async move {
13695                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13696                            while let Some(update) = push_updates.0.next().await {
13697                                let action = lsp_store
13698                                    .update(cx, |this, _| {
13699                                        let Some(local) = this.as_local() else {
13700                                            return ControlFlow::Break(());
13701                                        };
13702                                        let Some(watcher) = local
13703                                            .language_server_watched_paths
13704                                            .get(&language_server_id)
13705                                        else {
13706                                            return ControlFlow::Break(());
13707                                        };
13708                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13709                                            "Watched abs path is not registered with a watcher",
13710                                        );
13711                                        let matching_entries = update
13712                                            .into_iter()
13713                                            .filter(|event| globs.is_match(&event.path))
13714                                            .collect::<Vec<_>>();
13715                                        this.lsp_notify_abs_paths_changed(
13716                                            language_server_id,
13717                                            matching_entries,
13718                                        );
13719                                        ControlFlow::Continue(())
13720                                    })
13721                                    .ok()?;
13722
13723                                if action.is_break() {
13724                                    break;
13725                                }
13726                            }
13727                            Some(())
13728                        })
13729                        .await;
13730                    }
13731                });
13732                (abs_path, (globset, task))
13733            })
13734            .collect();
13735        LanguageServerWatchedPaths {
13736            worktree_paths: self.worktree_paths,
13737            abs_paths,
13738        }
13739    }
13740}
13741
13742struct LspBufferSnapshot {
13743    version: i32,
13744    snapshot: TextBufferSnapshot,
13745}
13746
13747/// A prompt requested by LSP server.
13748#[derive(Clone, Debug)]
13749pub struct LanguageServerPromptRequest {
13750    pub id: usize,
13751    pub level: PromptLevel,
13752    pub message: String,
13753    pub actions: Vec<MessageActionItem>,
13754    pub lsp_name: String,
13755    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13756}
13757
13758impl LanguageServerPromptRequest {
13759    pub fn new(
13760        level: PromptLevel,
13761        message: String,
13762        actions: Vec<MessageActionItem>,
13763        lsp_name: String,
13764        response_channel: smol::channel::Sender<MessageActionItem>,
13765    ) -> Self {
13766        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13767        LanguageServerPromptRequest {
13768            id,
13769            level,
13770            message,
13771            actions,
13772            lsp_name,
13773            response_channel,
13774        }
13775    }
13776    pub async fn respond(self, index: usize) -> Option<()> {
13777        if let Some(response) = self.actions.into_iter().nth(index) {
13778            self.response_channel.send(response).await.ok()
13779        } else {
13780            None
13781        }
13782    }
13783
13784    #[cfg(any(test, feature = "test-support"))]
13785    pub fn test(
13786        level: PromptLevel,
13787        message: String,
13788        actions: Vec<MessageActionItem>,
13789        lsp_name: String,
13790    ) -> Self {
13791        let (tx, _rx) = smol::channel::unbounded();
13792        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13793    }
13794}
13795impl PartialEq for LanguageServerPromptRequest {
13796    fn eq(&self, other: &Self) -> bool {
13797        self.message == other.message && self.actions == other.actions
13798    }
13799}
13800
13801#[derive(Clone, Debug, PartialEq)]
13802pub enum LanguageServerLogType {
13803    Log(MessageType),
13804    Trace { verbose_info: Option<String> },
13805    Rpc { received: bool },
13806}
13807
13808impl LanguageServerLogType {
13809    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13810        match self {
13811            Self::Log(log_type) => {
13812                use proto::log_message::LogLevel;
13813                let level = match *log_type {
13814                    MessageType::ERROR => LogLevel::Error,
13815                    MessageType::WARNING => LogLevel::Warning,
13816                    MessageType::INFO => LogLevel::Info,
13817                    MessageType::LOG => LogLevel::Log,
13818                    other => {
13819                        log::warn!("Unknown lsp log message type: {other:?}");
13820                        LogLevel::Log
13821                    }
13822                };
13823                proto::language_server_log::LogType::Log(proto::LogMessage {
13824                    level: level as i32,
13825                })
13826            }
13827            Self::Trace { verbose_info } => {
13828                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13829                    verbose_info: verbose_info.to_owned(),
13830                })
13831            }
13832            Self::Rpc { received } => {
13833                let kind = if *received {
13834                    proto::rpc_message::Kind::Received
13835                } else {
13836                    proto::rpc_message::Kind::Sent
13837                };
13838                let kind = kind as i32;
13839                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13840            }
13841        }
13842    }
13843
13844    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13845        use proto::log_message::LogLevel;
13846        use proto::rpc_message;
13847        match log_type {
13848            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13849                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13850                    LogLevel::Error => MessageType::ERROR,
13851                    LogLevel::Warning => MessageType::WARNING,
13852                    LogLevel::Info => MessageType::INFO,
13853                    LogLevel::Log => MessageType::LOG,
13854                },
13855            ),
13856            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13857                verbose_info: trace_message.verbose_info,
13858            },
13859            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13860                received: match rpc_message::Kind::from_i32(message.kind)
13861                    .unwrap_or(rpc_message::Kind::Received)
13862                {
13863                    rpc_message::Kind::Received => true,
13864                    rpc_message::Kind::Sent => false,
13865                },
13866            },
13867        }
13868    }
13869}
13870
13871pub struct WorkspaceRefreshTask {
13872    refresh_tx: mpsc::Sender<()>,
13873    progress_tx: mpsc::Sender<()>,
13874    #[allow(dead_code)]
13875    task: Task<()>,
13876}
13877
13878pub enum LanguageServerState {
13879    Starting {
13880        startup: Task<Option<Arc<LanguageServer>>>,
13881        /// List of language servers that will be added to the workspace once it's initialization completes.
13882        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13883    },
13884
13885    Running {
13886        adapter: Arc<CachedLspAdapter>,
13887        server: Arc<LanguageServer>,
13888        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13889        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13890    },
13891}
13892
13893impl LanguageServerState {
13894    fn add_workspace_folder(&self, uri: Uri) {
13895        match self {
13896            LanguageServerState::Starting {
13897                pending_workspace_folders,
13898                ..
13899            } => {
13900                pending_workspace_folders.lock().insert(uri);
13901            }
13902            LanguageServerState::Running { server, .. } => {
13903                server.add_workspace_folder(uri);
13904            }
13905        }
13906    }
13907    fn _remove_workspace_folder(&self, uri: Uri) {
13908        match self {
13909            LanguageServerState::Starting {
13910                pending_workspace_folders,
13911                ..
13912            } => {
13913                pending_workspace_folders.lock().remove(&uri);
13914            }
13915            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13916        }
13917    }
13918}
13919
13920impl std::fmt::Debug for LanguageServerState {
13921    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13922        match self {
13923            LanguageServerState::Starting { .. } => {
13924                f.debug_struct("LanguageServerState::Starting").finish()
13925            }
13926            LanguageServerState::Running { .. } => {
13927                f.debug_struct("LanguageServerState::Running").finish()
13928            }
13929        }
13930    }
13931}
13932
13933#[derive(Clone, Debug, Serialize)]
13934pub struct LanguageServerProgress {
13935    pub is_disk_based_diagnostics_progress: bool,
13936    pub is_cancellable: bool,
13937    pub title: Option<String>,
13938    pub message: Option<String>,
13939    pub percentage: Option<usize>,
13940    #[serde(skip_serializing)]
13941    pub last_update_at: Instant,
13942}
13943
13944#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13945pub struct DiagnosticSummary {
13946    pub error_count: usize,
13947    pub warning_count: usize,
13948}
13949
13950impl DiagnosticSummary {
13951    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13952        let mut this = Self {
13953            error_count: 0,
13954            warning_count: 0,
13955        };
13956
13957        for entry in diagnostics {
13958            if entry.diagnostic.is_primary {
13959                match entry.diagnostic.severity {
13960                    DiagnosticSeverity::ERROR => this.error_count += 1,
13961                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13962                    _ => {}
13963                }
13964            }
13965        }
13966
13967        this
13968    }
13969
13970    pub fn is_empty(&self) -> bool {
13971        self.error_count == 0 && self.warning_count == 0
13972    }
13973
13974    pub fn to_proto(
13975        self,
13976        language_server_id: LanguageServerId,
13977        path: &RelPath,
13978    ) -> proto::DiagnosticSummary {
13979        proto::DiagnosticSummary {
13980            path: path.to_proto(),
13981            language_server_id: language_server_id.0 as u64,
13982            error_count: self.error_count as u32,
13983            warning_count: self.warning_count as u32,
13984        }
13985    }
13986}
13987
13988#[derive(Clone, Debug)]
13989pub enum CompletionDocumentation {
13990    /// There is no documentation for this completion.
13991    Undocumented,
13992    /// A single line of documentation.
13993    SingleLine(SharedString),
13994    /// Multiple lines of plain text documentation.
13995    MultiLinePlainText(SharedString),
13996    /// Markdown documentation.
13997    MultiLineMarkdown(SharedString),
13998    /// Both single line and multiple lines of plain text documentation.
13999    SingleLineAndMultiLinePlainText {
14000        single_line: SharedString,
14001        plain_text: Option<SharedString>,
14002    },
14003}
14004
14005impl CompletionDocumentation {
14006    #[cfg(any(test, feature = "test-support"))]
14007    pub fn text(&self) -> SharedString {
14008        match self {
14009            CompletionDocumentation::Undocumented => "".into(),
14010            CompletionDocumentation::SingleLine(s) => s.clone(),
14011            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
14012            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
14013            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
14014                single_line.clone()
14015            }
14016        }
14017    }
14018}
14019
14020impl From<lsp::Documentation> for CompletionDocumentation {
14021    fn from(docs: lsp::Documentation) -> Self {
14022        match docs {
14023            lsp::Documentation::String(text) => {
14024                if text.lines().count() <= 1 {
14025                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
14026                } else {
14027                    CompletionDocumentation::MultiLinePlainText(text.into())
14028                }
14029            }
14030
14031            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
14032                lsp::MarkupKind::PlainText => {
14033                    if value.lines().count() <= 1 {
14034                        CompletionDocumentation::SingleLine(value.into())
14035                    } else {
14036                        CompletionDocumentation::MultiLinePlainText(value.into())
14037                    }
14038                }
14039
14040                lsp::MarkupKind::Markdown => {
14041                    CompletionDocumentation::MultiLineMarkdown(value.into())
14042                }
14043            },
14044        }
14045    }
14046}
14047
14048pub enum ResolvedHint {
14049    Resolved(InlayHint),
14050    Resolving(Shared<Task<()>>),
14051}
14052
14053pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
14054    glob.components()
14055        .take_while(|component| match component {
14056            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
14057            _ => true,
14058        })
14059        .collect()
14060}
14061
14062pub struct SshLspAdapter {
14063    name: LanguageServerName,
14064    binary: LanguageServerBinary,
14065    initialization_options: Option<String>,
14066    code_action_kinds: Option<Vec<CodeActionKind>>,
14067}
14068
14069impl SshLspAdapter {
14070    pub fn new(
14071        name: LanguageServerName,
14072        binary: LanguageServerBinary,
14073        initialization_options: Option<String>,
14074        code_action_kinds: Option<String>,
14075    ) -> Self {
14076        Self {
14077            name,
14078            binary,
14079            initialization_options,
14080            code_action_kinds: code_action_kinds
14081                .as_ref()
14082                .and_then(|c| serde_json::from_str(c).ok()),
14083        }
14084    }
14085}
14086
14087impl LspInstaller for SshLspAdapter {
14088    type BinaryVersion = ();
14089    async fn check_if_user_installed(
14090        &self,
14091        _: &dyn LspAdapterDelegate,
14092        _: Option<Toolchain>,
14093        _: &AsyncApp,
14094    ) -> Option<LanguageServerBinary> {
14095        Some(self.binary.clone())
14096    }
14097
14098    async fn cached_server_binary(
14099        &self,
14100        _: PathBuf,
14101        _: &dyn LspAdapterDelegate,
14102    ) -> Option<LanguageServerBinary> {
14103        None
14104    }
14105
14106    async fn fetch_latest_server_version(
14107        &self,
14108        _: &dyn LspAdapterDelegate,
14109        _: bool,
14110        _: &mut AsyncApp,
14111    ) -> Result<()> {
14112        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14113    }
14114
14115    async fn fetch_server_binary(
14116        &self,
14117        _: (),
14118        _: PathBuf,
14119        _: &dyn LspAdapterDelegate,
14120    ) -> Result<LanguageServerBinary> {
14121        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14122    }
14123}
14124
14125#[async_trait(?Send)]
14126impl LspAdapter for SshLspAdapter {
14127    fn name(&self) -> LanguageServerName {
14128        self.name.clone()
14129    }
14130
14131    async fn initialization_options(
14132        self: Arc<Self>,
14133        _: &Arc<dyn LspAdapterDelegate>,
14134        _: &mut AsyncApp,
14135    ) -> Result<Option<serde_json::Value>> {
14136        let Some(options) = &self.initialization_options else {
14137            return Ok(None);
14138        };
14139        let result = serde_json::from_str(options)?;
14140        Ok(result)
14141    }
14142
14143    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14144        self.code_action_kinds.clone()
14145    }
14146}
14147
14148pub fn language_server_settings<'a>(
14149    delegate: &'a dyn LspAdapterDelegate,
14150    language: &LanguageServerName,
14151    cx: &'a App,
14152) -> Option<&'a LspSettings> {
14153    language_server_settings_for(
14154        SettingsLocation {
14155            worktree_id: delegate.worktree_id(),
14156            path: RelPath::empty(),
14157        },
14158        language,
14159        cx,
14160    )
14161}
14162
14163pub fn language_server_settings_for<'a>(
14164    location: SettingsLocation<'a>,
14165    language: &LanguageServerName,
14166    cx: &'a App,
14167) -> Option<&'a LspSettings> {
14168    ProjectSettings::get(Some(location), cx).lsp.get(language)
14169}
14170
14171pub struct LocalLspAdapterDelegate {
14172    lsp_store: WeakEntity<LspStore>,
14173    worktree: worktree::Snapshot,
14174    fs: Arc<dyn Fs>,
14175    http_client: Arc<dyn HttpClient>,
14176    language_registry: Arc<LanguageRegistry>,
14177    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14178}
14179
14180impl LocalLspAdapterDelegate {
14181    pub fn new(
14182        language_registry: Arc<LanguageRegistry>,
14183        environment: &Entity<ProjectEnvironment>,
14184        lsp_store: WeakEntity<LspStore>,
14185        worktree: &Entity<Worktree>,
14186        http_client: Arc<dyn HttpClient>,
14187        fs: Arc<dyn Fs>,
14188        cx: &mut App,
14189    ) -> Arc<Self> {
14190        let load_shell_env_task =
14191            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14192
14193        Arc::new(Self {
14194            lsp_store,
14195            worktree: worktree.read(cx).snapshot(),
14196            fs,
14197            http_client,
14198            language_registry,
14199            load_shell_env_task,
14200        })
14201    }
14202
14203    pub fn from_local_lsp(
14204        local: &LocalLspStore,
14205        worktree: &Entity<Worktree>,
14206        cx: &mut App,
14207    ) -> Arc<Self> {
14208        Self::new(
14209            local.languages.clone(),
14210            &local.environment,
14211            local.weak.clone(),
14212            worktree,
14213            local.http_client.clone(),
14214            local.fs.clone(),
14215            cx,
14216        )
14217    }
14218}
14219
14220#[async_trait]
14221impl LspAdapterDelegate for LocalLspAdapterDelegate {
14222    fn show_notification(&self, message: &str, cx: &mut App) {
14223        self.lsp_store
14224            .update(cx, |_, cx| {
14225                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14226            })
14227            .ok();
14228    }
14229
14230    fn http_client(&self) -> Arc<dyn HttpClient> {
14231        self.http_client.clone()
14232    }
14233
14234    fn worktree_id(&self) -> WorktreeId {
14235        self.worktree.id()
14236    }
14237
14238    fn worktree_root_path(&self) -> &Path {
14239        self.worktree.abs_path().as_ref()
14240    }
14241
14242    fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
14243        self.worktree.resolve_relative_path(path)
14244    }
14245
14246    async fn shell_env(&self) -> HashMap<String, String> {
14247        let task = self.load_shell_env_task.clone();
14248        task.await.unwrap_or_default()
14249    }
14250
14251    async fn npm_package_installed_version(
14252        &self,
14253        package_name: &str,
14254    ) -> Result<Option<(PathBuf, Version)>> {
14255        let local_package_directory = self.worktree_root_path();
14256        let node_modules_directory = local_package_directory.join("node_modules");
14257
14258        if let Some(version) =
14259            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14260        {
14261            return Ok(Some((node_modules_directory, version)));
14262        }
14263        let Some(npm) = self.which("npm".as_ref()).await else {
14264            log::warn!(
14265                "Failed to find npm executable for {:?}",
14266                local_package_directory
14267            );
14268            return Ok(None);
14269        };
14270
14271        let env = self.shell_env().await;
14272        let output = util::command::new_command(&npm)
14273            .args(["root", "-g"])
14274            .envs(env)
14275            .current_dir(local_package_directory)
14276            .output()
14277            .await?;
14278        let global_node_modules =
14279            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14280
14281        if let Some(version) =
14282            read_package_installed_version(global_node_modules.clone(), package_name).await?
14283        {
14284            return Ok(Some((global_node_modules, version)));
14285        }
14286        return Ok(None);
14287    }
14288
14289    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14290        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14291        if self.fs.is_file(&worktree_abs_path).await {
14292            worktree_abs_path.pop();
14293        }
14294
14295        let env = self.shell_env().await;
14296
14297        let shell_path = env.get("PATH").cloned();
14298
14299        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14300    }
14301
14302    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14303        let mut working_dir = self.worktree_root_path().to_path_buf();
14304        if self.fs.is_file(&working_dir).await {
14305            working_dir.pop();
14306        }
14307        let output = util::command::new_command(&command.path)
14308            .args(command.arguments)
14309            .envs(command.env.clone().unwrap_or_default())
14310            .current_dir(working_dir)
14311            .output()
14312            .await?;
14313
14314        anyhow::ensure!(
14315            output.status.success(),
14316            "{}, stdout: {:?}, stderr: {:?}",
14317            output.status,
14318            String::from_utf8_lossy(&output.stdout),
14319            String::from_utf8_lossy(&output.stderr)
14320        );
14321        Ok(())
14322    }
14323
14324    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14325        self.language_registry
14326            .update_lsp_binary_status(server_name, status);
14327    }
14328
14329    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14330        self.language_registry
14331            .all_lsp_adapters()
14332            .into_iter()
14333            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14334            .collect()
14335    }
14336
14337    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14338        let dir = self.language_registry.language_server_download_dir(name)?;
14339
14340        if !dir.exists() {
14341            smol::fs::create_dir_all(&dir)
14342                .await
14343                .context("failed to create container directory")
14344                .log_err()?;
14345        }
14346
14347        Some(dir)
14348    }
14349
14350    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14351        let entry = self
14352            .worktree
14353            .entry_for_path(path)
14354            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14355        let abs_path = self.worktree.absolutize(&entry.path);
14356        self.fs.load(&abs_path).await
14357    }
14358}
14359
14360async fn populate_labels_for_symbols(
14361    symbols: Vec<CoreSymbol>,
14362    language_registry: &Arc<LanguageRegistry>,
14363    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14364    output: &mut Vec<Symbol>,
14365) {
14366    #[allow(clippy::mutable_key_type)]
14367    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14368
14369    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14370    for symbol in symbols {
14371        let Some(file_name) = symbol.path.file_name() else {
14372            continue;
14373        };
14374        let language = language_registry
14375            .load_language_for_file_path(Path::new(file_name))
14376            .await
14377            .ok()
14378            .or_else(|| {
14379                unknown_paths.insert(file_name.into());
14380                None
14381            });
14382        symbols_by_language
14383            .entry(language)
14384            .or_default()
14385            .push(symbol);
14386    }
14387
14388    for unknown_path in unknown_paths {
14389        log::info!("no language found for symbol in file {unknown_path:?}");
14390    }
14391
14392    let mut label_params = Vec::new();
14393    for (language, mut symbols) in symbols_by_language {
14394        label_params.clear();
14395        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14396            name: mem::take(&mut symbol.name),
14397            kind: symbol.kind,
14398            container_name: symbol.container_name.take(),
14399        }));
14400
14401        let mut labels = Vec::new();
14402        if let Some(language) = language {
14403            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14404                language_registry
14405                    .lsp_adapters(&language.name())
14406                    .first()
14407                    .cloned()
14408            });
14409            if let Some(lsp_adapter) = lsp_adapter {
14410                labels = lsp_adapter
14411                    .labels_for_symbols(&label_params, &language)
14412                    .await
14413                    .log_err()
14414                    .unwrap_or_default();
14415            }
14416        }
14417
14418        for (
14419            (
14420                symbol,
14421                language::Symbol {
14422                    name,
14423                    container_name,
14424                    ..
14425                },
14426            ),
14427            label,
14428        ) in symbols
14429            .into_iter()
14430            .zip(label_params.drain(..))
14431            .zip(labels.into_iter().chain(iter::repeat(None)))
14432        {
14433            output.push(Symbol {
14434                language_server_name: symbol.language_server_name,
14435                source_worktree_id: symbol.source_worktree_id,
14436                source_language_server_id: symbol.source_language_server_id,
14437                path: symbol.path,
14438                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14439                name,
14440                kind: symbol.kind,
14441                range: symbol.range,
14442                container_name,
14443            });
14444        }
14445    }
14446}
14447
14448pub(crate) fn collapse_newlines(text: &str, separator: &str) -> String {
14449    text.lines()
14450        .map(|line| line.trim())
14451        .filter(|line| !line.is_empty())
14452        .join(separator)
14453}
14454
14455fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14456    match server.capabilities().text_document_sync.as_ref()? {
14457        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14458            // Server wants didSave but didn't specify includeText.
14459            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14460            // Server doesn't want didSave at all.
14461            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14462            // Server provided SaveOptions.
14463            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14464                Some(save_options.include_text.unwrap_or(false))
14465            }
14466        },
14467        // We do not have any save info. Kind affects didChange only.
14468        lsp::TextDocumentSyncCapability::Kind(_) => None,
14469    }
14470}
14471
14472/// Completion items are displayed in a `UniformList`.
14473/// Usually, those items are single-line strings, but in LSP responses,
14474/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14475/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14476/// 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,
14477/// breaking the completions menu presentation.
14478///
14479/// 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.
14480pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14481    let mut new_text = String::with_capacity(label.text.len());
14482    let mut offset_map = vec![0; label.text.len() + 1];
14483    let mut last_char_was_space = false;
14484    let mut new_idx = 0;
14485    let chars = label.text.char_indices().fuse();
14486    let mut newlines_removed = false;
14487
14488    for (idx, c) in chars {
14489        offset_map[idx] = new_idx;
14490
14491        match c {
14492            '\n' if last_char_was_space => {
14493                newlines_removed = true;
14494            }
14495            '\t' | ' ' if last_char_was_space => {}
14496            '\n' if !last_char_was_space => {
14497                new_text.push(' ');
14498                new_idx += 1;
14499                last_char_was_space = true;
14500                newlines_removed = true;
14501            }
14502            ' ' | '\t' => {
14503                new_text.push(' ');
14504                new_idx += 1;
14505                last_char_was_space = true;
14506            }
14507            _ => {
14508                new_text.push(c);
14509                new_idx += c.len_utf8();
14510                last_char_was_space = false;
14511            }
14512        }
14513    }
14514    offset_map[label.text.len()] = new_idx;
14515
14516    // Only modify the label if newlines were removed.
14517    if !newlines_removed {
14518        return;
14519    }
14520
14521    let last_index = new_idx;
14522    let mut run_ranges_errors = Vec::new();
14523    label.runs.retain_mut(|(range, _)| {
14524        match offset_map.get(range.start) {
14525            Some(&start) => range.start = start,
14526            None => {
14527                run_ranges_errors.push(range.clone());
14528                return false;
14529            }
14530        }
14531
14532        match offset_map.get(range.end) {
14533            Some(&end) => range.end = end,
14534            None => {
14535                run_ranges_errors.push(range.clone());
14536                range.end = last_index;
14537            }
14538        }
14539        true
14540    });
14541    if !run_ranges_errors.is_empty() {
14542        log::error!(
14543            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14544            label.text
14545        );
14546    }
14547
14548    let mut wrong_filter_range = None;
14549    if label.filter_range == (0..label.text.len()) {
14550        label.filter_range = 0..new_text.len();
14551    } else {
14552        let mut original_filter_range = Some(label.filter_range.clone());
14553        match offset_map.get(label.filter_range.start) {
14554            Some(&start) => label.filter_range.start = start,
14555            None => {
14556                wrong_filter_range = original_filter_range.take();
14557                label.filter_range.start = last_index;
14558            }
14559        }
14560
14561        match offset_map.get(label.filter_range.end) {
14562            Some(&end) => label.filter_range.end = end,
14563            None => {
14564                wrong_filter_range = original_filter_range.take();
14565                label.filter_range.end = last_index;
14566            }
14567        }
14568    }
14569    if let Some(wrong_filter_range) = wrong_filter_range {
14570        log::error!(
14571            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14572            label.text
14573        );
14574    }
14575
14576    label.text = new_text;
14577}
14578
14579/// Apply edits to the buffer that will become part of the formatting transaction.
14580/// Fails if the buffer has been edited since the start of that transaction.
14581fn extend_formatting_transaction(
14582    buffer: &FormattableBuffer,
14583    formatting_transaction_id: text::TransactionId,
14584    cx: &mut AsyncApp,
14585    operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
14586) -> anyhow::Result<()> {
14587    buffer.handle.update(cx, |buffer, cx| {
14588        let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
14589        if last_transaction_id != Some(formatting_transaction_id) {
14590            anyhow::bail!("Buffer edited while formatting. Aborting")
14591        }
14592        buffer.start_transaction();
14593        operation(buffer, cx);
14594        if let Some(transaction_id) = buffer.end_transaction(cx) {
14595            buffer.merge_transactions(transaction_id, formatting_transaction_id);
14596        }
14597        Ok(())
14598    })
14599}